C # class design, flexible payment rules

I am currently modeling a system responsible for managing royalty payments. The fee can be as simple as:

  • Pay Author 15% Income

or as complicated as:

  • Pay Author B 15% of the income up to 1000 sold, then 12% of the income
  • Also pay the author B $ 1.50 for each sold up to 1000 quantity sold.

or

  • Pay Author C 15% of income for first income of $ 1,000, then 12% of income.

In short, a payment can be either a flat amount for each sold, or a percentage of revenue. The payment term may be based on the quantity sold or on revenue. I tried to create a class (which closely matches the database table behind the scenes) that covers all this flexibility by specifying types for a range of payments and payment values. However, I am worried that perhaps I am trying to make this class do too much, and may be in the corner if we need to consider additional scenarios in the future. I am looking for suggestions for alternative development approaches.

public class PaymentRule
{
    // I'm not 100% comfortable with this, as this will
    // really be an Int32 value for quantity sold ranges
    public decimal RangeMinimum { get; set; }
    public decimal? RangeMaximum { get; set; }

    // This will always be a decimal value, but may represent
    // a dollar amount or percentage depending on the context
    public decimal PaymentValue { get; set; }

    // Specify a type for the range: QuantitySold or Revenue
    public string RangeType { get; set; }

    // Specify a type for the value: AmountPerEachSold or RevenuePercentage
    public decimal ValueType { get; set; }

    public decimal CalculateRoyaltyDue(int quantitySold, decimal revenue)
    {
        // ...
    }
}

Any suggestions would be appreciated.

UPDATE 5/9/2012:

I should mention that these rules must be stored in the SQL Server database.

+3
source share
2 answers

- , , , .

, - - .

-, -. - Composite Specification. Composite Specification IsSatisfiedBy, . "" , , -. , - , , .

+1

- , , linq, chining , , - :

var revenue = 12000;
var ruleA = Rules.PayAuthor(15).PercentOf(revenue)
var ruleB = Rules.PayAuthor(15).PercentOf(revenue).UpTo(soldUnits:1000).Then(12).PercentOf(revenue)

var royalltyA = Royallty.For(ruleA, whenSoldUnitsIs: 1500);
var royalltyB = Royallty.For(ruleB, whenSoldUnitsIs: 1500);
-1

All Articles