예제 #1
0
        public async Task <ActionResult <decimal> > ConvertCurrency(ExchangeRate exchangeRate)
        {
            try
            {
                _logger.LogInformation($"Converting given amount of currency to provided currency: {exchangeRate}");
                var currencyCodes = _context.Currencies.Select(c => c.Code).ToList();

                if (!currencyCodes.Contains(exchangeRate.CurrencyFrom))
                {
                    return(NotFound(
                               $"Currency code \"{exchangeRate.CurrencyFrom}\" not found in available curriences"));
                }

                if (!currencyCodes.Contains(exchangeRate.CurrencyTo))
                {
                    return(NotFound(
                               $"Currency code \"{exchangeRate.CurrencyTo}\" not found in available curriences"));
                }

                return(await _currencyConverter.Convert(exchangeRate.AmountFrom, new Currency(exchangeRate.CurrencyFrom),
                                                        new Currency(exchangeRate.CurrencyTo)));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error in converting currency.");
                throw;
            }
        }
        public override async Task <IList <ProductViewModel> > ExecuteQuery(ListProductsQuery query, CancellationToken cancellationToken)
        {
            IList <ProductViewModel> productsViewMiodel = new List <ProductViewModel>();
            var products = await _unitOfWork.ProductRepository.ListAll(cancellationToken);

            if (string.IsNullOrEmpty(query.Currency))
            {
                throw new InvalidDataException("Currency code cannot be empty.");
            }

            var currency = Currency.FromCode(query.Currency);

            foreach (var product in products)
            {
                var convertedPrice = _currencyConverter.Convert(currency, product.Price);

                productsViewMiodel.Add(new ProductViewModel
                {
                    Id             = product.Id,
                    Name           = product.Name,
                    Price          = convertedPrice.Value.ToString(),
                    CurrencySymbol = currency.Symbol
                });
            }

            return(productsViewMiodel);
        }
예제 #3
0
        /// <summary>
        /// Gets the product totals.
        /// </summary>
        /// <typeparam name="TTotals">The type of the totals.</typeparam>
        /// <typeparam name="TProduct">The type of the product.</typeparam>
        /// <typeparam name="TCurrency">The type of the currency.</typeparam>
        /// <param name="product">The product.</param>
        /// <param name="currency">The currency.</param>
        /// <param name="quantity">The quantity.</param>
        /// <returns>The product prices list.</returns>
        public virtual TTotals GetProductTotals <TTotals, TProduct, TCurrency>(TProduct product, TCurrency currency, uint quantity)
            where TProduct : ProductBaseData
            where TTotals : DomainModel.Prices.Totals
            where TCurrency : Currency
        {
            Assert.ArgumentNotNull(product, "product");
            Assert.ArgumentNotNull(currency, "currency");

            TTotals productTotals = Context.Entity.Resolve <TTotals>();

            if (quantity < 1)
            {
                return(productTotals);
            }

            IDictionary <string, decimal> priceMatrix = new Dictionary <string, decimal>
            {
                { "NormalPrice", this.GetPriceMatrixPrice(product, "Normalprice") },
                { "MemberPrice", this.GetPriceMatrixPrice(product, "Memberprice") }
            };

            decimal vat = decimal.Zero;

            if (product is Product)
            {
                vat = this.GetVat(product as Product);
            }

            DomainModel.Prices.Totals totals = this.GetProductTotals(priceMatrix, vat, quantity);

            ICurrencyConverter <TTotals, TCurrency> currencyConverter = Context.Entity.Resolve <ICurrencyConverter <TTotals, TCurrency> >();

            return(currencyConverter.Convert(totals as TTotals, currency));
        }
예제 #4
0
        public async override Task <CartDetailsViewModel> ExecuteQuery(GetCartDetailsQuery query, CancellationToken cancellationToken)
        {
            CartDetailsViewModel viewModel = new CartDetailsViewModel();

            var customer = await _unitOfWork.CustomerRepository.GetById(query.CustomerId, cancellationToken);

            if (customer == null)
            {
                throw new InvalidDataException("Customer not found.");
            }

            if (string.IsNullOrWhiteSpace(query.Currency))
            {
                throw new InvalidDataException("Currency can't be empty.");
            }

            var cart = await _unitOfWork.CartRepository.GetByCustomerId(query.CustomerId, cancellationToken);

            if (cart == null)
            {
                // Creating cart
                cart = new Cart(customer);
                await _unitOfWork.CartRepository.Add(cart, cancellationToken);

                await _unitOfWork.CommitAsync();
            }

            var currency = Currency.FromCode(query.Currency);

            viewModel.CartId = cart.Id;
            if (cart.Items.Count > 0)
            {
                var productIds = cart.Items.Select(p => p.Product.Id).ToList();
                var products   = await _unitOfWork.ProductRepository.GetByIds(productIds, cancellationToken);

                if (products == null)
                {
                    throw new InvalidDataException("Products not found");
                }

                foreach (var cartItem in cart.Items)
                {
                    var product = products.Single(p => p.Id == cartItem.Product.Id);

                    viewModel.CartItems.Add(new CartItemDetailsViewModel
                    {
                        ProductId       = cartItem.Product.Id,
                        ProductQuantity = cartItem.Quantity,
                        ProductName     = product.Name,
                        ProductPrice    = _currencyConverter.Convert(currency, cartItem.Product.Price).Value,
                        CurrencySymbol  = currency.Symbol,
                    });
                }

                viewModel.CalculateTotalOrderPrice();
            }

            return(viewModel);
        }
        private async Task <double> SetAmount(string amountStr)
        {
            var    digits = Regex.Match(amountStr, @"^\d+").Value;
            double amount = double.Parse(digits);
            var    value  = await currencyConverter.Convert(amount, "EUR", "GBP");

            return(value > -1 ? value : amount);
        }
예제 #6
0
        public Money GetTotal(ICurrencyConverter currencyConverter, Currency currency)
        {
            var amount = _orderLines.Sum(ol =>
            {
                Money convertedProductPrice = currencyConverter.Convert(ol.Product.Price, currency);
                return(convertedProductPrice.Amount * ol.Quantity);
            });

            return(new Money(currency, amount));
        }
예제 #7
0
        /// <summary>
        /// Проставление полных стоимостей цены и её частей на основании подробностей цены с приведением к заданной валюте
        /// </summary>
        public void CalculateTotalPrices(string currency, ICurrencyConverter currencyConverter)
        {
            TotalPrice = new Money(0, currency, currencyConverter);

            foreach (var pricePart in GetPriceBreakdownsForCalculatingTotalPrice())
            {
                pricePart.CalculateTotalPrice();
                TotalPrice += currencyConverter.Convert(pricePart.TotalPrice, currency);
            }
        }
예제 #8
0
        public void Deposit(Money amount, ICurrencyConverter currencyConverter)
        {
            if (amount.Value < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(amount), "amount cannot be negative");
            }

            var normalizedAmount = currencyConverter.Convert(amount, this.Balance.Currency);

            this.AddEvent(new Deposit(this, normalizedAmount));
        }
예제 #9
0
        public static QuoteView FromModel(Quote quote, ICurrencyConverter currencyConverter, Currency currency)
        {
            if (null == quote)
            {
                throw new ArgumentNullException(nameof(quote));
            }

            var items = quote.Items.Select(qi => new QuoteItemView(qi.Product.Id, qi.Product.Name,
                                                                   currencyConverter.Convert(qi.Product.Price, currency), qi.Quantity)).ToArray();

            return(new QuoteView(quote.Id, items));
        }
예제 #10
0
        public static OrderView FromModel(Order order, ICurrencyConverter currencyConverter, Currency currency)
        {
            if (null == order)
            {
                throw new ArgumentNullException(nameof(order));
            }

            var items = order.OrderLines.Select(qi => new OrderLineView(qi.Product.Id, qi.Product.Name,
                                                                        currencyConverter.Convert(qi.Product.Price, currency), qi.Quantity)).ToArray();

            return(new OrderView(order.Id, items));
        }
예제 #11
0
    private void CalculateProductPrices(Money productPrice, Currency currency,
                                        ICurrencyConverter currencyConverter)
    {
        ProductBasePrice = Quantity * productPrice;
        var convertedPrice = currencyConverter.Convert(currency, ProductBasePrice);

        if (convertedPrice == null)
        {
            throw new BusinessRuleException("A valid product price must be provided.");
        }

        ProductExchangePrice = Money.Of(convertedPrice.Value, currency.Code);
    }
예제 #12
0
    public async override Task <QuoteDetailsViewModel> ExecuteQuery(GetQuoteDetailsQuery query,
                                                                    CancellationToken cancellationToken)
    {
        QuoteDetailsViewModel viewModel = new QuoteDetailsViewModel();

        var quoteId = new QuoteId(query.QuoteId);
        var quote   = await _unitOfWork.Quotes
                      .GetById(quoteId, cancellationToken);

        if (quote == null)
        {
            throw new ApplicationDataException("Quote not found.");
        }

        if (string.IsNullOrWhiteSpace(query.Currency))
        {
            throw new ApplicationDataException("Currency can't be empty.");
        }

        if (quote.Items.Count > 0)
        {
            viewModel.QuoteId = quote.Id.Value;
            var currency   = Currency.FromCode(query.Currency);
            var productIds = quote.Items.Select(p => p.ProductId).ToList();
            var products   = await _unitOfWork.Products
                             .GetByIds(productIds, cancellationToken);

            if (products == null)
            {
                throw new ApplicationDataException("Products not found");
            }

            foreach (var quoteItem in quote.Items)
            {
                var product        = products.Single(p => p.Id == quoteItem.ProductId);
                var convertedPrice = _currencyConverter.Convert(currency, product.Price);
                viewModel.QuoteItems.Add(new QuoteItemDetailsViewModel
                {
                    ProductId       = quoteItem.ProductId.Value,
                    ProductQuantity = quoteItem.Quantity,
                    ProductName     = product.Name,
                    ProductPrice    = Math.Round(convertedPrice.Value, 2),
                    CurrencySymbol  = currency.Symbol,
                });;
            }

            viewModel.CalculateTotalOrderPrice();
        }

        return(viewModel);
    }
예제 #13
0
        public void Withdraw(Money amount, ICurrencyConverter currencyConverter)
        {
            if (amount.Value < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(amount), "amount cannot be negative");
            }

            var normalizedAmount = currencyConverter.Convert(amount, this.Balance.Currency);

            if (normalizedAmount.Value > this.Balance.Value)
            {
                throw new AccountTransactionException($"unable to withdrawn {normalizedAmount} from account {this.Id}", this);
            }

            this.AddEvent(new Withdrawal(this, amount));
        }
예제 #14
0
        public UvsMockEcommerceService(ICurrencyConverter currencyConverter, Action <ECommerceHandleSettings> setupAction)
        {
            _currencyConverter = currencyConverter;
            _settings          = setupAction?.CreateTargetAndInvoke();

            _adapter = new MockUvsAdapter();
            _adapter.OnUvsPayment += (sender, e) =>
                                     OnReceived?.Invoke(this, new ECommerceIncomeEventArgs {
                Income = MoneyNaturalized.Create(_currencyConverter.Convert(Money.Create(e.Amount, _order.Amount.Currency), _settings.BaseCurrency),
                                                 Money.Create(e.Amount, _order.Amount.Currency))
            });
            _adapter.OnUvsOrderCancelled += (sender, e) =>
                                            OnPaymentCancelled?.Invoke(this, new ECommercePaymentCancelledEventArgs {
                Message = e.Message
            });
        }
    public async Task Order_has_been_placed_for_customer()
    {
        var currency        = Currency.CanadianDollar;
        var productPrice    = 12.5;
        var productQuantity = 10;
        var customerEmail   = "*****@*****.**";

        var productMoney = Money.Of(Convert.ToDecimal(productPrice), currency.Code);

        _currencyConverter.Convert(currency, Money.Of(Convert.ToDecimal(productPrice * productQuantity), currency.Code))
        .Returns(productMoney);

        var customerUniquenessChecker = Substitute.For <ICustomerUniquenessChecker>();

        customerUniquenessChecker.IsUserUnique(customerEmail).Returns(true);

        var customerId = new CustomerId(Guid.NewGuid());
        var customer   = Customer.CreateNew(customerEmail, "Customer X", customerUniquenessChecker);

        _customers.GetById(Arg.Any <CustomerId>()).Returns(customer);

        var product = Product.CreateNew("Product X", productMoney);

        _products.GetById(Arg.Any <ProductId>()).Returns(product);

        var productData = new QuoteItemProductData(product.Id, product.Price, productQuantity);
        var quote       = Quote.CreateNew(customerId);

        quote.AddItem(productData);

        List <Product> products = new List <Product>()
        {
            product
        };

        _quotes.GetById(quote.Id).Returns(quote);
        _products.GetByIds(Arg.Any <List <ProductId> >()).Returns(products);

        var placeOrderCommandHandler = new PlaceOrderCommandHandler(_unitOfWork, _currencyConverter);
        var placeOrderCommand        = new PlaceOrderCommand(quote.Id.Value, customerId.Value, currency.Code);

        var orderResult = await placeOrderCommandHandler.Handle(placeOrderCommand, CancellationToken.None);

        await _unitOfWork.Received(1).CommitAsync(Arg.Any <CancellationToken>());

        orderResult.Should().NotBe(Guid.Empty);
    }
예제 #16
0
        public IEnumerable <Product> Get(int pageStart = 0, int pageSize = 5, bool applyCurrencyConversion = false)
        {
            //Get the latest menu of products (I am assuming that is what _dataAccess.List() returns) rather than the random static products
            //The api returns the products but it use the data access functionality implemented
            var productList = _dataAccess.List(pageStart, pageSize);

            if (!applyCurrencyConversion)
            {
                return(productList);
            }

            //Get the price of the products returned in Euros when required
            return(productList.Select(product => new Product
            {
                Name = product.Name,
                Price = _currencyConverter.Convert(product.Price),
            }).ToList());
        }
예제 #17
0
        public double CalculateStock()
        {
            var    Stock      = stockProvider.GetStock();
            double totalPrice = 0;

            foreach (var item in Stock)
            {
                if (item.Currency == "RON")
                {
                    var totalPriceperItem = item.PricePerUnit * item.Quantity;
                    totalPrice += totalPriceperItem;
                }
                else
                {
                    double convertedAmmount = currencyConverter.Convert(item.PricePerUnit, item.Currency);
                    totalPrice += item.Quantity * convertedAmmount;
                }
            }

            return(totalPrice);
        }
예제 #18
0
        public async Task <RoiCalculationResult> Calculate(RoiCalculationRequest request)
        {
            var roi = new RoiCalculationResult()
            {
                Currency = _roiConfiguration.BaseCurrency, //It will be change to target currency once an actual conversion is applied.
                Total    = 0,
                Fees     = _roiConfiguration.BaseFee
            };

            // Apply each rule to investment allocation and amount;
            request.InvestmentOptions.ForEach(option =>
            {
                var investmentOptionInformation = _roiConfiguration.InvestmentBusinessRules.Find(op => op.Id == option.Id);

                if (investmentOptionInformation is null)
                {
                    throw new Exception("INVALID_OPTION");
                }

                var investmentAmountForOption = request.InvestmentAmount * option.AllocatedProportion;

                var optionRoi = investmentOptionInformation.CalculateRoiForAmount(investmentAmountForOption, option.AllocatedProportion);

                roi.Total += optionRoi.Value;
                roi.Fees  += optionRoi.Fee;
            });

            try
            {
                await _currencyConverter.Convert(roi, _roiConfiguration.BaseCurrency, _roiConfiguration.TargetCurrency);
            }
            catch (Exception ex)
            {
                // TODO: log this exception.
                Debug.Write(ex);
                // If something happens with the Fx rates service we just return in the same currency.
            }

            return(roi);
        }
예제 #19
0
        private IEnumerable <AuthorsInPrintingEditionsViewModel> AuthorsInPrintForming(IEnumerable <AuthorInPrintingEditions> authorsInPriningEditions, string currentCurrencyName)
        {
            var modelsList = new List <AuthorsInPrintingEditionsViewModel>();

            foreach (AuthorInPrintingEditions printEd in authorsInPriningEditions)
            {
                AuthorsInPrintingEditionsViewModel printEditionModel = modelsList.FirstOrDefault(r => r.PrtintingEditionId == printEd.PrintingEditionId);

                if (printEditionModel == null)
                {
                    double price = _currencyConverter.Convert(printEd.PrintingEdition.Currency, printEd.PrintingEdition.Price, currentCurrencyName);
                    printEditionModel = new AuthorsInPrintingEditionsViewModel
                    {
                        CurrencyName                = currentCurrencyName,
                        PrintingEditionImage        = printEd.PrintingEdition.ImageUrl,
                        PrintingEditionStatus       = printEd.PrintingEdition.Status,
                        PrintingEditionPrice        = price,
                        PrintingEditionTitle        = printEd.PrintingEdition.NameEdition,
                        PrtintingEditionDescription = printEd.PrintingEdition.Description,
                        PrtintingEditionType        = printEd.PrintingEdition.Type,
                        PrtintingEditionId          = printEd.PrintingEditionId
                    };

                    modelsList.Add(printEditionModel);
                }

                printEditionModel.AuthorsList.Add(new AuthorViewModel
                {
                    FirstName = printEd.Author.FirstName,
                    LastName  = printEd.Author.LastName,
                    Id        = printEd.Author.Id
                });
            }

            return(modelsList);
        }
예제 #20
0
        public T GetDiscountDataItem <T>(ICurrencyConverter currencyConverter, string currency) where T : BasePNRDataItem, new()
        {
            if (string.IsNullOrEmpty(Discount))
            {
                return(null);
            }

            DiscountDataItem discountDI = null;

            if (Discount.EndsWith("%"))
            {
                discountDI         = new DiscountDataItem();
                discountDI.Percent = Convert.ToSingle(Discount.TrimEnd('%'));
            }
            else
            {
                var discountMoney = currencyConverter.Convert(Money.Parse(Discount), currency);

                discountDI          = new DiscountDataItem();
                discountDI.Amount   = (float)discountMoney.Value;
                discountDI.Currency = discountMoney.Currency;
            }

            if (discountDI != null)
            {
                discountDI.AuthCode = AuthCode;

                var dataItem = new T();
                dataItem.Type     = PNRDataItemType.Discount;
                dataItem.Discount = discountDI;

                return(dataItem);
            }

            return(null);
        }
예제 #21
0
        private Invoice ProcessInvoiceLine(IReadOnlyDictionary <string, string> valuesFromAmazon, uint index, InvoiceConversionContext context)
        {
            var invoice = new Invoice(_vatPercentage);

            string shipCountry = valuesFromAmazon["ship-country"];

            // TODO handle optional fields
            decimal promotionDiscount = 0;

            if (valuesFromAmazon.TryGetValue("item-promotion-discount", out string itemDiscount))
            {
                promotionDiscount = decimal.Parse(itemDiscount);
            }

            if (valuesFromAmazon.TryGetValue("ship-promotion-discount", out string shippingDiscount))
            {
                decimal shipPromotionDiscount = decimal.Parse(shippingDiscount);
                promotionDiscount += shipPromotionDiscount; // shipping discount se scita do total discount
            }

            string sku = valuesFromAmazon["sku"];

            DateTime today = context.ConvertToDate;

            invoice.CurrencyName       = _currencyConverter.Convert(valuesFromAmazon["currency"]);
            invoice.Number             = context.ExistingInvoiceNumber + index;
            invoice.VariableSymbolFull = valuesFromAmazon["order-id"];
            invoice.ShipCountryCode    = shipCountry;
            invoice.ConversionDate     = today;

            string clientName  = FormatClientName(valuesFromAmazon["recipient-name"], invoice.VariableSymbolFull);
            string city        = FormatCity(valuesFromAmazon["ship-city"], valuesFromAmazon["ship-state"], string.Empty, invoice.VariableSymbolFull);
            string fullAddress = FormatFullAddress(valuesFromAmazon["ship-address-1"], valuesFromAmazon["ship-address-2"], valuesFromAmazon["ship-address-3"], invoice.VariableSymbolFull);
            string phoneNumber = FormatPhoneNumber(valuesFromAmazon["ship-phone-number"], valuesFromAmazon["buyer-phone-number"], invoice.VariableSymbolFull);

            invoice.ClientInfo = new ClientInfo
            {
                Name    = clientName,
                Address = new Address
                {
                    City    = city,
                    Street  = fullAddress,
                    Country = shipCountry,
                    Zip     = valuesFromAmazon["ship-postal-code"]
                },
                Contact = new ContactData
                {
                    Email = context.DefaultEmail,
                    Phone = phoneNumber
                }
            };

            invoice.CustomsDeclaration   = GetCustomsDeclarationBySkuOnlyForNonEu(sku, invoice.Classification);
            invoice.RelatedWarehouseName = GetSavedWarehouseBySku(sku);

            if (valuesFromAmazon.TryGetValue("sales-channel", out string salesChannelValue))
            {
                invoice.SalesChannel = salesChannelValue;
            }

            var invoiceItems   = new List <InvoiceItemBase>();
            var invoiceProduct = new InvoiceProduct(invoice)
            {
                WarehouseCode = GetSavedItemCodeBySku(sku),
                AmazonSku     = sku
            };


            var invoiceItemProduct = FillInvoiceItem(
                invoiceProduct,
                valuesFromAmazon["product-name"],
                decimal.Parse(valuesFromAmazon["item-price"]),
                decimal.Parse(valuesFromAmazon["item-tax"]),
                decimal.Parse(valuesFromAmazon["quantity-purchased"]));

            invoiceProduct.PackQuantityMultiplier = 1;
            if (!string.IsNullOrEmpty(invoiceProduct.AmazonSku) &&
                _autocompleteData.PackQuantitySku.ContainsKey(invoiceProduct.AmazonSku))
            {
                invoiceProduct.PackQuantityMultiplier = uint.Parse(_autocompleteData.PackQuantitySku[invoiceProduct.AmazonSku]);
            }
            invoiceItems.Add(invoiceItemProduct);


            var invoiceItemShipping = FillInvoiceItem(
                new InvoiceItemGeneral(invoice, InvoiceItemType.Shipping),
                GetSavedShippingType(sku, invoice.ClientInfo, invoice.Classification),
                decimal.Parse(valuesFromAmazon["shipping-price"]),
                decimal.Parse(valuesFromAmazon["shipping-tax"]),
                1);

            invoiceItems.Add(invoiceItemShipping);


            if (promotionDiscount != 0)
            {
                var invoiceItemDiscount = FillInvoiceItem(
                    new InvoiceItemGeneral(invoice, InvoiceItemType.Discount),
                    "Discount",
                    promotionDiscount,
                    0,
                    1);
                invoiceItems.Add(invoiceItemDiscount);
            }

            // TODO fix
            if (valuesFromAmazon.TryGetValue("gift-wrap-price", out var giftWrapPrice) && // columns are not always available in the amazon invoice
                valuesFromAmazon.TryGetValue("gift-wrap-tax", out var giftWrapTax) &&
                decimal.TryParse(giftWrapPrice, out var giftWrapPriceValue) &&
                giftWrapPriceValue != 0)
            {
                decimal giftWrapTaxVal = 0;

                if (decimal.TryParse(giftWrapTax, out var valueTax))
                {
                    giftWrapTaxVal = valueTax;
                }

                string giftWrapType        = "Gift wrap " + valuesFromAmazon["gift-wrap-type"];
                var    invoiceItemGiftWrap = FillInvoiceItem(
                    new InvoiceItemGeneral(invoice, InvoiceItemType.GiftWrap),
                    giftWrapType,
                    giftWrapPriceValue,
                    giftWrapTaxVal,
                    1);
                invoiceItems.Add(invoiceItemGiftWrap);
            }

            foreach (var item in invoiceItems)
            {
                invoice.AddInvoiceItem(item);
            }

            return(invoice);
        }
        private void MakeBonusTransaction(User user, CurrencyAmount bonusAmount)
        {
            var bonus = Converter.Convert(bonusAmount, user.BonusAccount.Currency);

            user.BonusAccount.Transactions.Add(new Transaction(user.BonusAccount, bonus));
        }
예제 #23
0
        protected override Money <T> EvaluateInner(ICurrencyConverter <T> currencyConverter, Currency toCurrency)
        {
            var convertedAmount = currencyConverter.Convert(this.Money.Amount, this.Money.Currency, toCurrency);

            return(new Money <T>(convertedAmount, toCurrency));
        }
 public static decimal Convert(this ICurrencyConverter converter, CurrencyAmount from, Currency to) =>
 converter.Convert(from.Currency, to, from.Amount);