//we perform rounding overall and per item, then fix accumulated error by adding it to the biggest element by each channel-model specifically
var promoQtysBeforeRounding = conditionList
.GroupBy(cl => new { cl.ChannelCode, cl.ModelCode })
.Select(cl => new
{
cl.Key.ChannelCode,
cl.Key.ModelCode,
custModelPromoSum = Math.Round(cl.Sum(a => a.PromotionQty), 0, MidpointRounding.AwayFromZero)
}).ToList();
foreach (var calcItem in conditionList)
{
calcItem.PromotionQty = Math.Round(calcItem.PromotionQty, 0, MidpointRounding.AwayFromZero);
}
var promoQtysAfterRounding = conditionList
.GroupBy(clg => new
{
clg.ChannelCode,
clg.ModelCode
})
.Select(clg => new
{
clg.Key.ChannelCode,
clg.Key.ModelCode,
custModelPromoSum = Math.Round(clg.Sum(a => a.PromotionQty), 0, MidpointRounding.AwayFromZero)
});
foreach (var listGroup in promoQtysAfterRounding)
{
var sumPromoQtyByDistAndModel = promoQtysBeforeRounding.Single(a => a.ModelCode == listGroup.ModelCode && a.ChannelCode == listGroup.ChannelCode);
if (listGroup.custModelPromoSum != sumPromoQtyByDistAndModel.custModelPromoSum)
{
var item = conditionList.Where(a => a.ModelCode == listGroup.ModelCode && a.ChannelCode == listGroup.ChannelCode).Aggregate((i, j) => i.PromotionQty > j.PromotionQty ? i : j);
var difference = sumPromoQtyByDistAndModel.custModelPromoSum - listGroup.custModelPromoSum;
item.PromotionQty += difference;
}
}