Example #1
0
        public void Valid_evaluation_context_successfull_tax_calculation()
        {
            //arrange
            var logService = new Mock <ILogger <AvaTaxRateProvider> >();
            var options    = new Mock <IOptions <AvaTaxSecureOptions> >();

            options.Setup(x => x.Value).Returns(Options);

            var avaTaxRateProvider = new AvaTaxRateProvider(logService.Object, CreateAvaTaxClient, options.Object);

            avaTaxRateProvider.Settings = Settings;

            var context = new TaxEvaluationContext
            {
                Address  = GetValidAddress(),
                Customer = new Customer()
                {
                    Id = Guid.NewGuid().ToString()
                },
                Lines    = GetContextTaxLines(),
                Currency = "USD",
                Id       = Guid.NewGuid().ToString()
            };

            //act
            var rates = avaTaxRateProvider.CalculateRates(context);

            //assert
            Assert.NotEmpty(rates);
        }
Example #2
0
        public virtual AvaCreateTransactionModel FromContext(TaxEvaluationContext context, string requiredCompanyCode)
        {
            code = context.Id;
            // TODO: customerCode is required by AvaTax API, but using stub values when the customer is not specified doesn't seem right...
            customerCode = context.Customer?.Id ?? Thread.CurrentPrincipal?.Identity?.Name ?? "undef";
            companyCode  = requiredCompanyCode;
            date         = DateTime.UtcNow;
            type         = DocumentType.SalesOrder;
            currencyCode = context.Currency;
            if (context.Lines != null)
            {
                lines = new List <LineItemModel>();
                foreach (var taxLine in context.Lines.Where(x => !x.IsTransient()))
                {
                    var avaLine = AbstractTypeFactory <AvaLineItem> .TryCreateInstance();

                    avaLine.FromTaxLine(taxLine);
                    lines.Add(avaLine);
                }
            }
            if (context.Address != null)
            {
                var avaAddress = AbstractTypeFactory <AvaAddressLocationInfo> .TryCreateInstance();

                avaAddress.FromAddress(context.Address);
                addresses = new AddressesModel
                {
                    // TODO: set actual origin address (fulfillment center/store owner)?
                    shipFrom = avaAddress,
                    shipTo   = avaAddress
                };
            }

            return(this);
        }
        public virtual coreDto.TaxEvaluationContext ToTaxEvaluationContextDto(TaxEvaluationContext taxContext)
        {
            var retVal = new coreDto.TaxEvaluationContext();

            retVal.InjectFrom <NullableAndEnumValueInjecter>(taxContext);
            if (taxContext.Address != null)
            {
                retVal.Address = taxContext.Address.ToCoreAddressDto();
            }
            if (taxContext.Customer != null)
            {
                retVal.Customer            = taxContext.Customer.ToCoreContactDto();
                retVal.Customer.MemberType = "Contact";
            }
            if (taxContext.Currency != null)
            {
                retVal.Currency = taxContext.Currency.Code;
            }

            retVal.Lines = new List <coreDto.TaxLine>();
            if (!taxContext.Lines.IsNullOrEmpty())
            {
                foreach (var line in taxContext.Lines)
                {
                    var serviceModelLine = new coreDto.TaxLine();
                    serviceModelLine.InjectFrom <NullableAndEnumValueInjecter>(line);
                    serviceModelLine.Amount = (double)line.Amount.Amount;
                    serviceModelLine.Price  = (double)line.Price.Amount;

                    retVal.Lines.Add(serviceModelLine);
                }
            }
            return(retVal);
        }
        public static TaxEvaluationContext ToTaxEvalContext(this ShoppingCart cart, Store store)
        {
            var result = new TaxEvaluationContext(cart.StoreId)
            {
                Id       = cart.Id,
                Code     = cart.Name,
                Currency = cart.Currency,
                Type     = "Cart",
                Customer = cart.Customer,
                StoreTaxCalculationEnabled = store.TaxCalculationEnabled,
                FixedTaxRate = store.FixedTaxRate
            };

            foreach (var lineItem in cart.Items)
            {
                result.Lines.Add(new TaxLine(lineItem.Currency)
                {
                    Id      = lineItem.Id,
                    Code    = lineItem.Sku,
                    Name    = lineItem.Name,
                    TaxType = lineItem.TaxType,
                    //Special case when product have 100% discount and need to calculate tax for old value
                    Amount = lineItem.ExtendedPrice.Amount > 0 ? lineItem.ExtendedPrice : lineItem.SalePrice
                });
            }

            foreach (var shipment in cart.Shipments)
            {
                var totalTaxLine = new TaxLine(shipment.Currency)
                {
                    Id      = shipment.Id,
                    Code    = shipment.ShipmentMethodCode,
                    Name    = shipment.ShipmentMethodOption,
                    TaxType = shipment.TaxType,
                    //Special case when shipment have 100% discount and need to calculate tax for old value
                    Amount = shipment.Total.Amount > 0 ? shipment.Total : shipment.Price
                };
                result.Lines.Add(totalTaxLine);

                if (shipment.DeliveryAddress != null)
                {
                    result.Address = shipment.DeliveryAddress;
                }
            }

            foreach (var payment in cart.Payments)
            {
                var totalTaxLine = new TaxLine(payment.Currency)
                {
                    Id      = payment.Id,
                    Code    = payment.PaymentGatewayCode,
                    Name    = payment.PaymentGatewayCode,
                    TaxType = payment.TaxType,
                    //Special case when shipment have 100% discount and need to calculate tax for old value
                    Amount = payment.Total.Amount > 0 ? payment.Total : payment.Price
                };
                result.Lines.Add(totalTaxLine);
            }
            return(result);
        }
        public void Valid_evaluation_context_successfull_tax_calcualtion()
        {
            //arrange
            var memberService = new Mock <IMemberService>();

            memberService.Setup(s => s.GetByIds(It.IsAny <string[]>(), It.IsAny <string[]>())).Returns <string[], string[]>((ids, types) => {
                return(new[] { new Contact() });
            });

            var logService = new Mock <ILog>();

            var avaTaxRateProvider = new AvaTaxRateProvider(memberService.Object, logService.Object, _settings.ToArray());

            var context = new TaxEvaluationContext
            {
                Address  = GetValidAddress(),
                Customer = new Contact {
                    Id = Guid.NewGuid().ToString()
                },
                Lines    = GetContextTaxLines(),
                Currency = "USD",
                Id       = Guid.NewGuid().ToString(),
            };


            //act
            var rates = avaTaxRateProvider.CalculateRates(context);

            //assert
            Assert.NotEmpty(rates);
        }
        public static coreDto.TaxEvaluationContext ToTaxEvaluationContextDto(this TaxEvaluationContext taxContext)
        {
            var retVal = new coreDto.TaxEvaluationContext();

            retVal.Code = taxContext.Code;
            retVal.Id   = taxContext.Id;
            retVal.Type = taxContext.Type;

            if (taxContext.Address != null)
            {
                retVal.Address = taxContext.Address.ToCoreAddressDto();
            }

            retVal.Customer = taxContext?.Customer?.Contact?.ToCoreContactDto();
            if (retVal.Customer != null)
            {
                retVal.Customer.MemberType = "Contact";
            }

            if (taxContext.Currency != null)
            {
                retVal.Currency = taxContext.Currency.Code;
            }

            retVal.Lines = new List <coreDto.TaxLine>();
            if (!taxContext.Lines.IsNullOrEmpty())
            {
                retVal.Lines = taxContext.Lines.Select(x => x.ToTaxLineDto()).ToList();
            }
            return(retVal);
        }
        public virtual void EvaluateTaxes(TaxEvaluationContext context, IEnumerable <ITaxable> owners)
        {
            IList <coreService.TaxRate> taxRates = new List <coreService.TaxRate>();

            if (context.StoreTaxCalculationEnabled)
            {
                taxRates = _coreModuleApiClient.Commerce.EvaluateTaxes(context.StoreId, context.ToTaxEvaluationContextDto());
            }
            InnerEvaluateTaxes(taxRates, owners);
        }
Example #8
0
        private List <TaxRate> GetTaxRates(TaxEvaluationContext evalContext)
        {
            List <TaxRate> retVal = new List <TaxRate>();

            LogInvoker <AvalaraLogger.TaxRequestContext> .Execute(log =>
            {
                if (IsEnabled && !string.IsNullOrEmpty(AccountNumber) &&
                    !string.IsNullOrEmpty(LicenseKey) &&
                    !string.IsNullOrEmpty(ServiceUrl) &&
                    !string.IsNullOrEmpty(CompanyCode))
                {
                    var request = evalContext.ToAvaTaxRequest(CompanyCode, false);
                    if (request != null)
                    {
                        log.docCode      = request.DocCode;
                        log.docType      = request.DocType.ToString();
                        log.customerCode = request.CustomerCode;

                        var taxSvc       = new JsonTaxSvc(AccountNumber, LicenseKey, ServiceUrl);
                        var getTaxResult = taxSvc.GetTax(request);

                        if (!getTaxResult.ResultCode.Equals(SeverityLevel.Success))
                        {
                            //if tax calculation failed create exception with provided error info
                            var error = string.Join(Environment.NewLine, getTaxResult.Messages.Select(m => m.Summary));
                            throw new Exception(error);
                        }

                        foreach (var taxLine in getTaxResult.TaxLines ?? Enumerable.Empty <AvaTaxCalcREST.TaxLine>())
                        {
                            var rate = new TaxRate
                            {
                                Rate        = taxLine.Tax,
                                Currency    = evalContext.Currency,
                                TaxProvider = this,
                                Line        = evalContext.Lines.First(l => l.Id == taxLine.LineNo)
                            };
                            retVal.Add(rate);
                        }
                    }
                    else
                    {
                        throw new Exception("Failed to create get tax request");
                    }
                }
                else
                {
                    throw new Exception("Failed to create get tax request");
                }
            })
            .OnError(_logger, AvalaraLogger.EventCodes.TaxCalculationError)
            .OnSuccess(_logger, AvalaraLogger.EventCodes.GetSalesInvoiceRequestTime);

            return(retVal);
        }
Example #9
0
        public virtual TaxEvaluationContext ToTaxEvalContext(ShoppingCart cart)
        {
            var result = new TaxEvaluationContext(cart.StoreId);

            result.Id       = cart.Id;
            result.Code     = cart.Name;
            result.Currency = cart.Currency;
            result.Type     = "Cart";
            result.Customer = cart.Customer;

            foreach (var lineItem in cart.Items)
            {
                result.Lines.Add(new TaxLine(lineItem.Currency)
                {
                    Id      = lineItem.Id,
                    Code    = lineItem.Sku,
                    Name    = lineItem.Name,
                    TaxType = lineItem.TaxType,
                    Amount  = lineItem.ExtendedPrice
                });
            }

            foreach (var shipment in cart.Shipments)
            {
                var totalTaxLine = new TaxLine(shipment.Currency)
                {
                    Id      = shipment.Id,
                    Code    = shipment.ShipmentMethodCode,
                    Name    = shipment.ShipmentMethodOption,
                    TaxType = shipment.TaxType,
                    Amount  = shipment.Total
                };
                result.Lines.Add(totalTaxLine);

                if (shipment.DeliveryAddress != null)
                {
                    result.Address = shipment.DeliveryAddress;
                }
            }

            foreach (var payment in cart.Payments)
            {
                var totalTaxLine = new TaxLine(payment.Currency)
                {
                    Id      = payment.Id,
                    Code    = payment.PaymentGatewayCode,
                    Name    = payment.PaymentGatewayCode,
                    TaxType = payment.TaxType,
                    Amount  = payment.Total
                };
                result.Lines.Add(totalTaxLine);
            }
            return(result);
        }
Example #10
0
        public async Task Run(TaxEvaluationContext parameter, Func <TaxEvaluationContext, Task> next)
        {
            var cartAggregate = await _cartAggregateRepository.GetCartAsync("default", parameter.StoreId, parameter.CustomerId, Language.InvariantLanguage.CultureName, parameter.Currency);

            if (cartAggregate != null)
            {
                _mapper.Map(cartAggregate, parameter);
            }

            await next(parameter);
        }
Example #11
0
        public QuoteRequestTotals CalculateTotals(QuoteRequest quote)
        {
            var retVal        = new QuoteRequestTotals();
            var cartFromQuote = quote.ToCartModel();
            var store         = _storeService.GetById(quote.StoreId);

            if (store != null)
            {
                //Calculate shipment total
                //firts try to get manual amount
                retVal.ShippingTotal = quote.ManualShippingTotal;
                if (retVal.ShippingTotal == 0 && quote.ShipmentMethod != null)
                {
                    //calculate total by using shipment gateways
                    var evalContext = new ShippingEvaluationContext(cartFromQuote);

                    var rate = store.ShippingMethods.Where(x => x.IsActive && x.Code == quote.ShipmentMethod.ShipmentMethodCode)
                               .SelectMany(x => x.CalculateRates(evalContext))
                               .Where(x => quote.ShipmentMethod.OptionName != null ? quote.ShipmentMethod.OptionName == x.OptionName : true)
                               .FirstOrDefault();
                    retVal.ShippingTotal = rate != null ? rate.Rate : 0m;
                }
                //Calculate taxes
                var taxProvider = store.TaxProviders.Where(x => x.IsActive).OrderBy(x => x.Priority).FirstOrDefault();
                if (taxProvider != null)
                {
                    var taxRequest     = quote.ToTaxRequest();
                    var taxEvalContext = new TaxEvaluationContext(taxRequest);
                    retVal.TaxTotal = taxProvider.CalculateRates(taxEvalContext).Select(x => x.Rate).DefaultIfEmpty(0).Sum(x => x);
                }
            }

            //Calculate subtotal
            var items = quote.Items.Where(x => x.SelectedTierPrice != null);

            if (quote.Items != null)
            {
                retVal.OriginalSubTotalExlTax = items.Sum(x => x.SalePrice * x.SelectedTierPrice.Quantity);
                retVal.SubTotalExlTax         = items.Sum(x => x.SelectedTierPrice.Price * x.SelectedTierPrice.Quantity);
                if (quote.ManualSubTotal > 0)
                {
                    retVal.DiscountTotal  = retVal.SubTotalExlTax - quote.ManualSubTotal;
                    retVal.SubTotalExlTax = quote.ManualSubTotal;
                }
                else if (quote.ManualRelDiscountAmount > 0)
                {
                    retVal.DiscountTotal = retVal.SubTotalExlTax * quote.ManualRelDiscountAmount * 0.01m;
                }
            }

            return(retVal);
        }
Example #12
0
        public async Task Run(TaxEvaluationContext parameter, Func <TaxEvaluationContext, Task> next)
        {
            if (!string.IsNullOrEmpty(parameter.CustomerId))
            {
                var member = await _memberIdResolver.ResolveMemberByIdAsync(parameter.CustomerId);

                if (member != null && member is Contact contact)
                {
                    parameter.Customer = _mapper.Map <Customer>(contact);
                }
            }
            await next(parameter);
        }
Example #13
0
        public async Task <ActionResult <TaxRate[]> > EvaluateTaxes(string storeId, [FromBody] TaxEvaluationContext evalContext)
        {
            var result            = new List <TaxRate>();
            var storeTaxProviders = await _taxProviderSearchService.SearchAsync(new TaxProviderSearchCriteria { StoreIds = new[] { storeId } });

            var activeTaxProvider = storeTaxProviders.Results.FirstOrDefault(x => x.IsActive);

            if (activeTaxProvider != null)
            {
                evalContext.StoreId = storeId;
                result.AddRange(activeTaxProvider.CalculateRates(evalContext));
            }
            return(Ok(result));
        }
        public virtual async Task EvaluateTaxesAsync(TaxEvaluationContext context, IEnumerable <ITaxable> owners)
        {
            IList <coreService.TaxRate> taxRates = new List <coreService.TaxRate>();

            if (context.StoreTaxCalculationEnabled)
            {
                var cacheKey = CacheKey.With(GetType(), context.GetCacheKey());

                taxRates = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, (cacheEntry) =>
                {
                    cacheEntry.AddExpirationToken(TaxCacheRegion.CreateChangeToken());
                    return(_commerceApi.EvaluateTaxesAsync(context.StoreId, context.ToTaxEvaluationContextDto()));
                });
            }
            ApplyTaxRates(taxRates, owners);
        }
        public async Task <IActionResult> EvaluateTaxes(string storeId, [FromBody] TaxEvaluationContext evalContext)
        {
            var retVal = new List <TaxRate>();
            var store  = await _storeService.GetByIdAsync(storeId);

            if (store != null)
            {
                var activeTaxProvider = store.TaxProviders.FirstOrDefault(x => x.IsActive);
                if (activeTaxProvider != null)
                {
                    evalContext.StoreId = store.Id;
                    retVal.AddRange(activeTaxProvider.CalculateRates(evalContext));
                }
            }
            return(Ok(retVal));
        }
Example #16
0
        public virtual TaxEvaluationContext ToTaxEvaluationContext(WorkContext workContext, IEnumerable <Product> products = null)
        {
            var result = new TaxEvaluationContext(workContext.CurrentStore.Id);

            result.Id       = workContext.CurrentStore.Id;
            result.Currency = workContext.CurrentCurrency;
            result.Type     = "";
            result.Address  = workContext.CurrentCustomer.DefaultBillingAddress;
            result.Customer = workContext.CurrentCustomer;

            if (products != null)
            {
                result.Lines = products.SelectMany(x => x.ToTaxLines()).ToList();
            }
            return(result);
        }
        protected virtual List <TaxRate> GetTaxRates(TaxEvaluationContext evalContext)
        {
            var retVal = new List <TaxRate>();

            LogInvoker <AvalaraLogger.TaxRequestContext> .Execute(log =>
            {
                var avaSettings = AvaTaxSettings.FromSettings(Settings, _options);
                Validate(avaSettings);

                var companyCode            = avaSettings.CompanyCode;
                var createTransactionModel = AbstractTypeFactory <AvaCreateTransactionModel> .TryCreateInstance();
                createTransactionModel.FromContext(evalContext, companyCode);
                createTransactionModel.commit = false;

                log.docCode      = createTransactionModel.code;
                log.docType      = createTransactionModel.type.ToString();
                log.customerCode = createTransactionModel.customerCode;
                if (createTransactionModel.IsValid)
                {
                    var avaTaxClient = _avaTaxClientFactory(avaSettings);
                    var transaction  = avaTaxClient.CreateTransaction(string.Empty, createTransactionModel);

                    if (!transaction.lines.IsNullOrEmpty())
                    {
                        foreach (var taxLine in transaction.lines)
                        {
                            var rate = new TaxRate
                            {
                                Rate        = taxLine.tax ?? 0.0m,
                                Currency    = evalContext.Currency,
                                TaxProvider = this,
                                Line        = evalContext.Lines.FirstOrDefault(x => x.Id == taxLine.lineNumber)
                            };
                            if (rate.Line != null)
                            {
                                retVal.Add(rate);
                            }
                        }
                    }
                }
            })
            .OnError(_logger, AvalaraLogger.EventCodes.TaxCalculationError)
            .OnSuccess(_logger, AvalaraLogger.EventCodes.GetSalesInvoiceRequestTime);

            return(retVal);
        }
Example #18
0
        public static coreDto.TaxEvaluationContext ToTaxEvaluationContextDto(this TaxEvaluationContext taxContext)
        {
            var retVal = new coreDto.TaxEvaluationContext();

            retVal.Code = taxContext.Code;
            retVal.Id   = taxContext.Id;
            retVal.Type = taxContext.Type;

            if (taxContext.Address != null)
            {
                retVal.Address = taxContext.Address.ToCoreAddressDto();
            }

            retVal.Customer = taxContext?.Customer?.Contact?.ToCoreContactDto();
            if (retVal.Customer != null)
            {
                retVal.Customer.MemberType = "Contact";
            }

            if (taxContext.Currency != null)
            {
                retVal.Currency = taxContext.Currency.Code;
            }

            retVal.Lines = new List <coreDto.TaxLine>();
            if (!taxContext.Lines.IsNullOrEmpty())
            {
                foreach (var line in taxContext.Lines)
                {
                    var serviceModelLine = new coreDto.TaxLine
                    {
                        Id       = line.Id,
                        Code     = line.Code,
                        Name     = line.Name,
                        Quantity = line.Quantity,
                        TaxType  = line.TaxType,
                        Amount   = (double)line.Amount.Amount,
                        Price    = (double)line.Price.Amount
                    };

                    retVal.Lines.Add(serviceModelLine);
                }
            }
            return(retVal);
        }
Example #19
0
        public static TaxEvaluationContext ToTaxEvaluationContext(this WorkContext workContext, IEnumerable <Product> products = null)
        {
            var result = new TaxEvaluationContext(workContext.CurrentStore.Id);

            result.Id       = workContext.CurrentStore.Id;
            result.Currency = workContext.CurrentCurrency;
            result.Type     = "";

            result.Customer = workContext.CurrentUser;
            result.StoreTaxCalculationEnabled = workContext.CurrentStore.TaxCalculationEnabled;

            result.Address = workContext.CurrentUser?.Contact?.DefaultBillingAddress;

            if (products != null)
            {
                result.Lines = products.SelectMany(x => x.ToTaxLines()).ToList();
            }
            return(result);
        }
Example #20
0
        public async Task Run(SearchProductResponse parameter, Func <SearchProductResponse, Task> next)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

            var query = parameter.Query;

            if (query == null)
            {
                throw new OperationCanceledException("Query must be set");
            }

            var responseGroup = EnumUtility.SafeParse(query.GetResponseGroup(), ExpProductResponseGroup.None);

            // If tax evaluation requested
            if (responseGroup.HasFlag(ExpProductResponseGroup.LoadPrices))
            {
                //Evaluate taxes
                var storeTaxProviders = await _taxProviderSearchService.SearchTaxProvidersAsync(new TaxProviderSearchCriteria { StoreIds = new[] { query.StoreId } });

                var activeTaxProvider = storeTaxProviders.Results.FirstOrDefault(x => x.IsActive);
                if (activeTaxProvider != null)
                {
                    var taxEvalContext = new TaxEvaluationContext {
                        Currency = query.CurrencyCode, StoreId = query.StoreId, CustomerId = query.UserId
                    };

                    await _pipeline.Execute(taxEvalContext);

                    taxEvalContext.Lines = parameter.Results.SelectMany(x => _mapper.Map <IEnumerable <TaxLine> >(x)).ToList();
                    var taxRates = activeTaxProvider.CalculateRates(taxEvalContext);
                    if (taxRates.Any())
                    {
                        parameter.Results.Apply(x => x.AllPrices.Apply(p => p.ApplyTaxRates(taxRates)));
                    }
                }
            }

            await next(parameter);
        }
Example #21
0
 public TaxEvaluationContext ToTaxEvalContext(TaxEvaluationContext target)
 {
     target.Id       = Id;
     target.Code     = Number;
     target.Currency = Currency;
     target.Address  = Addresses?.FirstOrDefault()?.ToTaxModel(AbstractTypeFactory <TaxModule.Core.Model.Address> .TryCreateInstance());
     target.Type     = GetType().Name;
     foreach (var quoteItem in Items)
     {
         var line = new TaxLine
         {
             Id      = quoteItem.Id,
             Code    = quoteItem.Sku,
             Name    = quoteItem.Name,
             TaxType = quoteItem.TaxType,
             Amount  = quoteItem.SelectedTierPrice.Price * quoteItem.SelectedTierPrice.Quantity
         };
         target.Lines.Add(line);
     }
     return(target);
 }
        public virtual async Task EvaluateTaxesAsync(TaxEvaluationContext context, IEnumerable <ITaxable> owners)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (owners == null)
            {
                throw new ArgumentNullException(nameof(owners));
            }
            IList <coreService.TaxRate> taxRates = new List <coreService.TaxRate>();

            if (context.StoreTaxCalculationEnabled)
            {
                //Do not execute platform API for tax evaluation if fixed tax rate is used
                if (context.FixedTaxRate != 0)
                {
                    foreach (var line in context.Lines ?? Enumerable.Empty <TaxLine>())
                    {
                        var rate = new coreService.TaxRate()
                        {
                            Rate     = (double)(line.Amount * context.FixedTaxRate * 0.01m).Amount,
                            Currency = context.Currency.Code,
                            Line     = line.ToTaxLineDto()
                        };
                        taxRates.Add(rate);
                    }
                }
                else
                {
                    var cacheKey = CacheKey.With(GetType(), context.GetCacheKey());
                    taxRates = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, (cacheEntry) =>
                    {
                        cacheEntry.AddExpirationToken(TaxCacheRegion.CreateChangeToken());
                        return(_commerceApi.EvaluateTaxesAsync(context.StoreId, context.ToTaxEvaluationContextDto()));
                    });
                }
            }
            ApplyTaxRates(taxRates, owners);
        }
Example #23
0
        public void EvaluateTaxes(TaxEvaluationContext context, IEnumerable <ITaxable> owners)
        {
            var taxRates = _coreModuleApiClient.Commerce.EvaluateTaxes(context.StoreId, context.ToTaxEvaluationContextDto());

            InnerEvaluateTaxes(taxRates, owners);
        }
Example #24
0
 public virtual void EvaluateTaxes(TaxEvaluationContext context, IEnumerable <ITaxable> owners)
 {
     Task.Factory.StartNew(() => EvaluateTaxesAsync(context, owners), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
 }
Example #25
0
 public static coreDto.TaxEvaluationContext ToTaxEvaluationContextDto(this TaxEvaluationContext taxContext)
 {
     return(TaxConverterInstance.ToTaxEvaluationContextDto(taxContext));
 }
Example #26
0
        private void CalculateCartTotals(CartChangeEvent cartChangeEvent)
        {
            var cart  = cartChangeEvent.ModifiedCart;
            var store = _storeService.GetById(cart.StoreId);

            cart.Total         = 0;
            cart.SubTotal      = 0;
            cart.TaxTotal      = 0;
            cart.ShippingTotal = 0;
            cart.DiscountTotal = 0;

            if (store != null)
            {
                //Calculate taxes
                var taxProvider = store.TaxProviders.Where(x => x.IsActive).OrderBy(x => x.Priority).FirstOrDefault();
                if (taxProvider != null)
                {
                    var taxRequest     = cart.ToTaxRequest();
                    var taxEvalContext = new TaxEvaluationContext(taxRequest);
                    cart.TaxTotal = taxProvider.CalculateRates(taxEvalContext).Select(x => x.Rate).DefaultIfEmpty(0).Sum(x => x);
                }
            }

            if (cart.Items != null)
            {
                foreach (var item in cart.Items)
                {
                    CalculateLineItemTotal(item);

                    cart.DiscountTotal += item.DiscountTotal;
                    cart.SubTotal      += item.PlacedPrice * item.Quantity;
                    cart.TaxTotal      += item.TaxTotal;
                }
            }

            if (cart.Shipments != null)
            {
                foreach (var shipment in cart.Shipments)
                {
                    CalculateShipmentTotals(shipment);

                    cart.ShippingTotal += shipment.Total;
                    cart.DiscountTotal += shipment.DiscountTotal;
                    cart.TaxTotal      += shipment.TaxTotal;
                }
            }

            if (cart.Discounts != null)
            {
                foreach (var discount in cart.Discounts)
                {
                    cart.DiscountTotal += discount.DiscountAmount;
                }
            }

            if (cart.TaxTotal > 0)
            {
                cart.TaxIncluded = true;
            }
            cart.Total = cart.SubTotal + cart.ShippingTotal + cart.TaxTotal - cart.DiscountTotal;
        }
Example #27
0
        public async Task EvaluateTaxesAsync(TaxEvaluationContext context, IEnumerable <ITaxable> owners)
        {
            var taxRates = await _coreModuleApiClient.Commerce.EvaluateTaxesAsync(context.StoreId, context.ToTaxEvaluationContextDto());

            InnerEvaluateTaxes(taxRates, owners);
        }
        public static GetTaxRequest ToAvaTaxRequest(this TaxEvaluationContext evalContext, string companyCode, bool commit = false)
        {
            if (evalContext.Address != null && evalContext.Lines != null && evalContext.Lines.Any())
            {
                // Document Level Elements
                // Required Request Parameters
                var getTaxRequest = new GetTaxRequest
                {
                    CustomerCode = evalContext.Customer.Id,
                    DocDate      = DateTime.UtcNow.ToString("yyyy-MM-dd"),
                    CompanyCode  = companyCode,
                    Client       = "VirtoCommerce,2.x,VirtoCommerce",
                    DetailLevel  = DetailLevel.Tax,
                    Commit       = commit,
                    DocType      = DocType.SalesInvoice,
                    DocCode      = evalContext.Id,
                    CurrencyCode = evalContext.Currency.ToString()
                };

                // Best Practice Request Parameters

                // Situational Request Parameters
                // getTaxRequest.CustomerUsageType = "G";
                // getTaxRequest.ExemptionNo = "12345";
                // getTaxRequest.BusinessIdentificationNo = "234243";
                // getTaxRequest.Discount = 50;
                // getTaxRequest.TaxOverride = new TaxOverrideDef();
                // getTaxRequest.TaxOverride.TaxOverrideType = "TaxDate";
                // getTaxRequest.TaxOverride.Reason = "Adjustment for return";
                // getTaxRequest.TaxOverride.TaxDate = "2013-07-01";
                // getTaxRequest.TaxOverride.TaxAmount = "0";

                // Optional Request Parameters
                //getTaxRequest.PurchaseOrderNo = order.Number;
                //getTaxRequest.ReferenceCode = "ref123456";
                //getTaxRequest.PosLaneCode = "09";

                //add customer tax exemption code to cart if exists
                getTaxRequest.ExemptionNo = evalContext.Customer.GetDynamicPropertyValue("Tax exempt", string.Empty);

                string destinationAddressIndex = "0";

                // Address Data
                var addresses = new List <Address> {
                    new Address
                    {
                        AddressCode = destinationAddressIndex,
                        Line1       = evalContext.Address.Line1,
                        City        = evalContext.Address.City,
                        Region      = evalContext.Address.RegionName ?? evalContext.Address.RegionId,
                        PostalCode  = evalContext.Address.PostalCode,
                        Country     = evalContext.Address.CountryName
                    }
                };

                getTaxRequest.Addresses = addresses.ToArray();

                // Line Data
                // Required Parameters

                getTaxRequest.Lines = evalContext.Lines.Select(li =>
                                                               new Line
                {
                    LineNo          = li.Id,
                    ItemCode        = li.Code,
                    Qty             = li.Amount,
                    Amount          = li.Price * li.Amount,
                    OriginCode      = destinationAddressIndex, //TODO set origin address (fulfillment?)
                    DestinationCode = destinationAddressIndex,
                    Description     = li.Name,
                    TaxCode         = li.TaxType
                }
                                                               ).ToList();

                return(getTaxRequest);
            }
            return(null);
        }