/// <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> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the calculated tax rate. A value indicating whether a request is taxable /// </returns> protected virtual async Task <(decimal taxRate, bool isTaxable)> GetTaxRateAsync(Product product, int taxCategoryId, Customer customer, decimal price) { var taxRate = decimal.Zero; //active tax provider var store = await _storeContext.GetCurrentStoreAsync(); var activeTaxProvider = await _taxPluginManager.LoadPrimaryPluginAsync(customer, store.Id); if (activeTaxProvider == null) { return(taxRate, true); } //tax request var taxRateRequest = await PrepareTaxRateRequestAsync(product, taxCategoryId, customer, price); var isTaxable = !await IsTaxExemptAsync(product, taxRateRequest.Customer); //tax exempt //make EU VAT exempt validation (the European Union Value Added Tax) if (isTaxable && _taxSettings.EuVatEnabled && await IsVatExemptAsync(taxRateRequest.Address, taxRateRequest.Customer)) { //VAT is not chargeable isTaxable = false; } //get tax rate var taxRateResult = await activeTaxProvider.GetTaxRateAsync(taxRateRequest); //tax rate is calculated, now consumers can adjust it await _eventPublisher.PublishAsync(new TaxRateCalculatedEvent(taxRateResult)); if (taxRateResult.Success) { //ensure that tax is equal or greater than zero if (taxRateResult.TaxRate < decimal.Zero) { taxRateResult.TaxRate = decimal.Zero; } taxRate = taxRateResult.TaxRate; } else if (_taxSettings.LogErrors) { foreach (var error in taxRateResult.Errors) { await _logger.ErrorAsync($"{activeTaxProvider.PluginDescriptor.FriendlyName} - {error}", null, customer); } } return(taxRate, isTaxable); }
public async Task CanLoadActiveTaxProvider() { var provider = await _taxPluginManager.LoadPrimaryPluginAsync(); provider.Should().NotBeNull(); }