/// <summary> /// Only support: /// Codes that are of the supported tax basis. /// And codes that are defined in the formula (Id > 0). /// And codes that are of either ServiceTax or VAT or SalesTax. /// </summary> /// <param name="isChargeLine">Indicate whether taxable item is chargeLine.</param> /// <param name="codeIndia">The tax code.</param> /// <param name="context">The request context.</param> /// <returns>The flag indicating whether the tax type is supported or not.</returns> private static bool SupportedTax(bool isChargeLine, TaxCodeIndia codeIndia, RequestContext context) { GetTaxParameterDataRequest dataRequest = new GetTaxParameterDataRequest(QueryResultSettings.AllRecords); TaxParameters taxParameter = context.Execute <SingleEntityDataServiceResponse <TaxParameters> >(dataRequest).Entity; // Only support service tax for misc charges if (isChargeLine) { return((codeIndia.Formula.SupportedTaxBasisForMiscCharge && codeIndia.Formula.Id > 0) && (codeIndia.TaxType == TaxTypeIndia.ServiceTax && taxParameter.ServiceTaxIndia)); } if (codeIndia.Formula.SupportedTaxBasis && codeIndia.Formula.Id > 0) { if (codeIndia.TaxType == TaxTypeIndia.SalesTax && taxParameter.SalesTaxIndia) { return(true); } if (codeIndia.TaxType == TaxTypeIndia.ServiceTax && taxParameter.ServiceTaxIndia) { return(true); } if (codeIndia.TaxType == TaxTypeIndia.VAT && taxParameter.VATIndia) { return(true); } } return(false); }
/// <summary> /// Back calculates the base price for items with included taxes. Based off of the class in AX /// <c>Tax.calcBaseAmtExclTax_IN</c>. /// </summary> /// <param name="baseLine">The base line amount.</param> /// <param name="codes">The tax codes.</param> /// <param name="formula">The formula value.</param> /// <param name="context">The request context.</param> /// <returns>The base price.</returns> private static decimal GetBasePriceForTaxIncluded(decimal baseLine, ReadOnlyCollection <TaxCode> codes, FormulaIndia formula, RequestContext context) { decimal taxVal; // A summarized tax rate for this code computed from the formula decimal taxValLine; // The summed tax rates for all codes for this line decimal amtPerUnitVal; // A summarized amount per unit contribution for this code computed from the formula decimal amtPerUnitLine; // The summed amount per unit contributions for all codes for this line. taxValLine = decimal.Zero; amtPerUnitLine = decimal.Zero; foreach (var code in codes) { taxVal = decimal.Zero; amtPerUnitVal = decimal.Zero; if (code.TaxIncludedInPrice) { // Handle codes differently based on whether they are India or not. TaxCodeIndia codeIndia = code as TaxCodeIndia; if (codeIndia != null) { CalculateTaxAmountsIndia(codes, codeIndia, ref amtPerUnitVal, ref taxVal, formula, context); } else { CalculateTaxAmounts(code, ref amtPerUnitVal, ref taxVal); } code.TaxValue = taxVal; code.AmountPerUnitValue = amtPerUnitVal; } taxValLine += taxVal; amtPerUnitLine += amtPerUnitVal; } // Back compute and set the price from price with tax (baseLine). return((Math.Abs(baseLine) - amtPerUnitLine) / (1 + taxValLine)); }
/// <summary> /// Sorts the specified tax codes by priority. /// </summary> /// <param name="codes">The tax codes.</param> /// <returns>An ordered collection of tax codes.</returns> protected override ReadOnlyCollection <TaxCode> SortCodes(Dictionary <string, TaxCode> codes) { if (codes == null) { throw new ArgumentNullException("codes"); } // Return codes to be processed in the following order: // Non-India codes // India codes ordered by Id return(new ReadOnlyCollection <TaxCode>( codes.Values.OrderBy(code => { TaxCodeIndia codeIndia = code as TaxCodeIndia; if (codeIndia != null) { return codeIndia.Formula.Id + MaxPriorityTaxCode + 1; } else { return TaxCodeProvider.TaxCodePriority(code); } }).ToList())); }
/// <summary> /// Calculates the tax amounts india. /// </summary> /// <param name="codes">The codes.</param> /// <param name="codeIndia">The code india.</param> /// <param name="amtPerUnitVal">The value of the amount per unit.</param> /// <param name="taxVal">The tax value.</param> /// <param name="formula">The formula value.</param> /// <param name="context">The request context.</param> private static void CalculateTaxAmountsIndia(ReadOnlyCollection <TaxCode> codes, TaxCodeIndia codeIndia, ref decimal amtPerUnitVal, ref decimal taxVal, FormulaIndia formula, RequestContext context) { decimal amtPerUnit = decimal.Zero; decimal taxCodeValue = decimal.Zero; decimal taxValueLoc; taxVal = decimal.Zero; amtPerUnitVal = decimal.Zero; if (codeIndia.Formula.TaxableBasis != TaxableBasisIndia.ExclusiveLineAmount && codeIndia.Formula.TaxableBasis != formula.TaxableBasis) { return; } string[] tokens = codeIndia.Formula.ParseExpression(); if (tokens.Length > 1) { GetTaxCodeFormulaIndiaDataRequest dataRequest = new GetTaxCodeFormulaIndiaDataRequest(codeIndia.TaxGroup, tokens[1]); FormulaIndia basisFormula = context.Execute <SingleEntityDataServiceResponse <FormulaIndia> >(dataRequest).Entity; if (basisFormula != null && basisFormula.TaxableBasis == formula.TaxableBasis) { // Iterate through the formula for (int index = 1; index < tokens.Length; index += 2) { TaxCode basisCode = (from c in codes where c.Code == tokens[index] select c).FirstOrDefault(); if ((basisCode != null) && !basisCode.Exempt) { codeIndia.IsTaxOnTax = true; if (!codeIndia.taxCodesInFormula.Contains(basisCode.Code)) { codeIndia.taxCodesInFormula.Add(basisCode.Code); } ////Either add or subtract the values based on the operator switch (tokens[index - 1]) { case "-": if (basisCode.TaxBase == TaxBase.AmountByUnit) { amtPerUnit -= basisCode.AmountPerUnitValue; } else { taxCodeValue -= basisCode.TaxValue; } break; case "+": if (basisCode.TaxBase == TaxBase.AmountByUnit) { amtPerUnit += basisCode.AmountPerUnitValue; } else { taxCodeValue += basisCode.TaxValue; } break; default: RetailLogger.Log.CrtServicesTaxCodeIndiaTaxServiceNotSupportedOperatorFoundInTaxAmountCalculation(tokens[index - 1]); break; } } } } } taxValueLoc = codeIndia.Value; if (codeIndia.TaxBase == TaxBase.AmountByUnit) { taxVal = decimal.Zero; amtPerUnitVal = taxValueLoc; } else { if (codeIndia.Formula.TaxableBasis != TaxableBasisIndia.ExclusiveLineAmount) { taxVal = ((1 + taxCodeValue) * taxValueLoc) / 100; } else { taxVal = (taxCodeValue * taxValueLoc) / 100; } taxVal *= (100 - codeIndia.AbatementPercent) / 100; amtPerUnitVal = amtPerUnit * taxValueLoc / 100; } }