Please read marginal value ranking algorithm first, as discount deal estimate is a core ingredient of the algorithm.

In short, ** average marginal value = (total discount with overlapped – total without) / overlapped quantity**.

In addition to its identity * offerId*, we need three basic properties for discount deal estimate (

*):*

`DiscountDealEstimate`

*,*

`totalDiscountAmountWithOverlapped`

*,*

`totalDiscountAmountWithoutOverlapped`

*of type*

`itemGroupIndexToQuantityNeededFromOverlappedLookup`

*.*

`Dictionary<int, decimal>`

You may wonder why we cannot have * overlappedQuantityNeeded *for the last one. In pricing zone concurrency model, multiple compounded discounts of the same priority can be compounded together. As such, we compound all compounded discounts into one estimate, comparing it to best-price discounts. Having the details of overlapped quantities avoids double counting when we compound estimates. Speaking of compound, the estimate needs

*.*

`canCompound`

For compete within priority and compound across concurrency model, compound does not apply because compound discounts compete against each other within the same priority.

The following is all you need to know to create an estimate,

public DiscountDealEstimate( bool canCompound, string offerId, decimal totalDiscountAmountWithOverlapped, decimal totalDiscountAmountWithoutOverlapped, Dictionary<int, decimal> itemGroupIndexToQuantityNeededFromOverlappedLookup)

Lastly, internally, it can take optional

. For mix and match with fixed quantity setup, *maxOverlappedQuantityNeeded*

can be over-estimated.*itemGroupIndexToQuantityNeededFromOverlappedLookup*

** Related**: Retail Discount Knapsack – Marginal Value Ranking Algorithm I