Пример #1
0
        /// <summary>
        /// Get the PercentRate for a given Tax (takes Gross Taxes into account)
        /// </summary>
        /// <param name="code"></param>
        /// <param name="taxBase"></param>
        /// <param name="otherCodes"></param>
        /// <returns></returns>
        private static decimal GetPercentPerTax(TaxCode code, decimal taxBase, ReadOnlyCollection <TaxCode> otherCodes)
        {
            decimal percent = decimal.Zero;

            if (code.TaxBase == TaxBase.PercentPerGross)
            {
                decimal otherPercents = decimal.Zero;
                foreach (TaxCode t in otherCodes.Where(c => (c.Code != code.Code && c.TaxBase != TaxBase.AmountByUnit)))
                {
                    otherPercents += t.PercentPerTax(taxBase);
                }

                decimal grossPercent = code.PercentPerTax(taxBase);

                //Gross Percent needs to be expressed with respect to the original item price:
                // ActualPercent = GrossPercent * (full price + other taxes)/100
                percent = grossPercent * (100 + otherPercents) / 100m;
            }
            else
            {
                percent = code.PercentPerTax(taxBase);
            }

            return(percent);
        }
Пример #2
0
 /// <summary>
 /// Calculates the tax amounts for non India tax codes (simple tax codes only supported).
 /// </summary>
 /// <param name="code">The code.</param>
 /// <param name="amtPerUnitVal">The amt per unit val.</param>
 /// <param name="taxVal">The tax val.</param>
 private static void CalculateTaxAmounts(TaxCode code, ref decimal amtPerUnitVal, ref decimal taxVal)
 {
     if (code.TaxBase == TaxBase.AmountByUnit)
     {
         amtPerUnitVal = code.Value;
         taxVal        = decimal.Zero;
     }
     else
     {
         amtPerUnitVal = decimal.Zero;
         taxVal        = code.Value;
     }
 }
Пример #3
0
        private void AddTaxCode(CacheKey cacheKey, SqlDataReader reader, ITaxableItem taxableItem, Dictionary <string, TaxCode> codes)
        {
            TaxCode code = GetTaxCode(reader, taxableItem);

            codes.Add(code.Code, code);

            if (!taxCodeCache.ContainsKey(cacheKey))
            {
                taxCodeCache[cacheKey] = new List <TaxCode>()
                {
                    code
                }
            }
            ;
            else
            {
                taxCodeCache[cacheKey].Add(code);
            }
        }
Пример #4
0
        protected static int TaxCodePriority(TaxCode code)
        {
            // Return codes to be processed in the following order:
            // 1. Amount per unit & Percent of net & Percent Gross on net
            // 2. Percent of tax
            // 3. Percent of gross (single tax)
            // 4. Percent of gross (all taxes)
            switch (code.TaxBase)
            {
            case TaxBase.AmountByUnit:
            case TaxBase.PercentPerNet:
            case TaxBase.PercentGrossOnNet:
                return(1);

            case TaxBase.PercentPerTax:
                return(2);

            case TaxBase.PercentPerGross:
                return(string.IsNullOrEmpty(code.TaxOnTax) ? MaxPriorityTaxCode : 3);

            default:
                return(0);
            }
        }
Пример #5
0
        /// <summary>
        /// Get the bases for tax calculations
        /// </summary>
        /// <param name="codes">The collection of tax codes.</param>
        /// <param name="taxInStoreCurrency">if set to <c>true</c> [tax in store currency].</param>
        /// <param name="calculateBasePrice">if set to <c>true</c> [Calculate the base price].</param>
        /// <param name="calculationBase">The calculation base.</param>
        /// <param name="limitBase">The limit base.</param>
        protected virtual void GetBases(ReadOnlyCollection <TaxCode> codes,
                                        bool taxInStoreCurrency,
                                        bool calculateBasePrice,
                                        out decimal calculationBase,
                                        out decimal limitBase)
        {
            decimal basePrice = decimal.Zero;

            if (calculateBasePrice)
            {
                basePrice = this.TaxIncludedInPrice ?
                            Provider.GetBasePriceForTaxIncluded(this.LineItem, codes) :
                            LineItem.NetAmountPerUnit;
            }

            //1. Get initial value for the Calculation Base
            switch (this.TaxBase)
            {
            case TaxBase.PercentPerTax:

                // Base is the amount of the other tax
                switch (this.TaxLimitBase)
                {
                case TaxLimitBase.InvoiceWithoutVat:
                case TaxLimitBase.InvoiceWithVat:
                    calculationBase = Math.Abs(this.CalculateTaxOnTax(this.LineItem.RetailTransaction));
                    break;

                case TaxLimitBase.UnitWithoutVat:
                case TaxLimitBase.UnitWithVat:
                    // if this tax's Limit is per-unit, then we need to convert the existing tax amounts from per-line to per-unit
                    decimal quantity = (this.LineItem.Quantity == decimal.Zero) ? decimal.One : this.LineItem.Quantity;
                    calculationBase = Math.Abs(this.CalculateTaxOnTax()) / Math.Abs(quantity);
                    break;

                default:
                    calculationBase = Math.Abs(this.CalculateTaxOnTax());
                    break;
                }
                break;

            case TaxBase.PercentPerGross:

                // Base is the price + other taxes
                calculationBase = basePrice;

                // If the Limit base is NOT per-unit, then we need to factor in the line quanity
                if (TaxLimitBase != TaxLimitBase.UnitWithoutVat && TaxLimitBase != TaxLimitBase.UnitWithVat)
                {
                    calculationBase *= Math.Abs(this.LineItem.Quantity);
                }

                if (!string.IsNullOrEmpty(this.TaxOnTax))
                {
                    // Base is the Price + the amount of a single other tax
                    calculationBase += Math.Abs(this.CalculateTaxOnTax());
                }
                else
                {
                    // Base is the Price + all other taxes
                    calculationBase += Math.Abs(TaxCode.SumAllTaxAmounts(this.LineItem));
                }

                break;

            case TaxBase.AmountByUnit:
                calculationBase = AmountPerUnitCalculationBase;
                break;

            case TaxBase.PercentPerNet:
            case TaxBase.PercentGrossOnNet:
            default:

                // Base is the Price
                calculationBase = basePrice;

                // If the Limit base is NOT per-unit, then we need to factor in the line quanity
                if (TaxLimitBase != TaxLimitBase.UnitWithoutVat && TaxLimitBase != TaxLimitBase.UnitWithVat)
                {
                    calculationBase *= Math.Abs(this.LineItem.Quantity);
                }

                break;
            }

            //3. Set Limit Base
            if (this.TaxBase == TaxBase.AmountByUnit)
            {
                // Base for limits/intervals is base-quantity * price
                limitBase = calculationBase * basePrice;

                // Convert limit base to Tax currency, if different
                if (!taxInStoreCurrency)
                {
                    limitBase = TaxService.Tax.InternalApplication.Services.Currency.CurrencyToCurrency(
                        ApplicationSettings.Terminal.StoreCurrency,
                        this.Currency,
                        limitBase);
                }

                // If the tax is calculated in a different UOM, then convert if possible
                // this is only applicable for lineItem taxes.
                BaseSaleItem saleLineItem = this.LineItem as BaseSaleItem;

                if (saleLineItem != null &&
                    !string.Equals(this.Unit, this.LineItem.SalesOrderUnitOfMeasure, StringComparison.OrdinalIgnoreCase))
                {
                    UnitOfMeasureData uomData = new UnitOfMeasureData(
                        ApplicationSettings.Database.LocalConnection,
                        ApplicationSettings.Database.DATAAREAID,
                        ApplicationSettings.Terminal.StorePrimaryId,
                        TaxService.Tax.InternalApplication);
                    UnitQtyConversion uomConversion = uomData.GetUOMFactor(this.LineItem.SalesOrderUnitOfMeasure, this.Unit, saleLineItem);
                    calculationBase *= uomConversion.GetFactorForQty(this.LineItem.Quantity);
                }
            }
            else
            {
                // Convert base to Tax currency, if different
                if (!taxInStoreCurrency)
                {
                    calculationBase = TaxService.Tax.InternalApplication.Services.Currency.CurrencyToCurrency(
                        ApplicationSettings.Terminal.StoreCurrency,
                        this.Currency,
                        calculationBase);
                }

                // Base for limits/intervals is same for Calculations
                limitBase = calculationBase;
            }
        }
Пример #6
0
 /// <summary>
 /// Whether or not a given TaxCode is in the Store Currency
 /// </summary>
 /// <param name="code"></param>
 /// <returns></returns>
 private static bool IsStoreCurrency(TaxCode code)
 {
     return(string.IsNullOrEmpty(code.Currency) ||
            code.Currency.Equals(ApplicationSettings.Terminal.StoreCurrency, StringComparison.OrdinalIgnoreCase));
 }
Пример #7
0
        /// <summary>
        /// Calculates the tax amounts india.
        /// </summary>
        /// <param name="codes">The codes.</param>
        /// <param name="codeIndia">The code india.</param>
        /// <param name="amtPerUnitVal">The amt per unit val.</param>
        /// <param name="taxVal">The tax val.</param>
        /// <param name="formula">The formula val.</param>
        private static void CalculateTaxAmountsIndia(ReadOnlyCollection <TaxCode> codes, TaxCodeIndia codeIndia, ref decimal amtPerUnitVal, ref decimal taxVal, Formula formula)
        {
            decimal amtPerUnit   = decimal.Zero;
            decimal taxCodeValue = decimal.Zero;
            decimal taxValueLoc;

            taxVal        = decimal.Zero;
            amtPerUnitVal = decimal.Zero;

            if (codeIndia.Formula.TaxableBasis != TaxableBases.ExclAmount && codeIndia.Formula.TaxableBasis != formula.TaxableBasis)
            {
                return;
            }

            string[] tokens = codeIndia.Formula.ParseExpression();

            if (tokens.Length > 1)
            {
                Formula basisFormula = FormulaData.GetFormula(codeIndia.TaxGroup, tokens[1]);

                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;
                            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.AmtPerUnitValue;
                                }
                                else
                                {
                                    taxCodeValue -= basisCode.TaxValue;
                                }
                                break;

                            case "+":
                                if (basisCode.TaxBase == TaxBase.AmountByUnit)
                                {
                                    amtPerUnit += basisCode.AmtPerUnitValue;
                                }
                                else
                                {
                                    taxCodeValue += basisCode.TaxValue;
                                }
                                break;

                            default:
                                NetTracer.Error("CalculateTaxAmountsIndia(): Multiplication and division not currently supported in AX. tokens[{0}]: {1}", index - 1, tokens[index - 1]);
                                Debug.Fail("Multiplication and division not currently supported in AX");

                                break;
                            }
                        }
                    }
                }
            }



            taxValueLoc = codeIndia.Value;

            if (codeIndia.TaxBase == TaxBase.AmountByUnit)
            {
                taxVal        = decimal.Zero;
                amtPerUnitVal = taxValueLoc;
            }
            else
            {
                if (codeIndia.Formula.TaxableBasis != TaxableBases.ExclAmount)
                {
                    taxVal = ((1 + taxCodeValue) * taxValueLoc) / 100;
                }
                else
                {
                    taxVal = (taxCodeValue * taxValueLoc) / 100;
                }

                taxVal       *= (100 - codeIndia.AbatementPercent) / 100;
                amtPerUnitVal = amtPerUnit * taxValueLoc / 100;
            }
        }