public CPrice getTierPrice(MIntervalConfig ivc, CBasketItem bi) { foreach (MInterval iv in ivc.IntervalItems) { double from = CUtil.StringToDouble(iv.FromValue); double to = CUtil.StringToDouble(iv.ToValue); double value = CUtil.StringToDouble(iv.ConfigValue); if ((bi.Quantity > from) && (bi.Quantity <= to)) { CPrice p = new CPrice(); if (ivc.TierScopeType == 1) { p.TotalAmount = value; p.UnitPrice = value / bi.Quantity; } else { //0 - by unit price p.TotalAmount = value * bi.Quantity; p.UnitPrice = value; } return(p); } } return(null); }
private Hashtable getEligibleItemsHash(Hashtable accumHash) { Hashtable filterHash = new Hashtable(); MPackage pkg = getPackage(); if (pkg.IsProductSpecific == false) { //All item in the basket is eligible return(accumHash); } foreach (String key in accumHash.Keys) { CPrice p = (CPrice)accumHash[key]; bool isEligible = isItemEligible(p, pkg, key); if (isEligible) { filterHash.Add(key, p); } } //If all all item exist in pkg.PackageFinalDiscounts if (isAllExist(filterHash, pkg)) { return(filterHash); } return(new Hashtable()); }
private double calculateRatio(CPrice p) { MPackage pkg = getPackage(); String pricingDef = pkg.DiscountDefinition; MIntervalConfig ivc = new MIntervalConfig(new CTable("")); ivc.DeserializeConfig(pricingDef); CPrice o = null; CBasketItem dummy = new CBasketItem("", null, p.Quantity, p.TotalAmount); //Gui might not see correctly earlier pkg.DiscountMapType = "1"; ivc.TierScopeType = 0; if (ivc.SelectionType == 1) { //step o = getStepDiscount(ivc, dummy); } else { //Tier o = getTierDiscount(ivc, dummy); } if (o != null) { //Use DiscountAmount as a temp field return(o.DiscountAmount); } return(-9999); }
private Boolean calculateFinalDiscount(CPrice p) { Boolean matched = false; MPackage pkg = getPackage(); String pricingDef = pkg.DiscountDefinition; MIntervalConfig ivc = new MIntervalConfig(new CTable("")); ivc.DeserializeConfig(pricingDef); CPrice o = null; CBasketItem dummy = new CBasketItem("", null, p.Quantity, p.TotalAmount); if (ivc.SelectionType == 1) { //step o = getStepDiscount(ivc, dummy); } else { //Tier o = getTierDiscount(ivc, dummy); } if (o != null) { res.FinalDiscount = o.DiscountAmount; finalDiscount = res.FinalDiscount; isFinalDiscount = true; matched = true; } return(matched); }
/* Return array of BasketSet, return null if package not applicable */ /* * Basket(Available) = {A:10, C:2, D:7} * Basket(Used) = {B:3} * Basket(Free) = {E:1} * BasketSet = {A={A:10, C:2, D:7}, U={B:3}, F={E:1}} */ public override CBasketSet ApplyPakageLogic(CBasketSet inBasket) { if (!isPackageEligible(res, null, false)) { res.SetInputBasketSet(inBasket.Clone()); res.SetOutputBasketSet(inBasket); addProcessingResult(res); return(inBasket); } Hashtable accumHash = getAccumulateHash(inBasket); Hashtable filterHash = getEligibleItemsHash(accumHash); CPrice accum = getAccumulatePrice(filterHash); CBasketSet output = finalizeOutput(inBasket, filterHash, accum); res.SetInputBasketSet(inBasket.Clone()); res.SetOutputBasketSet(output); addProcessingResult(res); if (giftCount <= 0) { res.SetErrorCode("ERROR_NO_PROMOTION_MATCH"); res.SetStatus(ProcessingResultStatus.ProcessingFail); } else { res.SetStatus(ProcessingResultStatus.ProcessingSuccess); } return(output); }
private Hashtable getAccumulateHash(CBasketSet inBasket) { Hashtable hash = new Hashtable(); ArrayList types = inBasket.GetBasketTypes(); foreach (BasketTypeEnum bt in types) { if (!isInBasketType(bt)) { continue; } ArrayList arr = inBasket.GetAllBasketByType(bt); foreach (CBasket bs in arr) { int cnt = bs.GetBasketItemCount(); for (int i = 0; i < cnt; i++) { CBasketItem bi = bs.GetBasketItem(i); if (bi.IsFinalDiscounted) { //Don't need to discount it again continue; } String key = bi.Key; CPrice p = null; //At this point, the Amount of Bundle items is 0.00 (will be added in later step) if (!hash.ContainsKey(key)) { p = new CPrice(); p.Quantity = bi.Quantity; p.TotalAmount = bi.GetTotal(); hash.Add(key, p); } else { p = (CPrice)hash[key]; p.Quantity = p.Quantity + bi.Quantity; p.TotalAmount = p.TotalAmount + bi.GetTotal(); } } } } return(hash); }
private CPrice getAccumulatePrice(Hashtable filters) { CPrice accum = new CPrice(); foreach (String key in filters.Keys) { CPrice p = (CPrice)filters[key]; accum.Quantity = accum.Quantity + p.Quantity; accum.TotalAmount = accum.TotalAmount + p.TotalAmount; } return(accum); }
protected CPrice getTierDiscount(MIntervalConfig ivc, CBasketItem bi) { MPackage pkg = getPackage(); double qty = 0.00; if (ivc.MappingType == 0) { //Map by quantity qty = bi.Quantity; } else { //Map by amount qty = bi.GetAmount(); } foreach (MInterval iv in ivc.IntervalItems) { double from = CUtil.StringToDouble(iv.FromValue); double to = CUtil.StringToDouble(iv.ToValue); double value = CUtil.StringToDouble(iv.ConfigValue); if ((qty > from) && (qty <= to)) { CPrice p = new CPrice(); if (ivc.TierScopeType == 0) { //Fixed p.DiscountAmount = value; } else if (ivc.TierScopeType == 1) { //Per unit p.DiscountAmount = bi.Quantity * value; } else { //2 - Percent of amount p.DiscountAmount = (value * bi.GetAmount()) / 100; } return(p); } } return(null); }
private CPrice getAccumulatePrice(Hashtable filters) { CPrice accum = new CPrice(); foreach (String key in filters.Keys) { CPrice p = (CPrice)filters[key]; accum.Quantity = accum.Quantity + p.Quantity; accum.TotalAmount = accum.TotalAmount + p.TotalAmount; } //Bundle amount has not been added earlier accum.TotalAmount = accum.TotalAmount + totalBundleAmt; return(accum); }
private CBasketItem calculatePrice(CBasketItem bi) { MPackage pkg = getPackage(); CBasketItem nbi = new CBasketItem(bi.Key, bi.Item, bi.Quantity); foreach (MPackagePrice pp in pkg.PackageItemPrices) { if (pp.EnabledFlag.Equals("N")) { continue; } if (!isItemApplicable(pp, bi)) { continue; } MIntervalConfig ivc = new MIntervalConfig(new CTable("")); ivc.DeserializeConfig(pp.PricingDefination); CPrice o = null; if (ivc.SelectionType == 1) { //step o = getStepPrice(ivc, bi); } else { //Tier o = getTierPrice(ivc, bi); } if (o != null) { nbi.SetAppliedPackage(pkg); nbi.SetUnitPrice(o.UnitPrice); return(nbi); } } return(null); }
private CBasketItem calculateDiscount(CBasketItem bi) { MPackage pkg = getPackage(); MSelectedItem vi = (MSelectedItem)bi.Item; CBasketItem nbi = new CBasketItem(bi.Key, bi.Item, bi.Quantity); nbi.SetUnitPrice(bi.GetUnitPrice()); foreach (MPackageTrayPriceDiscount pp in pkg.PackageTrayByItems) { if (!isItemApplicable(pp, bi)) { continue; } MIntervalConfig ivc = new MIntervalConfig(new CTable("")); ivc.DeserializeConfig(pp.DiscountDefination); CPrice o = null; if (ivc.SelectionType == 1) { //step o = getStepDiscount(ivc, bi); } else { //Tier o = getTierDiscount(ivc, bi); } if (o != null) { nbi.SetAppliedPackage(pkg); nbi.SetDiscount(o.DiscountAmount); return(nbi); } } return(null); }
private CBasketItem calculatePrice(CBasketItem bi) { CBasketItem nbi = new CBasketItem(bi.Key, bi.Item, bi.Quantity); MSelectedItem si = (MSelectedItem)bi.Item; String pricingDef = si.PricingDefination; if (si.SelectionType.Equals("1")) { pricingDef = si.ServicePricingDefinition; } MIntervalConfig ivc = new MIntervalConfig(new CTable("")); ivc.DeserializeConfig(pricingDef); CPrice o = null; if (ivc.SelectionType == 1) { //step o = getStepPrice(ivc, bi); } else { //Tier o = getTierPrice(ivc, bi); } if (o != null) { nbi.SetAppliedPackage(getPackage()); nbi.SetUnitPrice(o.UnitPrice); return(nbi); } return(null); }
private bool isItemEligible(CPrice item, MPackage pkg, String key) { ObservableCollection <MPackageFinalDiscount> arr = pkg.PackageFinalDiscounts; foreach (MPackageFinalDiscount pf in arr) { if (pf.EnabledFlag.Equals("N")) { continue; } if (key.Equals(pf.Key)) { double minimumQty = CUtil.StringToDouble(pf.Quantity); if (item.Quantity >= minimumQty) { return(true); } } } return(false); }
/* Return array of BasketSet, return null if package not applicable */ /* * Basket(Available) = {A:10, C:2, D:7} * Basket(Used) = {B:3} * Basket(Free) = {E:1} * BasketSet = {A={A:10, C:2, D:7}, U={B:3}, F={E:1}} */ public override CBasketSet ApplyPakageLogic(CBasketSet inBasket) { if (!isPackageEligible(res, null, false)) { res.SetInputBasketSet(inBasket.Clone()); res.SetOutputBasketSet(inBasket); addProcessingResult(res); return(inBasket); } Hashtable accumHash = getAccumulateHash(inBasket); Hashtable filterHash = getEligibleItemsHash(accumHash); //CPrice accum = getAccumulatePrice(filterHash); //totalBundleAmt created in finalizeOutput() and used in getAccumulatePrice() CBasketSet output = finalizeOutput(inBasket, filterHash); CPrice accum = getAccumulatePrice(filterHash); res.SetInputBasketSet(inBasket.Clone()); res.SetOutputBasketSet(output); Boolean priceMatched = calculateFinalDiscount(accum); addProcessingResult(res); if ((filterHash.Count <= 0) || (!priceMatched)) { res.SetErrorCode("ERROR_NO_PROMOTION_MATCH"); res.SetStatus(ProcessingResultStatus.ProcessingFail); } else { res.SetStatus(ProcessingResultStatus.ProcessingSuccess); } return(output); }
private CBasketItem calculatePrice(CBasketItem bi) { MPackage pkg = getPackage(); MIntervalConfig ivc = null; CPrice o = null; Boolean applicable = false; CBasketItem nbi = new CBasketItem(bi.Key, bi.Item, bi.Quantity); foreach (MPackageTrayPriceDiscount pp in pkg.PackageTrayByItems) { if (pp.EnabledFlag.Equals("N")) { continue; } if (!isItemApplicable(pp, bi)) { continue; } //Applicable here applicable = true; ivc = new MIntervalConfig(new CTable("")); ivc.DeserializeConfig(pp.PricingDefination); o = null; if (ivc.SelectionType == 1) { //step o = getStepPrice(ivc, bi); } else { //Tier o = getTierPrice(ivc, bi); } if (o != null) { //Got the price nbi.SetAppliedPackage(pkg); nbi.SetUnitPrice(o.UnitPrice); return(nbi); } } //Applicable but price not match here, or not applicable for all if (!applicable) { //Not applicable for all return(null); } //Get Default Price here MSelectedItem si = (MSelectedItem)bi.Item; ivc = new MIntervalConfig(new CTable("")); String pricingDef = si.PricingDefination; if (si.SelectionType.Equals("1")) { pricingDef = si.ServicePricingDefinition; } ivc.DeserializeConfig(pricingDef); o = null; if (ivc.SelectionType == 1) { //step o = getStepPrice(ivc, bi); } else { //Tier o = getTierPrice(ivc, bi); } if (o != null) { nbi.SetAppliedPackage(pkg); nbi.SetUnitPrice(o.UnitPrice); return(nbi); } return(null); }
public CPrice getStepPrice(MIntervalConfig ivc, CBasketItem bi) { ArrayList intervals = new ArrayList(); int idx = 0; foreach (MInterval iv in ivc.IntervalItems) { iv.Used = 0.00; intervals.Add(iv); idx++; } if (intervals.Count <= 0) { return(null); } double left = bi.Quantity; int cnt = ivc.IntervalItems.Count; idx = 0; while (left > 0) { MInterval iv = (MInterval)intervals[idx]; double from = CUtil.StringToDouble(iv.FromValue); double to = CUtil.StringToDouble(iv.ToValue); double value = CUtil.StringToDouble(iv.ConfigValue); double gap = to - from; iv.RepeatCount++; double used = 0.00; if (left > gap) { left = left - gap; used = gap; } else { used = left; left = 0.00; } iv.Used = iv.Used + used; idx++; if (idx >= cnt) { idx = 0; } } double total = 0.00; foreach (MInterval vi in intervals) { if (ivc.StepScopeType == 1) { total = total + vi.RepeatCount * CUtil.StringToDouble(vi.ConfigValue); } else { //0 - by unit price total = total + vi.Used * CUtil.StringToDouble(vi.ConfigValue); } } CPrice p = new CPrice(); p.TotalAmount = total; p.UnitPrice = total / bi.Quantity; return(p); }
protected CPrice getStepDiscount(MIntervalConfig ivc, CBasketItem bi) { ArrayList intervals = new ArrayList(); MPackage pkg = getPackage(); int idx = 0; foreach (MInterval iv in ivc.IntervalItems) { iv.Used = 0.00; intervals.Add(iv); idx++; } double qty = 0.00; if (ivc.MappingType == 0) { qty = bi.Quantity; } else { //Map by amount //We can use both total bill amount or amount that we use for looking up qty = bi.GetAmount(); } double left = qty; int cnt = ivc.IntervalItems.Count; idx = 0; while (left > 0) { MInterval iv = (MInterval)intervals[idx]; double from = CUtil.StringToDouble(iv.FromValue); double to = CUtil.StringToDouble(iv.ToValue); double value = CUtil.StringToDouble(iv.ConfigValue); double gap = to - from; iv.RepeatCount++; double used = 0.00; if (left > gap) { left = left - gap; used = gap; } else { used = left; left = 0.00; } iv.Used = iv.Used + used; idx++; if (idx >= cnt) { idx = 0; } } double total = 0.00; foreach (MInterval vi in intervals) { if (ivc.TierScopeType == 0) { //Fixed total = total + vi.RepeatCount * CUtil.StringToDouble(vi.ConfigValue); } else if (ivc.TierScopeType == 1) { //Per unit if (ivc.MappingType == 0) { //Map by quantity total = total + vi.Used * CUtil.StringToDouble(vi.ConfigValue); } } else { //2 - Percent of amount if (ivc.MappingType == 1) { //Map by amount //For step, we can use the vi.Used from the amount that we split it up total = total + vi.Used * CUtil.StringToDouble(vi.ConfigValue) / 100; } } } CPrice p = new CPrice(); p.DiscountAmount = total; return(p); }
private CBasketSet finalizeOutput(CBasketSet input, Hashtable filterHash, CPrice accum) { CBasketSet interim = new CBasketSet(); MPackage pkg = getPackage(); double totalBundleAmt = getSumAmount(input, BasketTypeEnum.Bundled); accum.TotalAmount = accum.TotalAmount + totalBundleAmt; double ratio = calculateRatio(accum); if (ratio > 0) { ObservableCollection <MPackageVoucher> gifts = pkg.PackagePostGiftFrees; CBasket nbk = new CBasket(BasketTypeEnum.PostFree); foreach (MPackageVoucher g in gifts) { if (g.EnabledFlag.Equals("N")) { continue; } double qty = CUtil.StringToDouble(g.Quantity) * ratio; if (qty > 0) { MSelectedItem si = createSelectedItem(g); CBasketItem nbi = new CBasketItem(si.Key, si, qty); nbk.AddBasketItem(nbi); } } if (nbk.GetBasketItemCount() > 0) { interim.AddBasket(nbk); giftCount++; } } //Copy the originals to output ArrayList types = input.GetBasketTypes(); foreach (BasketTypeEnum bt in types) { ArrayList baskets = input.GetAllBasketByType(bt); foreach (CBasket bk in baskets) { CBasket obk = new CBasket(bt); obk.CopyEntireFrom(bk); if (isInBasketType(bk.BasketType) && (giftCount > 0)) { updateBasketItem(obk, filterHash); } interim.AddBasket(obk); } } return(interim); }