/// <summary> /// Prepare paged affiliate list model /// </summary> /// <param name="searchModel">Affiliate search model</param> /// <returns>Affiliate list model</returns> public virtual async Task <AffiliateListModel> PrepareAffiliateListModelAsync(AffiliateSearchModel searchModel) { if (searchModel == null) { throw new ArgumentNullException(nameof(searchModel)); } //get affiliates var affiliates = await _affiliateService.GetAllAffiliatesAsync(searchModel.SearchFriendlyUrlName, searchModel.SearchFirstName, searchModel.SearchLastName, searchModel.LoadOnlyWithOrders, searchModel.OrdersCreatedFromUtc, searchModel.OrdersCreatedToUtc, searchModel.Page - 1, searchModel.PageSize, true); //prepare list model var model = await new AffiliateListModel().PrepareToGridAsync(searchModel, affiliates, () => { //fill in model values from the entity return(affiliates.SelectAwait(async affiliate => { var address = await _addressService.GetAddressByIdAsync(affiliate.AddressId); var affiliateModel = affiliate.ToModel <AffiliateModel>(); affiliateModel.Address = address.ToModel <AddressModel>(); affiliateModel.Address.CountryName = (await _countryService.GetCountryByAddressAsync(address))?.Name; affiliateModel.Address.StateProvinceName = (await _stateProvinceService.GetStateProvinceByAddressAsync(address))?.Name; return affiliateModel; })); }); return(model); }
public virtual async Task <CustomerAddressListModel> PrepareCompanyCustomerAddressListModelAsync(CustomerAddressSearchModel searchModel, Company company) { if (searchModel == null) { throw new ArgumentNullException(nameof(searchModel)); } if (company == null) { throw new ArgumentNullException(nameof(company)); } var model = new CustomerAddressListModel(); var getCompanyCustomers = await _companyService.GetCompanyCustomersByCompanyIdAsync(company.Id); IPagedList <Address> addressesList = new PagedList <Address>(new List <Address>(), 0, 1); foreach (var getCompanyCustomer in getCompanyCustomers) { var customer = await _customerService.GetCustomerByIdAsync(getCompanyCustomer.CustomerId); //get customer addresses var addresses = (await _customerService.GetAddressesByCustomerIdAsync(customer.Id)) .OrderByDescending(address => address.CreatedOnUtc).ThenByDescending(address => address.Id).ToList() .ToPagedList(searchModel); foreach (var address in addresses) { if (!addressesList.Where(x => x.Id == address.Id).Any()) { addressesList.Add(address); } } searchModel.CustomerId = customer.Id; } //prepare list model model = await new CustomerAddressListModel().PrepareToGridAsync(searchModel, addressesList, () => { return(addressesList.SelectAwait(async address => { //fill in model values from the entity var addressModel = address.ToModel <AddressModel>(); var customerAddressMapping = await _customerService.GetCustomerAddressesByAddressIdAsync(address.Id); addressModel.CustomerId = customerAddressMapping.Any() ? customerAddressMapping.FirstOrDefault().CustomerId : 0; addressModel.CountryName = (await _countryService.GetCountryByAddressAsync(address))?.Name; addressModel.StateProvinceName = (await _stateProvinceService.GetStateProvinceByAddressAsync(address))?.Name; //fill in additional values (not existing in the entity) await PrepareModelAddressHtmlAsync(addressModel, address); return addressModel; })); }); return(model); }
/// <summary> /// Create common query parameters for the request /// </summary> /// <param name="postProcessPaymentRequest">Payment info required for an order processing</param> /// <returns>Created query parameters</returns> private async Task <IDictionary <string, string> > CreateQueryParametersAsync(PostProcessPaymentRequest postProcessPaymentRequest) { //get store location var storeLocation = _webHelper.GetStoreLocation(); //choosing correct order address var orderAddress = await _addressService.GetAddressByIdAsync( (postProcessPaymentRequest.Order.PickupInStore ? postProcessPaymentRequest.Order.PickupAddressId : postProcessPaymentRequest.Order.ShippingAddressId) ?? 0); //create query parameters return(new Dictionary <string, string> { //PayPal ID or an email address associated with your PayPal account ["business"] = _payPalStandardPaymentSettings.BusinessEmail, //the character set and character encoding ["charset"] = "utf-8", //set return method to "2" (the customer redirected to the return URL by using the POST method, and all payment variables are included) ["rm"] = "2", ["bn"] = PayPalHelper.NopCommercePartnerCode, ["currency_code"] = (await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId))?.CurrencyCode, //order identifier ["invoice"] = postProcessPaymentRequest.Order.CustomOrderNumber, ["custom"] = postProcessPaymentRequest.Order.OrderGuid.ToString(), //PDT, IPN and cancel URL ["return"] = $"{storeLocation}Plugins/PaymentPayPalStandard/PDTHandler", ["notify_url"] = $"{storeLocation}Plugins/PaymentPayPalStandard/IPNHandler", ["cancel_return"] = $"{storeLocation}Plugins/PaymentPayPalStandard/CancelOrder", //shipping address, if exists ["no_shipping"] = postProcessPaymentRequest.Order.ShippingStatus == ShippingStatus.ShippingNotRequired ? "1" : "2", ["address_override"] = postProcessPaymentRequest.Order.ShippingStatus == ShippingStatus.ShippingNotRequired ? "0" : "1", ["first_name"] = orderAddress?.FirstName, ["last_name"] = orderAddress?.LastName, ["address1"] = orderAddress?.Address1, ["address2"] = orderAddress?.Address2, ["city"] = orderAddress?.City, ["state"] = (await _stateProvinceService.GetStateProvinceByAddressAsync(orderAddress))?.Abbreviation, ["country"] = (await _countryService.GetCountryByAddressAsync(orderAddress))?.TwoLetterIsoCode, ["zip"] = orderAddress?.ZipPostalCode, ["email"] = orderAddress?.Email }); }
/// <summary> /// Get pickup points for the address /// </summary> /// <param name="address">Address</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the represents a response of getting pickup points /// </returns> public async Task <GetPickupPointsResponse> GetPickupPointsAsync(Address address) { var result = new GetPickupPointsResponse(); var store = await _storeContext.GetCurrentStoreAsync(); foreach (var point in await _storePickupPointService.GetAllStorePickupPointsAsync(store.Id)) { var pointAddress = await _addressService.GetAddressByIdAsync(point.AddressId); if (pointAddress == null) { continue; } result.PickupPoints.Add(new PickupPoint { Id = point.Id.ToString(), Name = point.Name, Description = point.Description, Address = pointAddress.Address1, City = pointAddress.City, County = pointAddress.County, StateAbbreviation = (await _stateProvinceService.GetStateProvinceByAddressAsync(pointAddress))?.Abbreviation ?? string.Empty, CountryCode = (await _countryService.GetCountryByAddressAsync(pointAddress))?.TwoLetterIsoCode ?? string.Empty, ZipPostalCode = pointAddress.ZipPostalCode, OpeningHours = point.OpeningHours, PickupFee = point.PickupFee, DisplayOrder = point.DisplayOrder, ProviderSystemName = PluginDescriptor.SystemName, Latitude = point.Latitude, Longitude = point.Longitude, TransitDays = point.TransitDays }); } if (!result.PickupPoints.Any()) { result.AddError(await _localizationService.GetResourceAsync("Plugins.Pickup.PickupInStore.NoPickupPoints")); } return(result); }
/// <summary> /// Post process payment (used by payment gateways that require redirecting to a third-party URL) /// </summary> /// <param name="postProcessPaymentRequest">Payment info required for an order processing</param> public async Task PostProcessPaymentAsync(PostProcessPaymentRequest postProcessPaymentRequest) { //choosing correct order address var orderAddress = await _addressService.GetAddressByIdAsync( (postProcessPaymentRequest.Order.PickupInStore ? postProcessPaymentRequest.Order.PickupAddressId : postProcessPaymentRequest.Order.ShippingAddressId) ?? 0); var orderShippingAddress = await _addressService.GetAddressByIdAsync((int)postProcessPaymentRequest.Order.ShippingAddressId); var myUtility = new PayuHelper(); var orderId = postProcessPaymentRequest.Order.Id; var remotePostHelper = new RemotePost(); remotePostHelper.FormName = "PayuForm"; remotePostHelper.Url = _PayuPaymentSettings.PayUri; remotePostHelper.Add("key", _PayuPaymentSettings.MerchantId.ToString()); remotePostHelper.Add("amount", postProcessPaymentRequest.Order.OrderTotal.ToString(new CultureInfo("en-US", false).NumberFormat)); remotePostHelper.Add("productinfo", "productinfo"); remotePostHelper.Add("Currency", (await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId)).CurrencyCode); remotePostHelper.Add("Order_Id", orderId.ToString()); remotePostHelper.Add("txnid", orderId.ToString()); remotePostHelper.Add("service_provider", "payu_paisa"); remotePostHelper.Add("surl", _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayu/Return"); remotePostHelper.Add("furl", _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayu/Return"); remotePostHelper.Add("hash", myUtility.getchecksum(_PayuPaymentSettings.MerchantId.ToString(), postProcessPaymentRequest.Order.Id.ToString(), postProcessPaymentRequest.Order.OrderTotal.ToString(new CultureInfo("en-US", false).NumberFormat), "productinfo", orderAddress?.FirstName, orderAddress?.Email.ToString(), _PayuPaymentSettings.Key)); //Billing details remotePostHelper.Add("firstname", orderAddress?.FirstName.ToString()); remotePostHelper.Add("billing_cust_address", orderAddress?.Address1); remotePostHelper.Add("phone", orderAddress?.PhoneNumber); remotePostHelper.Add("email", orderAddress?.Email.ToString()); remotePostHelper.Add("billing_cust_city", orderAddress?.City); var billingStateProvince = (await _stateProvinceService.GetStateProvinceByAddressAsync(orderAddress))?.Abbreviation; if (billingStateProvince != null) { remotePostHelper.Add("billing_cust_state", (await _stateProvinceService.GetStateProvinceByAddressAsync(orderAddress))?.Abbreviation); } else { remotePostHelper.Add("billing_cust_state", ""); } remotePostHelper.Add("billing_zip_code", orderAddress?.ZipPostalCode); var billingCountry = (await _countryService.GetCountryByAddressAsync(orderAddress))?.TwoLetterIsoCode; if (billingCountry != null) { remotePostHelper.Add("billing_cust_country", (await _countryService.GetCountryByAddressAsync(orderAddress))?.TwoLetterIsoCode); } else { remotePostHelper.Add("billing_cust_country", ""); } //Delivery details if (postProcessPaymentRequest.Order.ShippingStatus != ShippingStatus.ShippingNotRequired) { remotePostHelper.Add("delivery_cust_name", orderShippingAddress.FirstName); remotePostHelper.Add("delivery_cust_address", orderShippingAddress.Address1); remotePostHelper.Add("delivery_cust_notes", string.Empty); remotePostHelper.Add("delivery_cust_tel", orderShippingAddress.PhoneNumber); remotePostHelper.Add("delivery_cust_city", orderShippingAddress.City); var deliveryStateProvince = await _stateProvinceService.GetStateProvinceByAddressAsync(orderShippingAddress); if (deliveryStateProvince != null) { remotePostHelper.Add("delivery_cust_state", deliveryStateProvince.Abbreviation); } else { remotePostHelper.Add("delivery_cust_state", ""); } remotePostHelper.Add("delivery_zip_code", orderShippingAddress.ZipPostalCode); var deliveryCountry = await _countryService.GetCountryByAddressAsync(orderShippingAddress); // postProcessPaymentRequest.Order.ShippingAddress.Country; if (deliveryCountry != null) { remotePostHelper.Add("delivery_cust_country", deliveryCountry.ThreeLetterIsoCode); } else { remotePostHelper.Add("delivery_cust_country", ""); } } // remotePostHelper.Add("Merchant_Param", _PayuPaymentSettings.MerchantParam); remotePostHelper.Post(); }
/// <summary> /// Invoke the widget view component /// </summary> /// <param name="widgetZone">Widget zone</param> /// <param name="additionalData">Additional parameters</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the view component result /// </returns> public async Task <IViewComponentResult> InvokeAsync(string widgetZone, object additionalData) { //ensure that Avalara tax provider is active var customer = await _workContext.GetCurrentCustomerAsync(); if (!await _taxPluginManager.IsPluginActiveAsync(AvalaraTaxDefaults.SystemName, customer)) { return(Content(string.Empty)); } //ensure that it's a proper widget zone if (!widgetZone.Equals(PublicWidgetZones.CheckoutConfirmTop) && !widgetZone.Equals(PublicWidgetZones.OpCheckoutConfirmTop)) { return(Content(string.Empty)); } //ensure thet address validation is enabled if (!_avalaraTaxSettings.ValidateAddress) { return(Content(string.Empty)); } //validate entered by customer addresses only var addressId = _taxSettings.TaxBasedOn == TaxBasedOn.BillingAddress ? customer.BillingAddressId : _taxSettings.TaxBasedOn == TaxBasedOn.ShippingAddress ? customer.ShippingAddressId : null; var address = await _addressService.GetAddressByIdAsync(addressId ?? 0); if (address == null) { return(Content(string.Empty)); } //validate address var validationResult = await _avalaraTaxManager.ValidateAddressAsync(address); //whether there are errors in validation result var errorDetails = validationResult?.messages? .Where(message => message.severity.Equals("Error", StringComparison.InvariantCultureIgnoreCase)) .Select(message => message.details) ?? new List <string>(); if (errorDetails.Any()) { //display error message to customer return(View("~/Plugins/Tax.Avalara/Views/Checkout/AddressValidation.cshtml", new AddressValidationModel { Message = string.Format(await _localizationService.GetResourceAsync("Plugins.Tax.Avalara.AddressValidation.Error"), WebUtility.HtmlEncode(string.Join("; ", errorDetails))), IsError = true })); } //if there are no errors and no validated addresses, nothing to display if (!validationResult?.validatedAddresses?.Any() ?? true) { return(Content(string.Empty)); } //get validated address info var validatedAddressInfo = validationResult.validatedAddresses.FirstOrDefault(); //create new address as a copy of address to validate and with details of the validated one var validatedAddress = _addressService.CloneAddress(address); validatedAddress.City = validatedAddressInfo.city; validatedAddress.CountryId = (await _countryService.GetCountryByTwoLetterIsoCodeAsync(validatedAddressInfo.country))?.Id; validatedAddress.Address1 = validatedAddressInfo.line1; validatedAddress.Address2 = validatedAddressInfo.line2; validatedAddress.ZipPostalCode = validatedAddressInfo.postalCode; validatedAddress.StateProvinceId = (await _stateProvinceService.GetStateProvinceByAbbreviationAsync(validatedAddressInfo.region))?.Id; //try to find an existing address with the same values var existingAddress = _addressService.FindAddress((await _customerService.GetAddressesByCustomerIdAsync(customer.Id)).ToList(), validatedAddress.FirstName, validatedAddress.LastName, validatedAddress.PhoneNumber, validatedAddress.Email, validatedAddress.FaxNumber, validatedAddress.Company, validatedAddress.Address1, validatedAddress.Address2, validatedAddress.City, validatedAddress.County, validatedAddress.StateProvinceId, validatedAddress.ZipPostalCode, validatedAddress.CountryId, validatedAddress.CustomAttributes); //if the found address is the same as address to validate, nothing to display if (address.Id == existingAddress?.Id) { return(Content(string.Empty)); } //otherwise display to customer a confirmation dialog about address updating var model = new AddressValidationModel(); if (existingAddress == null) { await _addressService.InsertAddressAsync(validatedAddress); model.AddressId = validatedAddress.Id; model.IsNewAddress = true; } else { model.AddressId = existingAddress.Id; } async Task <string> getAddressLineAsync(Address address) => WebUtility.HtmlEncode($"{(!string.IsNullOrEmpty(address.Address1) ? $"{address.Address1}, " : string.Empty)}" + $"{(!string.IsNullOrEmpty(address.Address2) ? $"{address.Address2}, " : string.Empty)}" + $"{(!string.IsNullOrEmpty(address.City) ? $"{address.City}, " : string.Empty)}" + $"{(await _stateProvinceService.GetStateProvinceByAddressAsync(address) is StateProvince stateProvince ? $"{stateProvince.Name}, " : string.Empty)}" + $"{(await _countryService.GetCountryByAddressAsync(address) is Country country ? $"{country.Name}, " : string.Empty)}" + $"{(!string.IsNullOrEmpty(address.ZipPostalCode) ? $"{address.ZipPostalCode}, " : string.Empty)}" .TrimEnd(' ').TrimEnd(',')); model.Message = string.Format(await _localizationService.GetResourceAsync("Plugins.Tax.Avalara.AddressValidation.Confirm"), await getAddressLineAsync(address), await getAddressLineAsync(existingAddress ?? validatedAddress)); return(View("~/Plugins/Tax.Avalara/Views/Checkout/AddressValidation.cshtml", model)); }
private async Task ProcessOrderEventAsync(Order order, bool add) { try { //settings per store var store = await _storeService.GetStoreByIdAsync(order.StoreId) ?? await _storeContext.GetCurrentStoreAsync(); var googleAnalyticsSettings = await _settingService.LoadSettingAsync <GoogleAnalyticsSettings>(store.Id); var request = new GoogleRequest { AccountCode = googleAnalyticsSettings.GoogleId, Culture = "en-US", HostName = new Uri(_webHelper.GetThisPageUrl(false)).Host, PageTitle = add ? "AddTransaction" : "CancelTransaction" }; var orderId = order.CustomOrderNumber; var orderShipping = googleAnalyticsSettings.IncludingTax ? order.OrderShippingInclTax : order.OrderShippingExclTax; var orderTax = order.OrderTax; var orderTotal = order.OrderTotal; if (!add) { orderShipping = -orderShipping; orderTax = -orderTax; orderTotal = -orderTotal; } var billingAddress = await _addressService.GetAddressByIdAsync(order.BillingAddressId); var trans = new Transaction(FixIllegalJavaScriptChars(orderId), FixIllegalJavaScriptChars(billingAddress.City), await _countryService.GetCountryByAddressAsync(billingAddress) is Country country ? FixIllegalJavaScriptChars(country.Name) : string.Empty, await _stateProvinceService.GetStateProvinceByAddressAsync(billingAddress) is StateProvince stateProvince ? FixIllegalJavaScriptChars(stateProvince.Name) : string.Empty, store.Name, orderShipping, orderTax, orderTotal); foreach (var item in await _orderService.GetOrderItemsAsync(order.Id)) { var product = await _productService.GetProductByIdAsync(item.ProductId); //get category var category = (await _categoryService.GetCategoryByIdAsync((await _categoryService.GetProductCategoriesByProductIdAsync(product.Id)).FirstOrDefault()?.CategoryId ?? 0))?.Name; var unitPrice = googleAnalyticsSettings.IncludingTax ? item.UnitPriceInclTax : item.UnitPriceExclTax; var qty = item.Quantity; if (!add) { qty = -qty; } var sku = await _productService.FormatSkuAsync(product, item.AttributesXml); if (string.IsNullOrEmpty(sku)) { sku = product.Id.ToString(); } var productItem = new TransactionItem(FixIllegalJavaScriptChars(orderId), FixIllegalJavaScriptChars(sku), FixIllegalJavaScriptChars(product.Name), unitPrice, qty, FixIllegalJavaScriptChars(category)); trans.Items.Add(productItem); } await request.SendRequest(trans, _httpClientFactory.CreateClient(NopHttpDefaults.DefaultHttpClient)); } catch (Exception ex) { await _logger.InsertLogAsync(LogLevel.Error, "Google Analytics. Error canceling transaction from server side", ex.ToString()); } }
/// <summary> /// Create shipment packages (requests) from shopping cart /// </summary> /// <param name="cart">Shopping cart</param> /// <param name="shippingAddress">Shipping address</param> /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param> /// <returns>Shipment packages (requests). Value indicating whether shipping is done from multiple locations (warehouses)</returns> public virtual async Task <(IList <GetShippingOptionRequest> shipmentPackages, bool shippingFromMultipleLocations)> CreateShippingOptionRequestsAsync(IList <ShoppingCartItem> cart, Address shippingAddress, int storeId) { //if we always ship from the default shipping origin, then there's only one request //if we ship from warehouses ("ShippingSettings.UseWarehouseLocation" enabled), //then there could be several requests //key - warehouse identifier (0 - default shipping origin) //value - request var requests = new Dictionary <int, GetShippingOptionRequest>(); //a list of requests with products which should be shipped separately var separateRequests = new List <GetShippingOptionRequest>(); foreach (var sci in cart) { if (!await IsShipEnabledAsync(sci)) { continue; } var product = await _productService.GetProductByIdAsync(sci.ProductId); if (product == null || !product.IsShipEnabled) { var associatedProducts = await(await _productAttributeParser.ParseProductAttributeValuesAsync(sci.AttributesXml)) .Where(attributeValue => attributeValue.AttributeValueType == AttributeValueType.AssociatedToProduct) .SelectAwait(async attributeValue => await _productService.GetProductByIdAsync(attributeValue.AssociatedProductId)).ToListAsync(); product = associatedProducts.FirstOrDefault(associatedProduct => associatedProduct != null && associatedProduct.IsShipEnabled); } if (product == null) { continue; } //warehouses Warehouse warehouse = null; if (_shippingSettings.UseWarehouseLocation) { if (product.ManageInventoryMethod == ManageInventoryMethod.ManageStock && product.UseMultipleWarehouses) { var allWarehouses = new List <Warehouse>(); //multiple warehouses supported foreach (var pwi in await _productService.GetAllProductWarehouseInventoryRecordsAsync(product.Id)) { var tmpWarehouse = await GetWarehouseByIdAsync(pwi.WarehouseId); if (tmpWarehouse != null) { allWarehouses.Add(tmpWarehouse); } } warehouse = await GetNearestWarehouseAsync(shippingAddress, allWarehouses); } else { //multiple warehouses are not supported warehouse = await GetWarehouseByIdAsync(product.WarehouseId); } } var warehouseId = warehouse?.Id ?? 0; if (requests.ContainsKey(warehouseId) && !product.ShipSeparately) { //add item to existing request requests[warehouseId].Items.Add(new GetShippingOptionRequest.PackageItem(sci, product)); } else { //create a new request var request = new GetShippingOptionRequest { //store StoreId = storeId }; //customer request.Customer = await _customerService.GetShoppingCartCustomerAsync(cart); //ship to request.ShippingAddress = shippingAddress; //ship from Address originAddress = null; if (warehouse != null) { //warehouse address originAddress = await _addressService.GetAddressByIdAsync(warehouse.AddressId); request.WarehouseFrom = warehouse; } if (originAddress == null) { //no warehouse address. in this case use the default shipping origin originAddress = await _addressService.GetAddressByIdAsync(_shippingSettings.ShippingOriginAddressId); } if (originAddress != null) { request.CountryFrom = await _countryService.GetCountryByAddressAsync(originAddress); request.StateProvinceFrom = await _stateProvinceService.GetStateProvinceByAddressAsync(originAddress); request.ZipPostalCodeFrom = originAddress.ZipPostalCode; request.CountyFrom = originAddress.County; request.CityFrom = originAddress.City; request.AddressFrom = originAddress.Address1; } //whether this product should be shipped separately from other ones if (product.ShipSeparately) { //whether product items should be shipped separately if (_shippingSettings.ShipSeparatelyOneItemEach) { //add item with overridden quantity 1 request.Items.Add(new GetShippingOptionRequest.PackageItem(sci, product, 1)); //create separate requests for all product quantity for (var i = 0; i < sci.Quantity; i++) { separateRequests.Add(request); } } else { //all of product items should be shipped in a single box, so create the single separate request request.Items.Add(new GetShippingOptionRequest.PackageItem(sci, product)); separateRequests.Add(request); } } else { //usual request request.Items.Add(new GetShippingOptionRequest.PackageItem(sci, product)); requests.Add(warehouseId, request); } } } //multiple locations? //currently we just compare warehouses //but we should also consider cases when several warehouses are located in the same address var shippingFromMultipleLocations = requests.Select(x => x.Key).Distinct().Count() > 1; var result = requests.Values.ToList(); result.AddRange(separateRequests); return(result, shippingFromMultipleLocations); }
/// <summary> /// Handle order completed event /// </summary> /// <param name="order">Order</param> /// <returns>A task that represents the asynchronous operation</returns> public async Task HandleOrderCompletedEventAsync(Order order) { //whether marketing automation is enabled if (!_sendinblueSettings.UseMarketingAutomation) { return; } if (order is null) { throw new ArgumentNullException(nameof(order)); } var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId); try { //create API client var client = CreateMarketingAutomationClient(); //first, try to identify current customer await client.IdentifyAsync(new Identify(customer.Email)); //get URL helper var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext); //get products data by order items var itemsData = await(await _orderService.GetOrderItemsAsync(order.Id)).SelectAwait(async item => { var product = await _productService.GetProductByIdAsync(item.ProductId); //try to get product attribute combination var combination = await _productAttributeParser.FindProductAttributeCombinationAsync(product, item.AttributesXml); //get default product picture var picture = await _pictureService.GetProductPictureAsync(product, item.AttributesXml); //get product SEO slug name var seName = await _urlRecordService.GetSeNameAsync(product); //create product data return(new { id = product.Id, name = product.Name, variant_id = combination?.Id ?? product.Id, variant_name = combination?.Sku ?? product.Name, sku = combination?.Sku ?? product.Sku, category = await(await _categoryService.GetProductCategoriesByProductIdAsync(item.ProductId)).AggregateAwaitAsync(",", async(all, pc) => { var res = (await _categoryService.GetCategoryByIdAsync(pc.CategoryId)).Name; res = all == "," ? res : all + ", " + res; return res; }), url = urlHelper.RouteUrl("Product", new { SeName = seName }, _webHelper.GetCurrentRequestProtocol()), image = (await _pictureService.GetPictureUrlAsync(picture)).Url, quantity = item.Quantity, price = item.PriceInclTax, }); }).ToArrayAsync(); var shippingAddress = await _addressService.GetAddressByIdAsync(order.ShippingAddressId ?? 0); var billingAddress = await _addressService.GetAddressByIdAsync(order.BillingAddressId); var shippingAddressData = new { firstname = shippingAddress?.FirstName, lastname = shippingAddress?.LastName, company = shippingAddress?.Company, phone = shippingAddress?.PhoneNumber, address1 = shippingAddress?.Address1, address2 = shippingAddress?.Address2, city = shippingAddress?.City, country = (await _countryService.GetCountryByAddressAsync(shippingAddress))?.Name, state = (await _stateProvinceService.GetStateProvinceByAddressAsync(shippingAddress))?.Name, zipcode = shippingAddress?.ZipPostalCode }; var billingAddressData = new { firstname = billingAddress?.FirstName, lastname = billingAddress?.LastName, company = billingAddress?.Company, phone = billingAddress?.PhoneNumber, address1 = billingAddress?.Address1, address2 = billingAddress?.Address2, city = billingAddress?.City, country = (await _countryService.GetCountryByAddressAsync(billingAddress))?.Name, state = (await _stateProvinceService.GetStateProvinceByAddressAsync(billingAddress))?.Name, zipcode = billingAddress?.ZipPostalCode }; var store = await _storeContext.GetCurrentStoreAsync(); //prepare cart data var cartData = new { id = order.Id, affiliation = customer.AffiliateId > 0 ? customer.AffiliateId.ToString() : store.Name, date = order.PaidDateUtc?.ToString("yyyy-MM-dd"), subtotal = order.OrderSubtotalInclTax, shipping = order.OrderShippingInclTax, total_before_tax = order.OrderSubtotalInclTax + order.OrderShippingInclTax, tax = order.OrderTax, discount = order.OrderDiscount, revenue = order.OrderTotal, url = urlHelper.RouteUrl("OrderDetails", new { orderId = order.Id }, _webHelper.GetCurrentRequestProtocol()), currency = order.CustomerCurrencyCode, //gift_wrapping = string.Empty, //currently we can't get this value items = itemsData, shipping_address = shippingAddressData, billing_address = billingAddressData }; //get shopping cart GUID var shoppingCartGuid = await _genericAttributeService.GetAttributeAsync <Guid?>(order, SendinblueDefaults.ShoppingCartGuidAttribute) ?? Guid.NewGuid(); //create track event object var trackEvent = new TrackEvent(customer.Email, SendinblueDefaults.OrderCompletedEventName, eventData: new { id = $"cart:{shoppingCartGuid}", data = cartData }); //track event client.TrackEvent(trackEvent); //update GUID for the current customer's shopping cart await _genericAttributeService.SaveAttributeAsync <Guid?>(order, SendinblueDefaults.ShoppingCartGuidAttribute, null); } catch (Exception exception) { //log full error await _logger.ErrorAsync($"Sendinblue Marketing Automation error: {exception.Message}.", exception, customer); } }
/// <summary> /// Prepare the order details model /// </summary> /// <param name="order">Order</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the order details model /// </returns> public virtual async Task <OrderDetailsModel> PrepareOrderDetailsModelAsync(Order order) { if (order == null) { throw new ArgumentNullException(nameof(order)); } var model = new OrderDetailsModel { Id = order.Id, CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(order.CreatedOnUtc, DateTimeKind.Utc), OrderStatus = await _localizationService.GetLocalizedEnumAsync(order.OrderStatus), IsReOrderAllowed = _orderSettings.IsReOrderAllowed, IsReturnRequestAllowed = await _orderProcessingService.IsReturnRequestAllowedAsync(order), PdfInvoiceDisabled = _pdfSettings.DisablePdfInvoicesForPendingOrders && order.OrderStatus == OrderStatus.Pending, CustomOrderNumber = order.CustomOrderNumber, //shipping info ShippingStatus = await _localizationService.GetLocalizedEnumAsync(order.ShippingStatus) }; if (order.ShippingStatus != ShippingStatus.ShippingNotRequired) { model.IsShippable = true; model.PickupInStore = order.PickupInStore; if (!order.PickupInStore) { var shippingAddress = await _addressService.GetAddressByIdAsync(order.ShippingAddressId ?? 0); await _addressModelFactory.PrepareAddressModelAsync(model.ShippingAddress, address : shippingAddress, excludeProperties : false, addressSettings : _addressSettings); } else if (order.PickupAddressId.HasValue && await _addressService.GetAddressByIdAsync(order.PickupAddressId.Value) is Address pickupAddress) { model.PickupAddress = new AddressModel { Address1 = pickupAddress.Address1, City = pickupAddress.City, County = pickupAddress.County, StateProvinceName = await _stateProvinceService.GetStateProvinceByAddressAsync(pickupAddress) is StateProvince stateProvince ? await _localizationService.GetLocalizedAsync(stateProvince, entity => entity.Name) : string.Empty, CountryName = await _countryService.GetCountryByAddressAsync(pickupAddress) is Country country ? await _localizationService.GetLocalizedAsync(country, entity => entity.Name) : string.Empty, ZipPostalCode = pickupAddress.ZipPostalCode }; } model.ShippingMethod = order.ShippingMethod; //shipments (only already shipped or ready for pickup) var shipments = (await _shipmentService.GetShipmentsByOrderIdAsync(order.Id, !order.PickupInStore, order.PickupInStore)).OrderBy(x => x.CreatedOnUtc).ToList(); foreach (var shipment in shipments) { var shipmentModel = new OrderDetailsModel.ShipmentBriefModel { Id = shipment.Id, TrackingNumber = shipment.TrackingNumber, }; if (shipment.ShippedDateUtc.HasValue) { shipmentModel.ShippedDate = await _dateTimeHelper.ConvertToUserTimeAsync(shipment.ShippedDateUtc.Value, DateTimeKind.Utc); } if (shipment.ReadyForPickupDateUtc.HasValue) { shipmentModel.ReadyForPickupDate = await _dateTimeHelper.ConvertToUserTimeAsync(shipment.ReadyForPickupDateUtc.Value, DateTimeKind.Utc); } if (shipment.DeliveryDateUtc.HasValue) { shipmentModel.DeliveryDate = await _dateTimeHelper.ConvertToUserTimeAsync(shipment.DeliveryDateUtc.Value, DateTimeKind.Utc); } model.Shipments.Add(shipmentModel); } } var billingAddress = await _addressService.GetAddressByIdAsync(order.BillingAddressId); //billing info await _addressModelFactory.PrepareAddressModelAsync(model.BillingAddress, address : billingAddress, excludeProperties : false, addressSettings : _addressSettings); //VAT number model.VatNumber = order.VatNumber; var languageId = (await _workContext.GetWorkingLanguageAsync()).Id; //payment method var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId); var paymentMethod = await _paymentPluginManager .LoadPluginBySystemNameAsync(order.PaymentMethodSystemName, customer, order.StoreId); model.PaymentMethod = paymentMethod != null ? await _localizationService.GetLocalizedFriendlyNameAsync(paymentMethod, languageId) : order.PaymentMethodSystemName; model.PaymentMethodStatus = await _localizationService.GetLocalizedEnumAsync(order.PaymentStatus); model.CanRePostProcessPayment = await _paymentService.CanRePostProcessPaymentAsync(order); //custom values model.CustomValues = _paymentService.DeserializeCustomValues(order); //order subtotal if (order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax && !_taxSettings.ForceTaxExclusionFromOrderSubtotal) { //including tax //order subtotal var orderSubtotalInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderSubtotalInclTax, order.CurrencyRate); model.OrderSubtotal = await _priceFormatter.FormatPriceAsync(orderSubtotalInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); model.OrderSubtotalValue = orderSubtotalInclTaxInCustomerCurrency; //discount (applied to order subtotal) var orderSubTotalDiscountInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderSubTotalDiscountInclTax, order.CurrencyRate); if (orderSubTotalDiscountInclTaxInCustomerCurrency > decimal.Zero) { model.OrderSubTotalDiscount = await _priceFormatter.FormatPriceAsync(-orderSubTotalDiscountInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); model.OrderSubTotalDiscountValue = orderSubTotalDiscountInclTaxInCustomerCurrency; } } else { //excluding tax //order subtotal var orderSubtotalExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderSubtotalExclTax, order.CurrencyRate); model.OrderSubtotal = await _priceFormatter.FormatPriceAsync(orderSubtotalExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); model.OrderSubtotalValue = orderSubtotalExclTaxInCustomerCurrency; //discount (applied to order subtotal) var orderSubTotalDiscountExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderSubTotalDiscountExclTax, order.CurrencyRate); if (orderSubTotalDiscountExclTaxInCustomerCurrency > decimal.Zero) { model.OrderSubTotalDiscount = await _priceFormatter.FormatPriceAsync(-orderSubTotalDiscountExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); model.OrderSubTotalDiscountValue = orderSubTotalDiscountExclTaxInCustomerCurrency; } } if (order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax) { //including tax //order shipping var orderShippingInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderShippingInclTax, order.CurrencyRate); model.OrderShipping = await _priceFormatter.FormatShippingPriceAsync(orderShippingInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); model.OrderShippingValue = orderShippingInclTaxInCustomerCurrency; //payment method additional fee var paymentMethodAdditionalFeeInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.PaymentMethodAdditionalFeeInclTax, order.CurrencyRate); if (paymentMethodAdditionalFeeInclTaxInCustomerCurrency > decimal.Zero) { model.PaymentMethodAdditionalFee = await _priceFormatter.FormatPaymentMethodAdditionalFeeAsync(paymentMethodAdditionalFeeInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); model.PaymentMethodAdditionalFeeValue = paymentMethodAdditionalFeeInclTaxInCustomerCurrency; } } else { //excluding tax //order shipping var orderShippingExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderShippingExclTax, order.CurrencyRate); model.OrderShipping = await _priceFormatter.FormatShippingPriceAsync(orderShippingExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); model.OrderShippingValue = orderShippingExclTaxInCustomerCurrency; //payment method additional fee var paymentMethodAdditionalFeeExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.PaymentMethodAdditionalFeeExclTax, order.CurrencyRate); if (paymentMethodAdditionalFeeExclTaxInCustomerCurrency > decimal.Zero) { model.PaymentMethodAdditionalFee = await _priceFormatter.FormatPaymentMethodAdditionalFeeAsync(paymentMethodAdditionalFeeExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); model.PaymentMethodAdditionalFeeValue = paymentMethodAdditionalFeeExclTaxInCustomerCurrency; } } //tax var displayTax = true; var displayTaxRates = true; if (_taxSettings.HideTaxInOrderSummary && order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax) { displayTax = false; displayTaxRates = false; } else { if (order.OrderTax == 0 && _taxSettings.HideZeroTax) { displayTax = false; displayTaxRates = false; } else { var taxRates = _orderService.ParseTaxRates(order, order.TaxRates); displayTaxRates = _taxSettings.DisplayTaxRates && taxRates.Any(); displayTax = !displayTaxRates; var orderTaxInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderTax, order.CurrencyRate); model.Tax = await _priceFormatter.FormatPriceAsync(orderTaxInCustomerCurrency, true, order.CustomerCurrencyCode, false, languageId); foreach (var tr in taxRates) { model.TaxRates.Add(new OrderDetailsModel.TaxRate { Rate = _priceFormatter.FormatTaxRate(tr.Key), Value = await _priceFormatter.FormatPriceAsync(_currencyService.ConvertCurrency(tr.Value, order.CurrencyRate), true, order.CustomerCurrencyCode, false, languageId), }); } } } model.DisplayTaxRates = displayTaxRates; model.DisplayTax = displayTax; model.DisplayTaxShippingInfo = _catalogSettings.DisplayTaxShippingInfoOrderDetailsPage; model.PricesIncludeTax = order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax; //discount (applied to order total) var orderDiscountInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderDiscount, order.CurrencyRate); if (orderDiscountInCustomerCurrency > decimal.Zero) { model.OrderTotalDiscount = await _priceFormatter.FormatPriceAsync(-orderDiscountInCustomerCurrency, true, order.CustomerCurrencyCode, false, languageId); model.OrderTotalDiscountValue = orderDiscountInCustomerCurrency; } //gift cards foreach (var gcuh in await _giftCardService.GetGiftCardUsageHistoryAsync(order)) { model.GiftCards.Add(new OrderDetailsModel.GiftCard { CouponCode = (await _giftCardService.GetGiftCardByIdAsync(gcuh.GiftCardId)).GiftCardCouponCode, Amount = await _priceFormatter.FormatPriceAsync(-(_currencyService.ConvertCurrency(gcuh.UsedValue, order.CurrencyRate)), true, order.CustomerCurrencyCode, false, languageId), }); } //reward points if (order.RedeemedRewardPointsEntryId.HasValue && await _rewardPointService.GetRewardPointsHistoryEntryByIdAsync(order.RedeemedRewardPointsEntryId.Value) is RewardPointsHistory redeemedRewardPointsEntry) { model.RedeemedRewardPoints = -redeemedRewardPointsEntry.Points; model.RedeemedRewardPointsAmount = await _priceFormatter.FormatPriceAsync(-(_currencyService.ConvertCurrency(redeemedRewardPointsEntry.UsedAmount, order.CurrencyRate)), true, order.CustomerCurrencyCode, false, languageId); } //total var orderTotalInCustomerCurrency = _currencyService.ConvertCurrency(order.OrderTotal, order.CurrencyRate); model.OrderTotal = await _priceFormatter.FormatPriceAsync(orderTotalInCustomerCurrency, true, order.CustomerCurrencyCode, false, languageId); model.OrderTotalValue = orderTotalInCustomerCurrency; //checkout attributes model.CheckoutAttributeInfo = order.CheckoutAttributeDescription; //order notes foreach (var orderNote in (await _orderService.GetOrderNotesByOrderIdAsync(order.Id, true)) .OrderByDescending(on => on.CreatedOnUtc) .ToList()) { model.OrderNotes.Add(new OrderDetailsModel.OrderNote { Id = orderNote.Id, HasDownload = orderNote.DownloadId > 0, Note = _orderService.FormatOrderNoteText(orderNote), CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(orderNote.CreatedOnUtc, DateTimeKind.Utc) }); } //purchased products model.ShowSku = _catalogSettings.ShowSkuOnProductDetailsPage; model.ShowVendorName = _vendorSettings.ShowVendorOnOrderDetailsPage; var orderItems = await _orderService.GetOrderItemsAsync(order.Id); foreach (var orderItem in orderItems) { var product = await _productService.GetProductByIdAsync(orderItem.ProductId); var orderItemModel = new OrderDetailsModel.OrderItemModel { Id = orderItem.Id, OrderItemGuid = orderItem.OrderItemGuid, Sku = await _productService.FormatSkuAsync(product, orderItem.AttributesXml), VendorName = (await _vendorService.GetVendorByIdAsync(product.VendorId))?.Name ?? string.Empty, ProductId = product.Id, ProductName = await _localizationService.GetLocalizedAsync(product, x => x.Name), ProductSeName = await _urlRecordService.GetSeNameAsync(product), Quantity = orderItem.Quantity, AttributeInfo = orderItem.AttributeDescription, }; //rental info if (product.IsRental) { var rentalStartDate = orderItem.RentalStartDateUtc.HasValue ? _productService.FormatRentalDate(product, orderItem.RentalStartDateUtc.Value) : ""; var rentalEndDate = orderItem.RentalEndDateUtc.HasValue ? _productService.FormatRentalDate(product, orderItem.RentalEndDateUtc.Value) : ""; orderItemModel.RentalInfo = string.Format(await _localizationService.GetResourceAsync("Order.Rental.FormattedDate"), rentalStartDate, rentalEndDate); } model.Items.Add(orderItemModel); //unit price, subtotal if (order.CustomerTaxDisplayType == TaxDisplayType.IncludingTax) { //including tax var unitPriceInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.UnitPriceInclTax, order.CurrencyRate); orderItemModel.UnitPrice = await _priceFormatter.FormatPriceAsync(unitPriceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); orderItemModel.UnitPriceValue = unitPriceInclTaxInCustomerCurrency; var priceInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.PriceInclTax, order.CurrencyRate); orderItemModel.SubTotal = await _priceFormatter.FormatPriceAsync(priceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, true); orderItemModel.SubTotalValue = priceInclTaxInCustomerCurrency; } else { //excluding tax var unitPriceExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.UnitPriceExclTax, order.CurrencyRate); orderItemModel.UnitPrice = await _priceFormatter.FormatPriceAsync(unitPriceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); orderItemModel.UnitPriceValue = unitPriceExclTaxInCustomerCurrency; var priceExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.PriceExclTax, order.CurrencyRate); orderItemModel.SubTotal = await _priceFormatter.FormatPriceAsync(priceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, languageId, false); orderItemModel.SubTotalValue = priceExclTaxInCustomerCurrency; } //downloadable products if (await _orderService.IsDownloadAllowedAsync(orderItem)) { orderItemModel.DownloadId = product.DownloadId; } if (await _orderService.IsLicenseDownloadAllowedAsync(orderItem)) { orderItemModel.LicenseId = orderItem.LicenseDownloadId ?? 0; } } return(model); }
/// <returns>A task that represents the asynchronous operation</returns> protected virtual async Task <IList <ShipStationServiceRate> > GetRatesAsync(GetShippingOptionRequest getShippingOptionRequest, string carrierCode) { var usedWeight = await _measureService.GetMeasureWeightBySystemKeywordAsync(Weight.Units); if (usedWeight == null) { throw new NopException("ShipStatio shipping service. Could not load \"{0}\" measure weight", Weight.Units); } var usedMeasureDimension = await _measureService.GetMeasureDimensionBySystemKeywordAsync(Dimensions.Units); if (usedMeasureDimension == null) { throw new NopException("ShipStatio shipping service. Could not load \"{0}\" measure dimension", Dimensions.Units); } var weight = Convert.ToInt32(Math.Ceiling(await _measureService.ConvertFromPrimaryMeasureWeightAsync(await _shippingService.GetTotalWeightAsync(getShippingOptionRequest), usedWeight))); var postData = new RatesRequest { CarrierCode = carrierCode, FromPostalCode = getShippingOptionRequest.ZipPostalCodeFrom ?? getShippingOptionRequest.ShippingAddress.ZipPostalCode, ToState = (await _stateProvinceService.GetStateProvinceByAddressAsync(getShippingOptionRequest.ShippingAddress)).Abbreviation, ToCountry = (await _countryService.GetCountryByAddressAsync(getShippingOptionRequest.ShippingAddress)).TwoLetterIsoCode, ToPostalCode = getShippingOptionRequest.ShippingAddress.ZipPostalCode, ToCity = getShippingOptionRequest.ShippingAddress.City, Weight = new Weight { Value = weight } }; if (_shipStationSettings.PassDimensions) { int length, height, width; decimal lengthTmp, widthTmp, heightTmp; switch (_shipStationSettings.PackingType) { case PackingType.PackByDimensions: (widthTmp, lengthTmp, heightTmp) = await _shippingService.GetDimensionsAsync(getShippingOptionRequest.Items); length = await ConvertFromPrimaryMeasureDimensionAsync(lengthTmp, usedMeasureDimension); height = await ConvertFromPrimaryMeasureDimensionAsync(heightTmp, usedMeasureDimension); width = await ConvertFromPrimaryMeasureDimensionAsync(widthTmp, usedMeasureDimension); break; case PackingType.PackByVolume: if (getShippingOptionRequest.Items.Count == 1 && getShippingOptionRequest.Items[0].GetQuantity() == 1) { var sci = getShippingOptionRequest.Items[0].ShoppingCartItem; var product = getShippingOptionRequest.Items[0].Product; (widthTmp, lengthTmp, heightTmp) = await _shippingService.GetDimensionsAsync(new List <GetShippingOptionRequest.PackageItem> { new GetShippingOptionRequest.PackageItem(sci, product, 1) }); length = await ConvertFromPrimaryMeasureDimensionAsync(lengthTmp, usedMeasureDimension); height = await ConvertFromPrimaryMeasureDimensionAsync(lengthTmp, usedMeasureDimension); width = await ConvertFromPrimaryMeasureDimensionAsync(widthTmp, usedMeasureDimension); } else { decimal totalVolume = 0; foreach (var item in getShippingOptionRequest.Items) { var sci = item.ShoppingCartItem; var product = item.Product; (widthTmp, lengthTmp, heightTmp) = await _shippingService.GetDimensionsAsync(new List <GetShippingOptionRequest.PackageItem> { new GetShippingOptionRequest.PackageItem(sci, product, 1) }); var productLength = await ConvertFromPrimaryMeasureDimensionAsync(lengthTmp, usedMeasureDimension); var productHeight = await ConvertFromPrimaryMeasureDimensionAsync(heightTmp, usedMeasureDimension); var productWidth = await ConvertFromPrimaryMeasureDimensionAsync(widthTmp, usedMeasureDimension); totalVolume += item.GetQuantity() * (productHeight * productWidth * productLength); } int dimension; if (totalVolume == 0) { dimension = 0; } else { // cubic inches var packageVolume = _shipStationSettings.PackingPackageVolume; if (packageVolume <= 0) { packageVolume = 5184; } // cube root (floor) dimension = Convert.ToInt32(Math.Floor(Math.Pow(Convert.ToDouble(packageVolume), 1.0 / 3.0))); } length = width = height = dimension; } break; default: length = height = width = 1; break; } if (length < 1) { length = 1; } if (height < 1) { height = 1; } if (width < 1) { width = 1; } postData.Dimensions = new Dimensions { Length = length, Height = height, Width = width }; } using var client = new WebClient { Credentials = new NetworkCredential(_shipStationSettings.ApiKey, _shipStationSettings.ApiSecret) }; client.Headers.Add("Content-Type", CONTENT_TYPE); var data = client.UploadString($"{API_URL}{LIST_RATES_CMD}", JsonConvert.SerializeObject(postData)); return((await TryGetError(data)) ? new List <ShipStationServiceRate>() : JsonConvert.DeserializeObject <List <ShipStationServiceRate> >(data)); }
/// <summary> /// Create request details to get shipping rates /// </summary> /// <param name="shippingOptionRequest">Shipping option request</param> /// <param name="saturdayDelivery">Whether to get rates for Saturday Delivery</param> /// <returns>Rate request details</returns> private async Task <UPSRate.RateRequest> CreateRateRequestAsync(GetShippingOptionRequest shippingOptionRequest, bool saturdayDelivery = false) { //set request details var request = new UPSRate.RateRequest { Request = new UPSRate.RequestType { //used to define the request type //Shop - the server validates the shipment, and returns rates for all UPS products from the ShipFrom to the ShipTo addresses RequestOption = new[] { "Shop" } } }; //prepare addresses details var stateCodeTo = (await _stateProvinceService.GetStateProvinceByAddressAsync(shippingOptionRequest.ShippingAddress))?.Abbreviation; var stateCodeFrom = shippingOptionRequest.StateProvinceFrom?.Abbreviation; var countryCodeFrom = (shippingOptionRequest.CountryFrom ?? (await _countryService.GetAllCountriesAsync()).FirstOrDefault())?.TwoLetterIsoCode ?? string.Empty; var addressFromDetails = new UPSRate.ShipAddressType { AddressLine = new[] { shippingOptionRequest.AddressFrom }, City = shippingOptionRequest.CityFrom, StateProvinceCode = stateCodeFrom, CountryCode = countryCodeFrom, PostalCode = shippingOptionRequest.ZipPostalCodeFrom }; var addressToDetails = new UPSRate.ShipToAddressType { AddressLine = new[] { shippingOptionRequest.ShippingAddress.Address1, shippingOptionRequest.ShippingAddress.Address2 }, City = shippingOptionRequest.ShippingAddress.City, StateProvinceCode = stateCodeTo, CountryCode = (await _countryService.GetCountryByAddressAsync(shippingOptionRequest.ShippingAddress))?.TwoLetterIsoCode, PostalCode = shippingOptionRequest.ShippingAddress.ZipPostalCode, ResidentialAddressIndicator = string.Empty }; //set shipment details request.Shipment = new UPSRate.ShipmentType { Shipper = new UPSRate.ShipperType { ShipperNumber = _upsSettings.AccountNumber, Address = addressFromDetails }, ShipFrom = new UPSRate.ShipFromType { Address = addressFromDetails }, ShipTo = new UPSRate.ShipToType { Address = addressToDetails } }; //set pickup options and customer classification for US shipments if (countryCodeFrom.Equals("US", StringComparison.InvariantCultureIgnoreCase)) { request.PickupType = new UPSRate.CodeDescriptionType { Code = GetUpsCode(_upsSettings.PickupType) }; request.CustomerClassification = new UPSRate.CodeDescriptionType { Code = GetUpsCode(_upsSettings.CustomerClassification) }; } //set negotiated rates details if (!string.IsNullOrEmpty(_upsSettings.AccountNumber) && !string.IsNullOrEmpty(stateCodeFrom) && !string.IsNullOrEmpty(stateCodeTo)) { request.Shipment.ShipmentRatingOptions = new UPSRate.ShipmentRatingOptionsType { NegotiatedRatesIndicator = string.Empty, UserLevelDiscountIndicator = string.Empty }; } //set Saturday delivery details if (saturdayDelivery) { request.Shipment.ShipmentServiceOptions = new UPSRate.ShipmentServiceOptionsType { SaturdayDeliveryIndicator = string.Empty }; } //set packages details request.Shipment.Package = _upsSettings.PackingType switch { PackingType.PackByOneItemPerPackage => (await GetPackagesForOneItemPerPackageAsync(shippingOptionRequest)).ToArray(), PackingType.PackByVolume => (await GetPackagesByCubicRootAsync(shippingOptionRequest)).ToArray(), _ => (await GetPackagesByDimensionsAsync(shippingOptionRequest)).ToArray() }; return(request); }
/// <summary> /// Prepare address model /// </summary> /// <param name="model">Address model</param> /// <param name="address">Address entity</param> /// <param name="excludeProperties">Whether to exclude populating of model properties from the entity</param> /// <param name="addressSettings">Address settings</param> /// <param name="loadCountries">Countries loading function; pass null if countries do not need to load</param> /// <param name="prePopulateWithCustomerFields">Whether to populate model properties with the customer fields (used with the customer entity)</param> /// <param name="customer">Customer entity; required if prePopulateWithCustomerFields is true</param> /// <param name="overrideAttributesXml">Overridden address attributes in XML format; pass null to use CustomAttributes of the address entity</param> /// <returns>A task that represents the asynchronous operation</returns> public virtual async Task PrepareAddressModelAsync(AddressModel model, Address address, bool excludeProperties, AddressSettings addressSettings, Func <Task <IList <Country> > > loadCountries = null, bool prePopulateWithCustomerFields = false, Customer customer = null, string overrideAttributesXml = "") { if (model == null) { throw new ArgumentNullException(nameof(model)); } if (addressSettings == null) { throw new ArgumentNullException(nameof(addressSettings)); } if (!excludeProperties && address != null) { model.Id = address.Id; model.FirstName = address.FirstName; model.LastName = address.LastName; model.Email = address.Email; model.Company = address.Company; model.CountryId = address.CountryId; model.CountryName = await _countryService.GetCountryByAddressAsync(address) is Country country ? await _localizationService.GetLocalizedAsync(country, x => x.Name) : null; model.StateProvinceId = address.StateProvinceId; model.StateProvinceName = await _stateProvinceService.GetStateProvinceByAddressAsync(address) is StateProvince stateProvince ? await _localizationService.GetLocalizedAsync(stateProvince, x => x.Name) : null; model.County = address.County; model.City = address.City; model.Address1 = address.Address1; model.Address2 = address.Address2; model.ZipPostalCode = address.ZipPostalCode; model.PhoneNumber = address.PhoneNumber; model.FaxNumber = address.FaxNumber; } if (address == null && prePopulateWithCustomerFields) { if (customer == null) { throw new Exception("Customer cannot be null when prepopulating an address"); } model.Email = customer.Email; model.FirstName = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.FirstNameAttribute); model.LastName = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.LastNameAttribute); model.Company = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.CompanyAttribute); model.Address1 = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.StreetAddressAttribute); model.Address2 = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.StreetAddress2Attribute); model.ZipPostalCode = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.ZipPostalCodeAttribute); model.City = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.CityAttribute); model.County = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.CountyAttribute); model.PhoneNumber = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.PhoneAttribute); model.FaxNumber = await _genericAttributeService.GetAttributeAsync <string>(customer, NopCustomerDefaults.FaxAttribute); } //countries and states if (addressSettings.CountryEnabled && loadCountries != null) { var countries = await loadCountries(); if (_addressSettings.PreselectCountryIfOnlyOne && countries.Count == 1) { model.CountryId = countries[0].Id; } else { model.AvailableCountries.Add(new SelectListItem { Text = await _localizationService.GetResourceAsync("Address.SelectCountry"), Value = "0" }); } foreach (var c in countries) { model.AvailableCountries.Add(new SelectListItem { Text = await _localizationService.GetLocalizedAsync(c, x => x.Name), Value = c.Id.ToString(), Selected = c.Id == model.CountryId }); } if (addressSettings.StateProvinceEnabled) { var languageId = (await _workContext.GetWorkingLanguageAsync()).Id; var states = (await _stateProvinceService .GetStateProvincesByCountryIdAsync(model.CountryId ?? 0, languageId)) .ToList(); if (states.Any()) { model.AvailableStates.Add(new SelectListItem { Text = await _localizationService.GetResourceAsync("Address.SelectState"), Value = "0" }); foreach (var s in states) { model.AvailableStates.Add(new SelectListItem { Text = await _localizationService.GetLocalizedAsync(s, x => x.Name), Value = s.Id.ToString(), Selected = (s.Id == model.StateProvinceId) }); } } else { var anyCountrySelected = model.AvailableCountries.Any(x => x.Selected); model.AvailableStates.Add(new SelectListItem { Text = await _localizationService.GetResourceAsync(anyCountrySelected ? "Address.Other" : "Address.SelectState"), Value = "0" }); } } } //form fields model.CompanyEnabled = addressSettings.CompanyEnabled; model.CompanyRequired = addressSettings.CompanyRequired; model.StreetAddressEnabled = addressSettings.StreetAddressEnabled; model.StreetAddressRequired = addressSettings.StreetAddressRequired; model.StreetAddress2Enabled = addressSettings.StreetAddress2Enabled; model.StreetAddress2Required = addressSettings.StreetAddress2Required; model.ZipPostalCodeEnabled = addressSettings.ZipPostalCodeEnabled; model.ZipPostalCodeRequired = addressSettings.ZipPostalCodeRequired; model.CityEnabled = addressSettings.CityEnabled; model.CityRequired = addressSettings.CityRequired; model.CountyEnabled = addressSettings.CountyEnabled; model.CountyRequired = addressSettings.CountyRequired; model.CountryEnabled = addressSettings.CountryEnabled; model.StateProvinceEnabled = addressSettings.StateProvinceEnabled; model.PhoneEnabled = addressSettings.PhoneEnabled; model.PhoneRequired = addressSettings.PhoneRequired; model.FaxEnabled = addressSettings.FaxEnabled; model.FaxRequired = addressSettings.FaxRequired; //customer attribute services if (_addressAttributeService != null && _addressAttributeParser != null) { await PrepareCustomAddressAttributesAsync(model, address, overrideAttributesXml); } if (_addressAttributeFormatter != null && address != null) { model.FormattedCustomAddressAttributes = await _addressAttributeFormatter.FormatAttributesAsync(address.CustomAttributes); } }
private async Task <AuthenticationTokenResponse> FindStatusCallAsync() { var storeScope = await _storeContext.GetActiveStoreScopeConfigurationAsync(); var paySynchronyPaymentSettings = await _settingService.LoadSettingAsync <SynchronyPaymentSettings>(storeScope); var cart = await _shoppingCartService.GetShoppingCartAsync( await _workContext.GetCurrentCustomerAsync(), ShoppingCartType.ShoppingCart, (await _storeContext.GetCurrentStoreAsync()).Id); var orderTotalsModel = await _shoppingCartModelFactory.PrepareOrderTotalsModelAsync(cart, false); string authorizationRegionStatusURL = paySynchronyPaymentSettings.Integration ? SynchronyPaymentConstants.DemoInquiryEndpoint : SynchronyPaymentConstants.LiveInquiryEndpoint; var merchantId = paySynchronyPaymentSettings.MerchantId; var merchantPassword = paySynchronyPaymentSettings.MerchantPassword; var Integration = paySynchronyPaymentSettings.Integration; var token = HttpContext.Session.GetString("token").Replace("\"", ""); var transactionAmount = Convert.ToDecimal(orderTotalsModel.OrderTotal.Replace("$", "")); var model = new AuthenticationTokenResponse(); // take reference from below link - Answer 1 by Seema As // https://stackoverflow.com/questions/39190018/how-to-get-object-using-httpclient-with-response-ok-in-web-api var response = new HttpResponseMessage(); using (HttpClient client = new HttpClient()) { client.BaseAddress = new Uri(authorizationRegionStatusURL); client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json"); client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0"); ServicePointManager.Expect100Continue = true; var requestBody = new { merchantNumber = merchantId, password = merchantPassword, userToken = token }; string json = JsonSerializer.Serialize(requestBody); if (_synchronyPaymentSettings.IsDebugMode) { await _logger.InsertLogAsync(Core.Domain.Logging.LogLevel.Debug, $"FindStatusCallAsync request - {requestBody.ToString()}"); } var content = new StringContent(json.ToString(), Encoding.UTF8, "application/json"); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; response = await client.PostAsync(authorizationRegionStatusURL, content); } var authResponseJsonAsString = await response.Content.ReadAsStringAsync(); if (_synchronyPaymentSettings.IsDebugMode) { await _logger.InsertLogAsync(Core.Domain.Logging.LogLevel.Debug, $"FindStatusCallAsync response - {authResponseJsonAsString}"); } if (authResponseJsonAsString.Contains("Unauthorized")) { await _logger.ErrorAsync($"Payments.Synchrony: Failed authenticating - {authResponseJsonAsString}"); throw new HttpRequestException("There was an error, please select another payment method."); } var authResponse = JsonSerializer.Deserialize <AuthenticationTokenResponse>( authResponseJsonAsString ); var customer = await _workContext.GetCurrentCustomerAsync(); var billingAddress = await _addressService.GetAddressByIdAsync(customer.BillingAddressId.Value); model.Integration = Integration; model.MerchantId = merchantId; model.clientToken = token; model.transactionId = authResponse.transactionId; model.responseCode = authResponse.responseCode; model.responseDesc = authResponse.responseDesc; model.ZipCode = billingAddress.ZipPostalCode; model.State = (await _stateProvinceService.GetStateProvinceByAddressAsync( billingAddress )).Abbreviation; model.FirstName = billingAddress.FirstName; model.City = billingAddress.City; model.Address1 = billingAddress.Address1; model.LastName = billingAddress.LastName; model.StatusCode = authResponse.StatusCode; model.AccountNumber = authResponse.AccountNumber; model.StatusMessage = authResponse.StatusMessage; model.TransactionAmount = transactionAmount.ToString(); model.ClientTransactionID = authResponse.ClientTransactionID; model.TransactionDate = authResponse.TransactionDate; model.TransactionDescription = authResponse.TransactionDescription; model.AuthCode = authResponse.AuthCode; model.PromoCode = authResponse.PromoCode; model.PostbackId = authResponse.PostbackId; return(model); }
public async Task <IList <YahooHeaderRow> > GetYahooHeaderRowsAsync(Order order) { var result = new List <YahooHeaderRow>(); var orderItems = await _customOrderService.GetOrderItemsAsync(order.Id); if (!orderItems.Any()) { return(result); } var splitItems = orderItems.SplitByPickupAndShipping(); var address = await _addressService.GetAddressByIdAsync(order.BillingAddressId); var stateAbbv = (await _stateProvinceService.GetStateProvinceByAddressAsync(address)).Abbreviation; var country = (await _countryService.GetCountryByAddressAsync(address)).Name; var cardName = _encryptionService.DecryptText(order.CardName, _securitySettings.EncryptionKey); var cardNumber = _encryptionService.DecryptText(order.CardNumber, _securitySettings.EncryptionKey); var cardMonth = _encryptionService.DecryptText(order.CardExpirationMonth, _securitySettings.EncryptionKey); var cardYear = _encryptionService.DecryptText(order.CardExpirationYear, _securitySettings.EncryptionKey); var cardCvv2 = _encryptionService.DecryptText(order.CardCvv2, _securitySettings.EncryptionKey); var customValues = _paymentService.DeserializeCustomValues(order); var ccRefNo = customValues != null? customValues.Where(cv => cv.Key == "CC_REFNO") .Select(cv => cv.Value?.ToString()) .FirstOrDefault() : null; var pickupItems = splitItems.pickupItems; if (pickupItems.Any()) { decimal backendOrderTax, backendOrderTotal; CalculateValues(pickupItems, out backendOrderTax, out backendOrderTotal); var giftCard = await CalculateGiftCardAsync(order, backendOrderTotal); result.Add(new YahooHeaderRow( _settings.OrderIdPrefix, order, address, stateAbbv, country, cardName, cardNumber, cardMonth, cardYear, cardCvv2, await _priceCalculationService.RoundPriceAsync(backendOrderTax), await _priceCalculationService.RoundPriceAsync(backendOrderTotal), giftCard.GiftCardCode, giftCard.GiftCardUsage, ccRefNo )); } var shippingItems = splitItems.shippingItems; if (shippingItems.Any()) { decimal homeDeliveryCost = 0; decimal shippingCost = 0; homeDeliveryCost = await _homeDeliveryCostService.GetHomeDeliveryCostAsync(shippingItems); shippingCost = order.OrderShippingExclTax - homeDeliveryCost; decimal backendOrderTax, backendOrderTotal; CalculateValues(shippingItems, out backendOrderTax, out backendOrderTotal); decimal shippingTax = order.OrderShippingInclTax - order.OrderShippingExclTax; backendOrderTax += shippingTax; backendOrderTotal += order.OrderShippingInclTax; var giftCard = await CalculateGiftCardAsync(order, backendOrderTotal); result.Add(new YahooHeaderRowShipping( _settings.OrderIdPrefix, order, address, stateAbbv, country, cardName, cardNumber, cardMonth, cardYear, cardCvv2, await _priceCalculationService.RoundPriceAsync(backendOrderTax), await _priceCalculationService.RoundPriceAsync(shippingCost), await _priceCalculationService.RoundPriceAsync(homeDeliveryCost), await _priceCalculationService.RoundPriceAsync(backendOrderTotal), giftCard.GiftCardCode, giftCard.GiftCardUsage, ccRefNo )); } return(result); }