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;
                }
            }
        }
Esempio n. 2
0
        private void TaxItems(List <ITaxable> items, IAddress billingAddress, IAddress shippingAddress, decimal totalOrderDiscounts, string userId)
        {
            var     applyVATRules = _app.CurrentStore.Settings.ApplyVATRules;
            decimal discount      = 0;
            decimal qty           = 0;

            if (totalOrderDiscounts != 0)
            {
                foreach (var i in items)
                {
                    if (i.IsTaxExempt == false && i.TaxSchedule != -1)
                    {
                        if (_app.OrderServices.TaxSchedules.FindForThisStore(i.TaxSchedule) != null)
                        {
                            qty += i.Quantity;
                        }
                    }
                }

                if (qty != 0)
                {
                    discount = totalOrderDiscounts / qty;
                }
            }

            foreach (var item in items)
            {
                if (item.IsTaxExempt)
                {
                    continue;
                }

                ITaxSchedule schedule = _app.OrderServices.TaxSchedules.FindForThisStore(item.TaxSchedule);

                if (schedule == null)
                {
                    continue;
                }

                //Get best match by address
                var taxationAddress = item.IsNonShipping ? billingAddress : shippingAddress;
                var tax             = _app.OrderServices.Taxes.FindByAdress(_app.CurrentStore.Id, schedule.TaxScheduleId(),
                                                                            taxationAddress);

                var     defaultRate         = schedule.TaxScheduleDefaultRate() / 100;
                var     defaultShippingRate = schedule.TaxScheduleDefaultShippingRate() / 100;
                decimal rate         = 0;
                decimal shippingRate = 0;

                if (applyVATRules)
                {
                    rate         = defaultRate;
                    shippingRate = defaultShippingRate;
                }

                if (tax != null)
                {
                    var user          = _app.MembershipServices.Customers.Find(userId);
                    var taxExemptUser = user != null ? user.TaxExempt : false;

                    if (!taxExemptUser)
                    {
                        rate = tax.Rate / 100;

                        if (tax.ApplyToShipping)
                        {
                            shippingRate = tax.ShippingRate / 100;
                        }
                    }
                }

                item.SetTaxRate(rate);

                item.SetShippingTaxRate(shippingRate);
                var lineItemTotalDiscount = item.Quantity * discount;

                if (tax != null)
                {
                    if (applyVATRules)
                    {
                        if (rate != defaultRate)
                        {
                            //Subtract included tax
                            var lineTotal    = item.LineTotal;
                            var lineTotalVAT = Money.RoundCurrency(lineTotal - lineTotal / (1 + defaultRate));

                            item.LineTotal = lineTotal - lineTotalVAT;

                            //Add new tax value
                            item.TaxPortion = Money.RoundCurrency(item.LineTotal * rate);

                            item.LineTotal += item.TaxPortion;
                        }
                        else
                        {
                            var lineTotal = item.LineTotal;

                            item.TaxPortion = Money.RoundCurrency(lineTotal - lineTotal / (1 + rate));
                        }

                        if (shippingRate != defaultShippingRate)
                        {
                            //Subtract tax from shipping portion always since rates may differ
                            var shippingPortion    = item.ShippingPortion;
                            var shippingPortionVAT =
                                Money.RoundCurrency(shippingPortion - shippingPortion / (1 + defaultShippingRate));

                            item.ShippingPortion = shippingPortion - shippingPortionVAT;

                            item.ShippingTaxPortion = Money.RoundCurrency(item.ShippingPortion * shippingRate);

                            item.ShippingPortion += item.ShippingTaxPortion;
                        }
                        else
                        {
                            var shippingPortion = item.ShippingPortion;

                            item.ShippingTaxPortion =
                                Money.RoundCurrency(shippingPortion - shippingPortion / (1 + shippingRate));
                        }
                    }
                    else
                    {
                        var lineTotalTax = Money.RoundCurrency((item.LineTotal + lineItemTotalDiscount) * rate);

                        item.TaxPortion = lineTotalTax;

                        var shippingPortionTax = Money.RoundCurrency(item.ShippingPortion * shippingRate);

                        item.ShippingTaxPortion = shippingPortionTax;
                    }
                }

                item.AdjustedPricePerItem = Money.RoundCurrency(item.LineTotal / item.Quantity);
            }
        }
Esempio n. 3
0
        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;
                }
            }
        }