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 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); } }
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; } } }