/// <summary> /// Get cost with discount /// </summary> public decimal CalculateCost(IEnumerable <IProductComparable <T> > products) { if (products == null) { throw new ArgumentNullException(); } SetRules(); if (!ValidateAlphabet()) { throw new Exception("repository do not contains required items"); } var unit = new CalculateUnit <T> { NotCalculatedProducts = products.ToList() }; foreach (var f in _rules) { unit = f(unit); } return(unit.Cost + unit.NotCalculatedProducts.Sum(x => x.Cost)); }
/// <summary> /// get cost with discount by product count /// </summary> protected CalculateUnit <T> SaleCountProcess(CalculateUnit <T> unit, int count, decimal discount) { if (unit.NotCalculatedProducts.Count >= count) { var costTotal = unit.NotCalculatedProducts.Take(count).Sum(x => x.Cost); unit.Cost += costTotal - costTotal * discount; unit.NotCalculatedProducts.RemoveRange(0, count); return(SaleCountProcess(unit, count, discount)); } return(unit); }
/// <summary> /// get cost with discount by product ids /// </summary> protected CalculateUnit <T> SaleGroupProcess(CalculateUnit <T> unit, IEnumerable <T> ids, decimal discount) { var useInDiscount = new List <IProductComparable <T> >(); var tmpStorage = new List <IProductComparable <T> >(unit.NotCalculatedProducts); foreach (var id in ids) { var findResult = tmpStorage.FirstOrDefault(x => x.Id.CompareTo(id) == 0); if (findResult == null) { return(unit); } tmpStorage.Remove(findResult); useInDiscount.Add(findResult); } var costTotal = useInDiscount.Sum(x => x.Cost); unit.Cost += costTotal - costTotal * discount; unit.NotCalculatedProducts = unit.NotCalculatedProducts.Except(useInDiscount).ToList(); return(SaleGroupProcess(unit, ids, discount)); }