示例#1
0
        public CalculateTaxResult GetTaxRate(CalculateTaxRequest calculateTaxRequest)
        {
            var result = new CalculateTaxResult();

            if (calculateTaxRequest.Address == null)
            {
                result.Errors.Add("Address is not set");
                return(result);
            }

            if (_taxSettings.EuVatEnabled)
            {
                if (!(calculateTaxRequest.Address.Country?.SubjectToVat ?? false))
                {
                    // Fallback to fixed rate (merchant country VAT rate).
                    result.TaxRate = _settingService.GetSettingByKey <decimal>($"Tax.TaxProvider.FixedRate.TaxCategoryId{calculateTaxRequest.TaxCategoryId}");
                    return(result);
                }
            }

            var taxRates = _taxRateService.GetAllTaxRates(
                calculateTaxRequest.TaxCategoryId,
                calculateTaxRequest.Address.Country?.Id ?? 0,
                calculateTaxRequest.Address.StateProvince?.Id ?? 0,
                calculateTaxRequest.Address.ZipPostalCode);

            if (taxRates.Any())
            {
                result.TaxRate = taxRates[0].Percentage;
            }

            return(result);
        }
        private void PrepareModel(ByRegionTaxRateListModel model)
        {
            var taxCategories  = _taxCategoryService.GetAllTaxCategories().ToDictionary(x => x.Id);
            var taxRates       = _taxRateService.GetAllTaxRates();
            var countries      = _countryService.GetAllCountries(true).ToDictionary(x => x.Id);
            var stateProvinces = _stateProvinceService.GetAllStateProvinces(true).ToDictionary(x => x.Id);
            var stateProvincesOfFirstCountry = stateProvinces.Values.Where(x => x.CountryId == countries.Values.FirstOrDefault().Id).ToList();
            var unavailable = T("Common.Unavailable").Text;

            model.AvailableTaxCategories = taxCategories.Values.Select(x => new SelectListItem
            {
                Text  = x.Name,
                Value = x.Id.ToString()
            })
                                           .ToList();

            model.AvailableCountries = countries.Values.Select(x => new SelectListItem
            {
                Text  = x.Name,
                Value = x.Id.ToString()
            })
                                       .ToList();

            model.AvailableStates = stateProvincesOfFirstCountry.Select(x => new SelectListItem
            {
                Text  = x.Name,
                Value = x.Id.ToString()
            })
                                    .ToList();
            model.AvailableStates.Insert(0, new SelectListItem {
                Text = "*", Value = "0"
            });

            model.TaxRates = taxRates.Select(x =>
            {
                var m = new ByRegionTaxRateModel
                {
                    Id              = x.Id,
                    TaxCategoryId   = x.TaxCategoryId,
                    CountryId       = x.CountryId,
                    StateProvinceId = x.StateProvinceId,
                    Zip             = x.Zip.HasValue() ? x.Zip : "*",
                    Percentage      = x.Percentage
                };

                taxCategories.TryGetValue(x.TaxCategoryId, out TaxCategory tc);
                m.TaxCategoryName = tc?.Name.EmptyNull();

                countries.TryGetValue(x.CountryId, out Country c);
                m.CountryName = c?.Name ?? unavailable;

                stateProvinces.TryGetValue(x.StateProvinceId, out StateProvince s);
                m.StateProvinceName = s?.Name ?? "*";

                return(m);
            })
                             .ToList();
        }
        public async Task <IActionResult> RatesList(DataSourceRequest command)
        {
            if (!await _permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings))
            {
                return(Content("Access denied"));
            }

            var records = await _taxRateService.GetAllTaxRates(command.Page - 1, command.PageSize);

            var taxRatesModel = new List <TaxRateModel>();

            foreach (var x in records)
            {
                var m = new TaxRateModel
                {
                    Id              = x.Id,
                    StoreId         = x.StoreId,
                    TaxCategoryId   = x.TaxCategoryId,
                    CountryId       = x.CountryId,
                    StateProvinceId = x.StateProvinceId,
                    Zip             = x.Zip,
                    Percentage      = x.Percentage,
                };
                //store
                var store = await _storeService.GetStoreById(x.StoreId);

                m.StoreName = (store != null) ? store.Name : "*";
                //tax category
                var tc = await _taxCategoryService.GetTaxCategoryById(x.TaxCategoryId);

                m.TaxCategoryName = (tc != null) ? tc.Name : "";
                //country
                var c = await _countryService.GetCountryById(x.CountryId);

                m.CountryName = (c != null) ? c.Name : "Unavailable";
                //state
                var s = await _stateProvinceService.GetStateProvinceById(x.StateProvinceId);

                m.StateProvinceName = (s != null) ? s.Name : "*";
                //zip
                m.Zip = (!String.IsNullOrEmpty(x.Zip)) ? x.Zip : "*";
                taxRatesModel.Add(m);
            }

            var gridModel = new DataSourceResult
            {
                Data  = taxRatesModel,
                Total = records.TotalCount
            };

            return(Json(gridModel));
        }
示例#4
0
        /// <summary>
        /// Gets tax rate
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="taxCategoryId">Tax category identifier</param>
        /// <param name="customer">Customer</param>
        /// <param name="price">Price (taxable value)</param>
        /// <param name="taxRate">Calculated tax rate</param>
        /// <param name="isTaxable">A value indicating whether a request is taxable</param>
        protected virtual void GetTaxRate(Product product, int taxCategoryId, Customer customer, decimal price, out decimal taxRate, out bool isTaxable)
        {
            taxRate   = decimal.Zero;
            isTaxable = true;

            //tax provider
            var taxProvider = _taxRateService.GetAllTaxRates();

            if (taxProvider == null)
            {
                return;
            }

            //tax request
            var calculateTaxRequest = CreateCalculateTaxRequest(product, taxCategoryId, customer, price);

            //tax exempt
            if (IsTaxExempt(product, calculateTaxRequest.Customer))
            {
                isTaxable = false;
            }
            //make EU VAT exempt validation (the European Union Value Added Tax)
            if (isTaxable &&
                _taxSettings.EuVatEnabled &&
                IsVatExempt(calculateTaxRequest.Address, calculateTaxRequest.Customer))
            {
                //VAT is not chargeable
                isTaxable = false;
            }

            //get tax rate
            var calculateTaxResult = _taxRateService.GetTaxRate(calculateTaxRequest);

            if (calculateTaxResult.Success)
            {
                //ensure that tax is equal or greater than zero
                if (calculateTaxResult.TaxRate < decimal.Zero)
                {
                    calculateTaxResult.TaxRate = decimal.Zero;
                }

                taxRate = calculateTaxResult.TaxRate;
            }
            else
            if (_taxSettings.LogErrors)
            {
                foreach (var error in calculateTaxResult.Errors)
                {
                    _logger.Error(string.Format("{0} - {1}", "CountryStateZipTaxRate", error), null, customer);
                }
            }
        }
示例#5
0
        public ActionResult RatesList(GridCommand command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageTaxSettings))
            {
                return(Content("Access denied"));
            }

            var records       = _taxRateService.GetAllTaxRates(command.Page - 1, command.PageSize);
            var taxRatesModel = records
                                .Select(x =>
            {
                var m = new TaxRateModel()
                {
                    Id              = x.Id,
                    StoreId         = x.StoreId,
                    TaxCategoryId   = x.TaxCategoryId,
                    CountryId       = x.CountryId,
                    StateProvinceId = x.StateProvinceId,
                    Zip             = x.Zip,
                    Percentage      = x.Percentage,
                };
                //store
                var store   = _storeService.GetStoreById(x.StoreId);
                m.StoreName = (store != null) ? store.Name : "*";
                //tax category
                var tc            = _taxCategoryService.GetTaxCategoryById(x.TaxCategoryId);
                m.TaxCategoryName = (tc != null) ? tc.Name : "";
                //country
                var c         = _countryService.GetCountryById(x.CountryId);
                m.CountryName = (c != null) ? c.Name : "Unavailable";
                //state
                var s = _stateProvinceService.GetStateProvinceById(x.StateProvinceId);
                m.StateProvinceName = (s != null) ? s.Name : "*";
                //zip
                m.Zip = (!String.IsNullOrEmpty(x.Zip)) ? x.Zip : "*";
                return(m);
            })
                                .ToList();
            var model = new GridModel <TaxRateModel>
            {
                Data  = taxRatesModel,
                Total = records.TotalCount
            };

            return(new JsonResult
            {
                Data = model
            });
        }
示例#6
0
        //tax category
        public void HandleEvent(EntityDeleted <TaxCategory> eventMessage)
        {
            if (eventMessage.Entity == null)
            {
                return;
            }

            //delete an appropriate record when tax category is deleted
            var recordsToDelete = _taxRateService.GetAllTaxRates().Where(tr => tr.TaxCategoryId == eventMessage.Entity.Id).ToList();

            foreach (var taxRate in recordsToDelete)
            {
                _taxRateService.DeleteTaxRate(taxRate);
            }
        }
        public async Task <IActionResult> RatesList(DataSourceRequest command)
        {
            var records = await _taxRateService.GetAllTaxRates(command.Page - 1, command.PageSize);

            var taxRatesModel = new List <TaxRateModel>();

            foreach (var x in records)
            {
                var m = new TaxRateModel
                {
                    Id              = x.Id,
                    StoreId         = x.StoreId,
                    TaxCategoryId   = x.TaxCategoryId,
                    CountryId       = x.CountryId,
                    StateProvinceId = x.StateProvinceId,
                    Zip             = x.Zip,
                    Percentage      = x.Percentage,
                };
                //store
                var store = await _storeService.GetStoreById(x.StoreId);

                m.StoreName = (store != null) ? store.Shortcut : "*";
                //tax category
                var tc = await _taxCategoryService.GetTaxCategoryById(x.TaxCategoryId);

                m.TaxCategoryName = (tc != null) ? tc.Name : "";
                //country
                var c = await _countryService.GetCountryById(x.CountryId);

                m.CountryName = (c != null) ? c.Name : "Unavailable";
                //state
                var s = c?.StateProvinces.FirstOrDefault(z => z.Id == x.StateProvinceId);
                m.StateProvinceName = (s != null) ? s.Name : "*";
                //zip
                m.Zip = (!String.IsNullOrEmpty(x.Zip)) ? x.Zip : "*";
                taxRatesModel.Add(m);
            }

            var gridModel = new DataSourceResult
            {
                Data  = taxRatesModel,
                Total = records.TotalCount
            };

            return(Json(gridModel));
        }
示例#8
0
        /// <summary>
        /// Gets tax rate
        /// </summary>
        /// <param name="calculateTaxRequest">Tax calculation request</param>
        /// <returns>Tax</returns>
        public CalculateTaxResult GetTaxRate(CalculateTaxRequest calculateTaxRequest)
        {
            var result = new CalculateTaxResult();

            if (calculateTaxRequest.Address == null)
            {
                result.Errors.Add("Address is not set");
                return(result);
            }

            var taxRates = _taxRateService.GetAllTaxRates(calculateTaxRequest.TaxCategoryId,
                                                          calculateTaxRequest.Address.Country != null ? calculateTaxRequest.Address.Country.Id: 0,
                                                          calculateTaxRequest.Address.StateProvince != null ? calculateTaxRequest.Address.StateProvince.Id : 0,
                                                          calculateTaxRequest.Address.ZipPostalCode);

            if (taxRates.Count > 0)
            {
                result.TaxRate = taxRates[0].Percentage;
            }

            return(result);
        }
        public ActionResult RatesList(GridCommand command)
        {
            var records       = _taxRateService.GetAllTaxRates(command.Page - 1, command.PageSize);
            var taxRatesModel = records
                                .Select(x =>
            {
                var m = new TaxRateModel()
                {
                    Id              = x.Id,
                    TaxCategoryId   = x.TaxCategoryId,
                    CountryId       = x.CountryId,
                    StateProvinceId = x.StateProvinceId,
                    Zip             = x.Zip,
                    Percentage      = x.Percentage,
                };
                var tc              = _taxCategoryService.GetTaxCategoryById(x.TaxCategoryId);
                m.TaxCategoryName   = (tc != null) ? tc.Name : "";
                var c               = _countryService.GetCountryById(x.CountryId);
                m.CountryName       = (c != null) ? c.Name : "Unavailable";
                var s               = _stateProvinceService.GetStateProvinceById(x.StateProvinceId);
                m.StateProvinceName = (s != null) ? s.Name : "*";
                m.Zip               = (!String.IsNullOrEmpty(x.Zip)) ? x.Zip : "*";
                return(m);
            })
                                .ToList();
            var model = new GridModel <TaxRateModel>
            {
                Data  = taxRatesModel,
                Total = records.TotalCount
            };

            return(new JsonResult
            {
                Data = model
            });
        }
示例#10
0
        public ActionResult Configure()
        {
            var taxCategories = _taxCategoryService.GetAllTaxCategories();

            if (taxCategories.Count == 0)
            {
                return(Content("No tax categories can be loaded"));
            }

            var model = new TaxRateListModel();

            foreach (var tc in taxCategories)
            {
                model.AvailableTaxCategories.Add(new SelectListItem()
                {
                    Text = tc.Name, Value = tc.Id.ToString()
                });
            }
            var countries = _countryService.GetAllCountries(true);

            foreach (var c in countries)
            {
                model.AvailableCountries.Add(new SelectListItem()
                {
                    Text = c.Name, Value = c.Id.ToString()
                });
            }
            model.AvailableStates.Add(new SelectListItem()
            {
                Text = "*", Value = "0"
            });
            var states = _stateProvinceService.GetStateProvincesByCountryId(countries.FirstOrDefault().Id);

            if (states.Count > 0)
            {
                foreach (var s in states)
                {
                    model.AvailableStates.Add(new SelectListItem()
                    {
                        Text = s.Name, Value = s.Id.ToString()
                    });
                }
            }

            model.TaxRates = _taxRateService.GetAllTaxRates()
                             .Select(x =>
            {
                var m = new TaxRateModel()
                {
                    Id              = x.Id,
                    TaxCategoryId   = x.TaxCategoryId,
                    CountryId       = x.CountryId,
                    StateProvinceId = x.StateProvinceId,
                    Zip             = x.Zip,
                    Percentage      = x.Percentage,
                };
                var tc              = _taxCategoryService.GetTaxCategoryById(x.TaxCategoryId);
                m.TaxCategoryName   = (tc != null) ? tc.Name : "";
                var c               = _countryService.GetCountryById(x.CountryId);
                m.CountryName       = (c != null) ? c.Name : "Unavailable";
                var s               = _stateProvinceService.GetStateProvinceById(x.StateProvinceId);
                m.StateProvinceName = (s != null) ? s.Name : "*";
                m.Zip               = (!String.IsNullOrEmpty(x.Zip)) ? x.Zip : "*";
                return(m);
            })
                             .ToList();

            return(View("SmartStore.Plugin.Tax.CountryStateZip.Views.TaxCountryStateZip.Configure", model));
        }
        /// <summary>
        /// Gets tax rate
        /// </summary>
        /// <param name="calculateTaxRequest">Tax calculation request</param>
        /// <returns>Tax</returns>
        public async Task <CalculateTaxResult> GetTaxRate(CalculateTaxRequest calculateTaxRequest)
        {
            var result = new CalculateTaxResult();

            if (calculateTaxRequest.Address == null)
            {
                result.Errors.Add("Address is not set");
                return(result);
            }

            const string cacheKey    = ModelCacheEventConsumer.ALL_TAX_RATES_MODEL_KEY;
            var          allTaxRates = await _cacheManager.GetAsync(cacheKey, async() =>
            {
                var taxes = await _taxRateService.GetAllTaxRates();
                return(taxes.Select(x => new TaxRateForCaching
                {
                    Id = x.Id,
                    StoreId = x.StoreId,
                    TaxCategoryId = x.TaxCategoryId,
                    CountryId = x.CountryId,
                    StateProvinceId = x.StateProvinceId,
                    Zip = x.Zip,
                    Percentage = x.Percentage
                }));
            });

            var storeId         = _storeContext.CurrentStore.Id;
            var taxCategoryId   = calculateTaxRequest.TaxCategoryId;
            var countryId       = calculateTaxRequest.Address.CountryId;
            var stateProvinceId = calculateTaxRequest.Address.StateProvinceId;
            var zip             = calculateTaxRequest.Address.ZipPostalCode;

            if (zip == null)
            {
                zip = string.Empty;
            }
            zip = zip.Trim();

            var existingRates = allTaxRates.Where(taxRate => taxRate.CountryId == countryId && taxRate.TaxCategoryId == taxCategoryId).ToList();

            //filter by store
            var matchedByStore = existingRates.Where(taxRate => storeId == taxRate.StoreId).ToList();

            //not found? use the default ones (ID == 0)
            if (!matchedByStore.Any())
            {
                matchedByStore.AddRange(existingRates.Where(taxRate => string.IsNullOrEmpty(taxRate.StoreId)));
            }

            //filter by state/province
            var matchedByStateProvince = matchedByStore.Where(taxRate => stateProvinceId == taxRate.StateProvinceId).ToList();

            //not found? use the default ones (ID == 0)
            if (!matchedByStateProvince.Any())
            {
                matchedByStateProvince.AddRange(matchedByStore.Where(taxRate => string.IsNullOrEmpty(taxRate.StateProvinceId)));
            }

            //filter by zip
            var matchedByZip = matchedByStateProvince.Where(taxRate => (string.IsNullOrEmpty(zip) && string.IsNullOrEmpty(taxRate.Zip)) || zip.Equals(taxRate.Zip, StringComparison.OrdinalIgnoreCase)).ToList();

            if (!matchedByZip.Any())
            {
                matchedByZip.AddRange(matchedByStateProvince.Where(taxRate => string.IsNullOrWhiteSpace(taxRate.Zip)));
            }

            if (matchedByZip.Any())
            {
                result.TaxRate = matchedByZip[0].Percentage;
            }

            return(result);
        }
示例#12
0
        /// <summary>
        /// Gets tax rate
        /// </summary>
        /// <param name="calculateTaxRequest">Tax calculation request</param>
        /// <returns>Tax</returns>
        public CalculateTaxResult GetTaxRate(CalculateTaxRequest calculateTaxRequest)
        {
            var result = new CalculateTaxResult();

            if (calculateTaxRequest.Address == null)
            {
                result.Errors.Add("Address is not set");
                return(result);
            }

            //first, load all tax rate records (cached) - loaded only once
            string cacheKey    = ModelCacheEventConsumer.ALL_TAX_RATES_MODEL_KEY;
            var    allTaxRates = _cacheManager.Get(cacheKey, () =>
                                                   _taxRateService
                                                   .GetAllTaxRates()
                                                   .Select(x => new TaxRateForCaching
            {
                Id              = x.Id,
                StoreId         = x.StoreId,
                TaxCategoryId   = x.TaxCategoryId,
                CountryId       = x.CountryId,
                StateProvinceId = x.StateProvinceId,
                Zip             = x.Zip,
                Percentage      = x.Percentage,
            }
                                                           )
                                                   .ToList()
                                                   );

            string storeId         = _storeContext.CurrentStore.Id;
            string taxCategoryId   = calculateTaxRequest.TaxCategoryId;
            string countryId       = calculateTaxRequest.Address.CountryId;
            string stateProvinceId = calculateTaxRequest.Address.StateProvinceId;
            string zip             = calculateTaxRequest.Address.ZipPostalCode;


            if (zip == null)
            {
                zip = string.Empty;
            }
            zip = zip.Trim();

            var existingRates = new List <TaxRateForCaching>();

            foreach (var taxRate in allTaxRates)
            {
                if (taxRate.CountryId == countryId && taxRate.TaxCategoryId == taxCategoryId)
                {
                    existingRates.Add(taxRate);
                }
            }

            //filter by store
            var matchedByStore = new List <TaxRateForCaching>();

            //first, find by a store ID
            foreach (var taxRate in existingRates)
            {
                if (storeId == taxRate.StoreId)
                {
                    matchedByStore.Add(taxRate);
                }
            }
            //not found? use the default ones (ID == 0)
            if (matchedByStore.Count == 0)
            {
                foreach (var taxRate in existingRates)
                {
                    if (!String.IsNullOrEmpty(taxRate.StoreId))
                    {
                        matchedByStore.Add(taxRate);
                    }
                }
            }


            //filter by state/province
            var matchedByStateProvince = new List <TaxRateForCaching>();

            //first, find by a state ID
            foreach (var taxRate in matchedByStore)
            {
                if (stateProvinceId == taxRate.StateProvinceId)
                {
                    matchedByStateProvince.Add(taxRate);
                }
            }
            //not found? use the default ones (ID == 0)
            if (matchedByStateProvince.Count == 0)
            {
                foreach (var taxRate in matchedByStore)
                {
                    if (String.IsNullOrEmpty(taxRate.StateProvinceId))
                    {
                        matchedByStateProvince.Add(taxRate);
                    }
                }
            }


            //filter by zip
            var matchedByZip = new List <TaxRateForCaching>();

            foreach (var taxRate in matchedByStateProvince)
            {
                if ((String.IsNullOrEmpty(zip) && String.IsNullOrEmpty(taxRate.Zip)) ||
                    (zip.Equals(taxRate.Zip, StringComparison.InvariantCultureIgnoreCase)))
                {
                    matchedByZip.Add(taxRate);
                }
            }
            if (matchedByZip.Count == 0)
            {
                foreach (var taxRate in matchedByStateProvince)
                {
                    if (String.IsNullOrWhiteSpace(taxRate.Zip))
                    {
                        matchedByZip.Add(taxRate);
                    }
                }
            }

            if (matchedByZip.Count > 0)
            {
                result.TaxRate = matchedByZip[0].Percentage;
            }

            return(result);
        }