private void AddTaxCode(RequestContext context, TaxableItem taxableItem, TaxCodeInterval taxCodeInterval, Dictionary <string, TaxCode> codes, SalesTransaction transaction) { TaxCode code = this.GetTaxCode(context, taxableItem, taxCodeInterval, transaction); codes.Add(code.Code, code); this.transactionTaxCodes.Add(code); }
/// <summary> /// Calculates the tax amount properties on this taxable item. /// </summary> /// <param name="taxableItem">The taxable item.</param> private static void CalculateTax(TaxableItem taxableItem) { taxableItem.TaxAmount = taxableItem.TaxLines.Sum(t => t.IsExempt ? decimal.Zero : t.Amount); taxableItem.TaxAmountExclusive = taxableItem.TaxLines.Sum(t => (t.IsExempt || t.IsIncludedInPrice) ? decimal.Zero : t.Amount); taxableItem.TaxAmountInclusive = taxableItem.TaxLines.Sum(t => (t.IsExempt || !t.IsIncludedInPrice) ? decimal.Zero : t.Amount); taxableItem.TaxAmountExemptInclusive = taxableItem.TaxLines.Sum(t => (t.IsExempt && t.IsIncludedInPrice) ? t.Amount : decimal.Zero); }
internal static void AddToTaxItems(SalesTransaction salesTransaction, TaxableItem taxableItem) { // If a taxgroup has been assigned to the saleItem if (taxableItem.ItemTaxGroupId != null) { AddToTaxItems(salesTransaction, taxableItem.TaxLines); } }
/// <summary> /// Gets the tax code. /// </summary> /// <param name="context">The request context.</param> /// <param name="taxableItem">The taxable item.</param> /// <param name="taxCodeInterval">The tax code interval.</param> /// <param name="transaction">Current transaction.</param> /// <returns>The tax code object.</returns> protected virtual TaxCode GetTaxCode(RequestContext context, TaxableItem taxableItem, TaxCodeInterval taxCodeInterval, SalesTransaction transaction) { if (context == null) { throw new ArgumentNullException("context"); } return(new TaxCode(context, taxableItem, taxCodeInterval, this.TaxContext, transaction)); }
protected virtual ReadOnlyCollection <TaxCode> GetTaxCodes(TaxableItem taxableItem, RequestContext context, SalesTransaction transaction) { ThrowIf.Null(taxableItem, "taxableItem"); ThrowIf.Null(context, "context"); try { Dictionary <string, TaxCode> codes = new Dictionary <string, TaxCode>(); // If the line has an EndDate specified (usually because it's a Returned line), // then use that value to calculate taxes, otherwise use BeginDate TaxDateAndGroups key = new TaxDateAndGroups(this.GetTaxDate(taxableItem), taxableItem.SalesTaxGroupId, taxableItem.ItemTaxGroupId); ReadOnlyCollection <TaxCodeInterval> taxCodeIntervals = null; if (key.IsNoTax) { taxCodeIntervals = new List <TaxCodeInterval>().AsReadOnly(); } else if (!this.TaxContext.TaxCodeInternalsLookup.TryGetValue(key, out taxCodeIntervals)) { // Shouldn't get here. taxCodeIntervals = this.GetTaxCodeIntervals(context, taxableItem.SalesTaxGroupId, taxableItem.ItemTaxGroupId, key.TaxDate); } foreach (TaxCodeInterval taxCodeInterval in taxCodeIntervals) { if (codes.ContainsKey(taxCodeInterval.TaxCode)) { // Add a new 'value' entry for an existing tax code var taxInterval = new TaxInterval(taxCodeInterval.TaxLimitMinimum, taxCodeInterval.TaxLimitMaximum, taxCodeInterval.TaxValue); codes[taxCodeInterval.TaxCode].TaxIntervals.Add(taxInterval); } else { this.AddTaxCode(context, taxableItem, taxCodeInterval, codes, transaction); } } // Link any taxes which rely on other taxes foreach (TaxCode tax in codes.Values) { if (!string.IsNullOrEmpty(tax.TaxOnTax) && (tax.TaxBase == TaxBase.PercentPerTax || tax.TaxBase == TaxBase.PercentPerGross) && codes.Keys.Contains(tax.TaxOnTax)) { tax.TaxOnTaxInstance = codes[tax.TaxOnTax]; } } return(this.SortCodes(codes)); } catch (Exception ex) { RetailLogger.Log.CrtServicesTaxCodeProviderTaxServiceGetTaxCodesFailure(ex); throw; } }
private DateTimeOffset GetTaxDate(TaxableItem taxableItem) { DateTimeOffset taxDate = (taxableItem.EndDateTime <= NoDate) ? taxableItem.BeginDateTime : taxableItem.EndDateTime; if (taxDate == DateTimeOffset.MinValue) { taxDate = this.TaxContext.NowInChannelTimeZone; } return(taxDate); }
/// <summary> /// Retrieves a list of TaxCodes for the given sale line item. /// </summary> /// <param name="taxableItem">The taxable item.</param> /// <param name="context">The context.</param> /// <param name="transaction">Current transaction.</param> /// <returns>Tax codes applicable with the taxableItem.</returns> /// <remarks> /// No user input or variable in the SQL query. No SQL injection threat. /// </remarks> protected override ReadOnlyCollection <TaxCode> GetTaxCodes(TaxableItem taxableItem, RequestContext context, SalesTransaction transaction) { // Only use codes that are not processed as India tax codes, or those that are and are // supported. return(new ReadOnlyCollection <TaxCode>(base.GetTaxCodes(taxableItem, context, transaction).Where(c => { var codeIndia = c as TaxCodeIndia; bool isChargeLine = taxableItem is ChargeLine; return codeIndia == null || SupportedTax(isChargeLine, codeIndia, context); }).ToList <TaxCode>())); }
/// <summary> /// Calculates the tax amount properties on this taxable item. /// </summary> /// <param name="taxableItem">The taxable item.</param> public static void CalculateTax(TaxableItem taxableItem) { if (taxableItem == null) { throw new ArgumentNullException("taxableItem"); } taxableItem.TaxAmount = taxableItem.TaxLines.Sum(t => t.IsExempt ? decimal.Zero : t.Amount); taxableItem.TaxAmountExclusive = taxableItem.TaxLines.Sum(t => (t.IsExempt || t.IsIncludedInPrice) ? decimal.Zero : t.Amount); taxableItem.TaxAmountInclusive = taxableItem.TaxLines.Sum(t => (t.IsExempt || !t.IsIncludedInPrice) ? decimal.Zero : t.Amount); taxableItem.TaxAmountExemptInclusive = taxableItem.TaxLines.Sum(t => (t.IsExempt && t.IsIncludedInPrice) ? t.Amount : decimal.Zero); }
/// <summary> /// Gets the duty taxes. /// </summary> /// <param name="lineItem">The line item.</param> /// <param name="codes">The codes.</param> /// <returns>Sum of duty taxes applicable on the line.</returns> private static decimal GetApplicableDutyTaxes(TaxableItem lineItem, IEnumerable <TaxCode> codes) { decimal dutyTaxSum = 0; if (lineItem != null && !codes.IsNullOrEmpty()) { var dutyTaxes = codes.Where(c => c.IsTaxIncludedInTax); dutyTaxSum = dutyTaxes.Sum(dt => dt.Value * Math.Abs(lineItem.Quantity)); } return(dutyTaxSum); }
/// <summary> /// Sets the line item tax rate. /// </summary> /// <param name="taxableItem">The taxable item.</param> /// <param name="taxAmount">The tax amount.</param> protected static void SetLineItemTaxRate(TaxableItem taxableItem, decimal taxAmount) { if (taxableItem == null) { throw new ArgumentNullException("taxableItem"); } decimal extendedPrice = taxableItem.Price * taxableItem.Quantity; if (extendedPrice == decimal.Zero) { extendedPrice = 1; } taxableItem.TaxRatePercent += (taxAmount * 100) / extendedPrice; }
/// <summary> /// Simple version of TaxIncluded algorithm for tax code collections that are not based on: /// intervals, limits, collection limits and total invoice. /// </summary> /// <param name="lineItem">The taxable item.</param> /// <param name="codes">The collection of tax codes.</param> /// <returns>The base price.</returns> private static decimal GetBasePriceSimpleTaxIncluded(TaxableItem lineItem, ReadOnlyCollection <TaxCode> codes) { // accumulation of % based tax decimal fullLineTaxRate = decimal.Zero; // accumulation of amount based tax decimal fullLineUnitTax = decimal.Zero; decimal nonExemptLineUnitTax = decimal.Zero; // 1. Determine sum of all AmountByUnit taxes (ref: AX\Classes\Tax.AmountExclTax() - line 222) decimal codeValue = decimal.Zero; // Reference dev item 5747 foreach (TaxCode code in codes.Where(c => c.TaxBase == TaxBase.AmountByUnit)) { codeValue = code.Calculate(codes, false); // Amount by units don't depend on basePrice fullLineUnitTax += codeValue; nonExemptLineUnitTax += code.Exempt ? decimal.Zero : codeValue; } // 2. Determine sum of all tax rates for non-AmountByUnit taxes (ref: AX\Classes\Tax.AmountExclTax() - line 331) foreach (TaxCode code in codes.Where(c => c.TaxBase != TaxBase.AmountByUnit)) { if (code.TaxBase == TaxBase.PercentPerGross && string.IsNullOrEmpty(code.TaxOnTax)) { // Sum all OTHER taxes... codeValue = codes.Sum(c => (c.TaxBase == TaxBase.AmountByUnit) ? decimal.Zero : c.PercentPerTax()); // And then apply the Gross tax on top of that codeValue *= code.PercentPerTax() / 100; // Add this rate to the running total. fullLineTaxRate += codeValue; } else { // Add this rate to the running total. codeValue = code.PercentPerTax(); fullLineTaxRate += codeValue; } } // 3. Back calculate the Price based on tax rates, start with the Price that includes ALL taxes decimal taxBase = lineItem.NetAmountWithAllInclusiveTaxPerUnit - fullLineUnitTax; return((taxBase * 100) / (100 + fullLineTaxRate)); }
/// <summary> /// Sets the line item tax rate. /// </summary> /// <param name="taxableItem">The taxable item.</param> /// <param name="lineTaxResult">The line tax result.</param> protected static void SetLineItemTaxRate(TaxableItem taxableItem, LineTaxResult lineTaxResult) { if (taxableItem == null) { throw new ArgumentNullException("taxableItem"); } if (lineTaxResult == null) { throw new ArgumentNullException("lineTaxResult"); } // Ignore any portion of the TaxAmount that is 'Exempt' when computing the rate. decimal amount = lineTaxResult.TaxAmount - lineTaxResult.ExemptAmount; SetLineItemTaxRate(taxableItem, amount); }
/// <summary> /// Gets the tax code. /// </summary> /// <param name="context">The request context.</param> /// <param name="taxableItem">The taxable item.</param> /// <param name="taxCodeInterval">The tax code interval.</param> /// <param name="transaction">Current transaction.</param> /// <returns>The tax code object.</returns> protected override TaxCode GetTaxCode(RequestContext context, TaxableItem taxableItem, TaxCodeInterval taxCodeInterval, SalesTransaction transaction) { if (context == null) { throw new ArgumentNullException("context"); } TaxCodeIntervalIndia taxCodeIntervalIndia = taxCodeInterval as TaxCodeIntervalIndia; if (taxCodeIntervalIndia.TaxType == TaxTypeIndia.None) { return(base.GetTaxCode(context, taxableItem, taxCodeInterval, transaction)); } else { return(new TaxCodeIndia(context, taxableItem, taxCodeIntervalIndia, this.TaxContext, transaction)); } }
/// <summary> /// Initializes a new instance of the <see cref="TaxCodeIndia"/> class. /// </summary> /// <param name="context">The request context.</param> /// <param name="taxableItem">The taxable line item.</param> /// <param name="taxCodeInterval">The tax code interval.</param> /// <param name="taxContext">Tax context.</param> /// <param name="transaction">Current transaction.</param> public TaxCodeIndia( RequestContext context, TaxableItem taxableItem, TaxCodeIntervalIndia taxCodeInterval, TaxContext taxContext, SalesTransaction transaction) : base(context, taxableItem, taxCodeInterval, taxContext, transaction) { if (context == null) { throw new ArgumentNullException("context"); } if (taxCodeInterval == null) { throw new ArgumentNullException("taxCodeInterval"); } this.TaxType = taxCodeInterval.TaxType; this.AbatementPercent = taxCodeInterval.AbatementPercent; this.taxCodesInFormula = new List <string>(); }
/// <summary> /// Gets the base price for tax included. /// </summary> /// <param name="taxableItem">The taxable item.</param> /// <param name="codes">The codes.</param> /// <param name="taxContext">The tax context.</param> /// <returns>The base price for tax included.</returns> public static decimal GetBasePriceForTaxIncluded(TaxableItem taxableItem, ReadOnlyCollection <TaxCode> codes, TaxContext taxContext) { // check to see if we can do the 'simple' Inclusive algorithm bool simpleBasis = codes.All(c => (c.TaxBase == TaxBase.PercentPerNet || c.TaxBase == TaxBase.PercentGrossOnNet) && (c.TaxLimitMin == decimal.Zero && c.TaxLimitMax == decimal.Zero)); bool collectLimits = codes.Any(c => (c.CollectLimitMax != decimal.Zero || c.CollectLimitMin != decimal.Zero)); bool multiplePercentage = codes.Any(c => (c.TaxIntervals.Count > 1)); if (simpleBasis && !collectLimits && !multiplePercentage) { // Get base price for Simple TaxInclusive calculation return(GetBasePriceSimpleTaxIncluded(taxableItem, codes)); } else { // Get base price for Full TaxInclusive calculation return(GetBasePriceAdvancedTaxIncluded(taxableItem, codes, collectLimits, taxContext)); } }
/// <summary> /// Initializes a new instance of the <see cref="TaxCode"/> class. /// </summary> /// <param name="context">The request context.</param> /// <param name="lineItem">The taxable line item.</param> /// <param name="interval">The tax code interval.</param> /// <param name="taxContext">Tax context.</param> /// <param name="transaction">Current transaction.</param> public TaxCode(RequestContext context, TaxableItem lineItem, TaxCodeInterval interval, TaxContext taxContext, SalesTransaction transaction) { if (context == null) { throw new ArgumentNullException("context"); } if (interval == null) { throw new ArgumentNullException("interval"); } this.Code = interval.TaxCode; this.TaxableEntity = lineItem; this.TaxGroup = interval.TaxItemGroup; this.Currency = interval.TaxCurrencyCode; this.Exempt = interval.IsTaxExempt; this.TaxBase = (TaxBase)interval.TaxBase; this.TaxLimitBase = (TaxLimitBase)interval.TaxLimitBase; this.TaxCalculationMethod = (TaxCalculationMode)interval.TaxCalculationMethod; this.TaxOnTax = interval.TaxOnTax; this.Unit = interval.TaxUnit; this.RoundingOff = interval.TaxRoundOff; this.RoundingOffType = Rounding.ConvertRoundOffTypeToRoundingMethod(interval.TaxRoundOffType); this.CollectLimitMax = interval.TaxMaximum; this.CollectLimitMin = interval.TaxMinimum; this.TaxGroupRounding = interval.IsGroupRounding; this.IsTaxIncludedInTax = interval.IsTaxIncludedInTax; this.TaxIntervals = new Collection <TaxInterval>(new List <TaxInterval>(1)); // should this be removed in favor of intervals? this.Value = interval.TaxValue; this.TaxLimitMin = interval.TaxLimitMinimum; this.TaxLimitMax = interval.TaxLimitMaximum; this.RequestContext = context; this.Transaction = transaction; this.TaxIntervals.Add(new TaxInterval(interval.TaxLimitMinimum, interval.TaxLimitMaximum, interval.TaxValue)); this.TaxContext = taxContext; }
/// <summary> /// Calculate tax on the given line item. /// </summary> /// <param name="taxableItem">The taxable item.</param> /// <param name="context">The context.</param> /// <param name="transaction">Current transaction.</param> private void CalculateTax(TaxableItem taxableItem, RequestContext context, SalesTransaction transaction) { ReadOnlyCollection <TaxCode> codes = this.GetTaxCodes(taxableItem, context, transaction); LineTaxResult lineTaxResult = new LineTaxResult { HasExempt = false, TaxRatePercent = decimal.Zero, TaxAmount = decimal.Zero, ExemptAmount = decimal.Zero }; foreach (TaxCode code in codes) { var taxCodeAmount = code.CalculateTaxAmount(codes, this.taxCodeAmountRounder); lineTaxResult.TaxAmount += taxCodeAmount; // sum up the amounts that are exempt if (code.Exempt) { lineTaxResult.HasExempt = true; lineTaxResult.ExemptAmount += lineTaxResult.TaxAmount; } } // Set the 'virtual tax rate', if extended price is ZERO, then just add the full amount decimal extendedPrice = taxableItem.Price * Math.Abs(taxableItem.Quantity); if (extendedPrice == decimal.Zero) { extendedPrice = decimal.One; } lineTaxResult.TaxRatePercent = (lineTaxResult.TaxAmount * 100) / extendedPrice; SetLineItemTaxRate(taxableItem, lineTaxResult); }
private void TaxItems(ITaxSchedule schedule, List <ITaxable> items, IAddress address) { if (schedule == null) { return; } if (items == null) { return; } if (address == null) { return; } // Holds all taxes for the schedule summarized TaxableItem summaryForSchedule = new TaxableItem(); summaryForSchedule.ScheduleId = schedule.TaxScheduleId(); // Find all items that match the schedule List <ITaxable> itemsMatchingSchedule = new List <ITaxable>(); foreach (ITaxable item in items) { if (item.TaxScheduleId() == schedule.TaxScheduleId()) { summaryForSchedule.Value += item.TaxableValue(); summaryForSchedule.ShippingValue += item.TaxableShippingValue(); itemsMatchingSchedule.Add(item); } } // Now Apply all taxes in schedule to total price of all items foreach (ITaxRate rate in _app.OrderServices.Taxes.GetRates(_app.CurrentStore.Id, schedule.TaxScheduleId())) { rate.TaxItem(summaryForSchedule, address); } // Total Tax for all items on this schedule is calculated // Now, we assign the tax parts to each line item based on their // linetotal value. The last item should get the remainder of the tax decimal RoundedTotal = Math.Round(summaryForSchedule.TaxedValue, 2); decimal TotalApplied = 0M; for (int i = 0; i < itemsMatchingSchedule.Count(); i++) { ITaxable item = itemsMatchingSchedule[i]; item.ClearTaxValue(); if (i == itemsMatchingSchedule.Count() - 1) { // last item item.IncrementTaxValue(RoundedTotal - TotalApplied); } else { decimal percentOfTotal = 0; if (summaryForSchedule.TaxableValue() != 0) { percentOfTotal = item.TaxableValue() / summaryForSchedule.TaxableValue(); } decimal part = Math.Round(percentOfTotal * summaryForSchedule.TaxedValue, 2); item.IncrementTaxValue(part); TotalApplied += part; } } }
private static decimal GetBasePriceAdvancedTaxIncluded( TaxableItem taxableItem, ReadOnlyCollection <TaxCode> codes, bool collectLimits, TaxContext taxContext) { // accumulation of amount based tax decimal fullLineUnitTax = decimal.Zero; decimal nonExemptLineUnitTax = decimal.Zero; decimal codeValue = decimal.Zero; // AX variables decimal endAmount = taxableItem.NetAmountWithAllInclusiveTaxPerUnit; // endAmount will be the final price w/o tax int sign = 1; // 3. decimal taxLimitMax = decimal.Zero; decimal taxLimitMin = decimal.Zero; decimal startAmount = decimal.Zero; // 3a... decimal taxCalc = decimal.Zero; decimal baseCur; // Tax Amount deducted for a given Code Dictionary <string, decimal> deductedTax = new Dictionary <string, decimal>(); // 3b ... decimal percentTotal; decimal tmpBase; // 3c.. // Whether or not a Code needs to be removed from the sum of percent rates Dictionary <string, bool> removePercent = new Dictionary <string, bool>(); // 3d. decimal totalTax = decimal.Zero; // Whether or not the Code needs to be calculated Dictionary <string, bool> calcTax = new Dictionary <string, bool>(); string storeCurrency = taxContext.ChannelCurrency; // Begin Tax included calculation // 0. Initialize the supporting collections foreach (TaxCode code in codes) { deductedTax[code.Code] = decimal.Zero; removePercent[code.Code] = false; calcTax[code.Code] = true; } // 1. Remove all AmountByUnit taxes foreach (TaxCode code in codes.Where(c => c.TaxBase == TaxBase.AmountByUnit)) { codeValue = code.Calculate(codes, false); // Reference dev item 5748. fullLineUnitTax += codeValue; nonExemptLineUnitTax += code.Exempt ? decimal.Zero : codeValue; calcTax[code.Code] = false; } endAmount -= Math.Abs(nonExemptLineUnitTax); // 2. Record the sign, and then continue using the magnitude of endAmount sign = (endAmount < decimal.Zero) ? -1 : 1; endAmount = Math.Abs(endAmount); // 3. while (startAmount < endAmount) { // 3a Consider interval limits taxCalc = decimal.Zero; taxLimitMax = decimal.Zero; foreach (TaxCode code in codes) { if (code.TaxCalculationMethod == TaxCalculationMode.FullAmounts) { taxLimitMax = decimal.Zero; } else { if (code.IsStoreCurrency) { baseCur = taxContext.TaxCurrencyOperations.ConvertCurrency(storeCurrency, code.Currency, taxLimitMin); } else { baseCur = taxLimitMin; } baseCur += 1; // if 'baseCur' falls into an interval if (code.TaxIntervals.Exists(baseCur)) { // get the Upper limit of the interval that 'baseCur'/'taxLimitMin' falls into decimal amount = code.TaxIntervals.Find(taxLimitMin + 1).TaxLimitMax; taxLimitMax = (amount != decimal.Zero && amount < endAmount) ? amount : endAmount; } } taxCalc += deductedTax[code.Code]; } // 3b. Sum up all the Tax Percentage Rates percentTotal = 0; tmpBase = (taxLimitMax > decimal.Zero) ? taxLimitMax : endAmount; foreach (TaxCode code in codes.Where(c => calcTax[c.Code])) { percentTotal += GetPercentPerTax(code, tmpBase, codes); } decimal taxMax; decimal baseInclTax; decimal baseExclTax; // 3c. // if this is the last interval?? if (taxLimitMax == decimal.Zero) { // Forward calculate taxes to see if we exceed the CollectLimit foreach (TaxCode code in codes.Where(c => calcTax[c.Code])) { taxMax = code.CollectLimitMax; baseInclTax = endAmount - taxLimitMin - taxCalc; baseExclTax = baseInclTax * 100 / (100 + percentTotal); if (taxMax != decimal.Zero) { tmpBase = endAmount; decimal percent = GetPercentPerTax(code, tmpBase, codes); if ((deductedTax[code.Code] + (baseExclTax * percent / 100)) > taxMax) { deductedTax[code.Code] = taxMax; removePercent[code.Code] = true; } } } // 3d. // Now remove any rates that exceed their LimitMax foreach (TaxCode code in codes) { if (removePercent[code.Code] && calcTax[code.Code]) { tmpBase = endAmount; percentTotal -= GetPercentPerTax(code, tmpBase, codes); calcTax[code.Code] = false; } taxCalc += deductedTax[code.Code]; } } // 4. Compute tax adjusted for limits totalTax = decimal.Zero; foreach (TaxCode code in codes.Where(c => c.TaxBase != TaxBase.AmountByUnit)) { if (calcTax[code.Code]) { tmpBase = (taxLimitMax > decimal.Zero) ? taxLimitMax : endAmount; decimal percent = GetPercentPerTax(code, tmpBase, codes); if (taxLimitMax > decimal.Zero && taxLimitMax < endAmount) { deductedTax[code.Code] += (taxLimitMax - taxLimitMin) * percent / 100; } else { baseInclTax = endAmount - taxLimitMin - taxCalc; baseExclTax = baseInclTax * 100 / (100 + percentTotal); deductedTax[code.Code] += baseExclTax * percent / 100; } taxMax = code.CollectLimitMax; if (taxMax > decimal.Zero && deductedTax[code.Code] > taxMax) { deductedTax[code.Code] = taxMax; } } totalTax += deductedTax[code.Code]; } if (taxLimitMax > decimal.Zero) { taxLimitMin = taxLimitMax; startAmount = taxLimitMin + totalTax; } else { startAmount = endAmount; } } // END if( startAmount < endAmount) // 5a. Total up taxes foreach (TaxCode code in codes) { if (collectLimits && (deductedTax[code.Code] < code.CollectLimitMin)) { totalTax -= deductedTax[code.Code]; deductedTax[code.Code] = decimal.Zero; } if (code.IsStoreCurrency) { taxCalc = Rounding.RoundToUnit(deductedTax[code.Code], code.RoundingOff, code.RoundingOffType); } else { taxCalc = deductedTax[code.Code]; } totalTax += taxCalc - deductedTax[code.Code]; deductedTax[code.Code] = taxCalc; } // 5b. Determine base price return((endAmount - totalTax) * sign); }
/// <summary> /// Return a sum of all the currently applied tax amounts. /// </summary> /// <param name="lineItem">The line item.</param> /// <returns>The summation of all tax amount.</returns> private static decimal SumAllTaxAmounts(TaxableItem lineItem) { decimal allTaxAmounts = lineItem.TaxLines.Sum(t => t.IsExempt ? decimal.Zero : t.Amount); return(allTaxAmounts); }