public void UpgradeOrders() { List <long> orderToUpgradeIdList = null; List <long> orderToResetUpgradeIdList = null; using (var db = _dbFactory.GetRWDb()) { var orders = db.Orders.GetAll().Where(o => o.OrderStatus == OrderStatusEnumEx.Unshipped).ToList(); var orderIdList = orders .Where(o => !ShippingUtils.IsInternational(o.ShippingCountry) && o.SourceShippingService == ShippingUtils.StandardServiceName) .Select(o => o.Id) .ToList(); var shippings = db.OrderShippingInfos.GetAll().Where(sh => orderIdList.Contains(sh.OrderId) && sh.IsActive && sh.AvgDeliveryDays >= 1.99M).ToList(); orderToUpgradeIdList = shippings.Select(sh => sh.OrderId).Distinct().ToList(); var orderItems = db.OrderItemSources.GetAll().Where(oi => orderToUpgradeIdList.Contains(oi.OrderId)).ToList(); orderToUpgradeIdList = orderToUpgradeIdList .Where(o => orderItems.Where(oi => oi.OrderId == o).Sum(oi => oi.ItemPrice) > 10) .ToList(); var ordersToUpgrade = orders.Where(o => orderToUpgradeIdList.Contains(o.Id)).ToList(); _log.Info(String.Join(", ", ordersToUpgrade.Select(o => o.AmazonIdentifier).ToList())); var zipList = ordersToUpgrade.Select(o => o.ShippingZip).ToList(); _log.Info(String.Join(", ", zipList)); } UpgradeOrderList(orderToUpgradeIdList); }
public static IList <MessageString> ValidateQuickReturnLabel(IUnitOfWork db, string orderNumber) { var messages = new List <MessageString>(); var order = db.Orders.GetAll().FirstOrDefault(o => o.AmazonIdentifier == orderNumber); if (ShippingUtils.IsInternational(order.ShippingCountry)) { messages.Add(MessageString.Warning("The International return label cannot be generated automatically")); } var existReturnLabel = db.MailLabelInfos.GetAllAsDto() .Where(m => m.OrderId == order.Id && m.MailReasonId == (int)MailLabelReasonCodes.ReturnLabelReasonCode).ToList(); if (existReturnLabel.Any()) { messages.Add(MessageString.Warning("Order already has return label")); } return(messages); }
public CheckResult Check(DTOMarketOrder order) { CheckResult result = new CheckResult() { IsSuccess = false }; var serviceType = order.InitialServiceType; if ((ShippingUtils.IsServiceTwoDays(serviceType) || ShippingUtils.IsServiceNextDay(serviceType)) && ShippingUtils.IsInternational(order.ShippingCountry)) { return(new CheckResult() { IsSuccess = true }); } return(result); }
public CheckResult Check(IUnitOfWork db, DTOOrder order, IList <ListingOrderDTO> orderItems) { var min = 1.99M; if (ShippingUtils.IsInternational(order.FinalShippingCountry) || order.InitialServiceType != ShippingUtils.StandardServiceName || orderItems.Sum(i => i.ItemPrice) <= 10) { return(new CheckResult() { IsSuccess = false }); } var avgDeliveryDays = GetAvgDeliveryInfo(db, order); if (avgDeliveryDays != null && avgDeliveryDays.AverageFirstClassDeliveryDays.HasValue && avgDeliveryDays.AverageFirstClassDeliveryDays.Value >= min) { _log.Info("Zip=" + avgDeliveryDays.Zip + ", Avg FC Days=" + avgDeliveryDays.AverageFirstClassDeliveryDays + ", min=" + min); order.UpgradeLevel = 1; return(new CheckResult() { IsSuccess = true }); } return(new CheckResult() { IsSuccess = false }); }
public AddressDTO ComposeAddressDto() { var address = new AddressDTO(); //NOTE: Original address dosn't came after submit address.FullName = ManuallyPersonName; address.ManuallyAddress1 = ManuallyShippingAddress1; address.ManuallyAddress2 = ManuallyShippingAddress2; address.ManuallyCity = ManuallyShippingCity; address.ManuallyCountry = ManuallyShippingCountry; address.ManuallyState = !ShippingUtils.IsInternational(address.ManuallyCountry) // == "US" ? ManuallyShippingUSState : ManuallyShippingState; address.ManuallyZip = ManuallyShippingZip; address.ManuallyZipAddon = ManuallyShippingZipAddon; address.ManuallyPhone = ManuallyShippingPhone; address.IsManuallyUpdated = true; return(address); }
public CheckResult Check(IUnitOfWork db, long orderId, IList <ListingOrderDTO> orderItems, IList <OrderShippingInfoDTO> shippings, DTOMarketOrder marketOrder) { if (!orderItems.Any() || !shippings.Any()) { return new CheckResult() { IsSuccess = false } } ; if (marketOrder.UpgradeLevel > 0) { return new CheckResult() { IsSuccess = false } } ; if (marketOrder.Market == (int)MarketType.Groupon) { return new CheckResult() { IsSuccess = false } } ; CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); culture.NumberFormat.CurrencyNegativePattern = 1; decimal paidShppingCost = orderItems.Sum(i => i.ShippingPrice); string currency = orderItems.First().ShippingPriceCurrency; paidShppingCost = PriceHelper.RougeConvertToUSD(currency, paidShppingCost); if (marketOrder.OrderType == (int)OrderTypeEnum.Prime) { paidShppingCost += orderItems.Sum(oi => AmazonPrimeHelper.GetShippingAmount(oi.Weight)); } decimal?actualShippingsCost = null; if (shippings != null && shippings.Any(sh => sh.IsActive)) { actualShippingsCost = shippings.Where(sh => sh.IsActive && sh.ShippingMethodId != ShippingUtils.FedexSmartPost).Sum(sh => sh.StampsShippingCost ?? 0); } _log.Info("CheckIsExceededShippingCost: paid=" + paidShppingCost + " < actual=" + actualShippingsCost); if (shippings != null) { //"Excessive shipping cost. Because priority flat went up I get lots of “excesive” in cases like. We need to ignore those cases…" var activeShipping = shippings.FirstOrDefault(sh => sh.IsActive); if (activeShipping != null && activeShipping.ShippingMethod != null && activeShipping.ShippingMethod.Id == ShippingUtils.PriorityFlatShippingMethodId) { return new CheckResult() { IsSuccess = false } } ; } #region New Checking //price/1.17-shipping price-product cost-2 > -exc if (actualShippingsCost != null) { decimal totalThreashold = 0; decimal totalCost = 0; bool allHaveCost = true; foreach (var item in orderItems) { decimal?styleThreashold = null; if (item.StyleId.HasValue) { var featureValue = db.StyleFeatureTextValues.GetFeatureValueByStyleIdByFeatureId( item.StyleId.Value, StyleFeatureHelper.EXCESSIVE_SHIPMENT); if (featureValue != null && !String.IsNullOrEmpty(featureValue.Value)) { styleThreashold = StringHelper.TryGetDecimal(featureValue.Value); } var cost = db.StyleItemCaches.GetAllAsDto().Select(i => new { i.Id, i.Cost }).FirstOrDefault(i => i.Id == item.StyleItemId)?.Cost; if (cost.HasValue) { totalCost += cost.Value * item.QuantityOrdered; } else { allHaveCost = false; } } if (styleThreashold.HasValue) { totalThreashold += styleThreashold.Value * item.QuantityOrdered; } } if (allHaveCost) { var totalPaid = PriceHelper.RougeConvertToUSD(currency, orderItems.Sum(i => i.ShippingPrice + i.ItemPrice)); //Please ignore income disparity<1 like 180-111-825-1659 / 381-205-041-7263 if (totalThreashold < 1) { totalThreashold = 1; } var isValid = totalPaid / 1.17M - actualShippingsCost - totalCost - 2 > -totalThreashold; if (!isValid) { var excpectIncome = totalPaid / 1.17M - actualShippingsCost.Value - totalCost - 2; _log.Info(String.Format("Added Income disparity, income: {0}, totalPaid: {1}, actualShippingCost: {2}, totalCost: {3}", excpectIncome.ToString("C", culture), totalPaid, actualShippingsCost, totalCost)); var message = String.Format("Income disparity, income: {0}", excpectIncome.ToString("C", culture)); db.OrderComments.Add(new OrderComment() { OrderId = orderId, Message = message, Type = (int)CommentType.System, CreateDate = _time.GetAppNowTime(), }); db.Commit(); return(new CheckResult() { IsSuccess = true }); } } } #endregion #region Old Checking //TASK: When order has 2 robes, and they sent as 2 First class (like 102-1792536-3635439) don’t show Excess ship. cost if (shippings.Where(sh => sh.IsActive).All(sh => sh.ShippingMethodId == ShippingUtils.AmazonFirstClassShippingMethodId || sh.ShippingMethodId == ShippingUtils.FirstClassShippingMethodId || sh.ShippingMethodId == ShippingUtils.DhlEComSMParcelGroundShippingMethodId || sh.ShippingMethodId == ShippingUtils.DhlEComSMParcelExpeditedShippingMethodId)) { if (orderItems.All( i => ItemStyleHelper.GetFromItemStyleOrTitle(i.ItemStyle, i.Title) == ItemStyleType.Robe)) { return(new CheckResult() { IsSuccess = false }); } } //NOTE: used default threashold: $1 //NOTE: if price disparity <$2 it's ok var threshold = 2.0M; //TASK: When order has 2 or more items and service "Standard" made threashold $2 if (orderItems.Sum(oi => oi.QuantityOrdered) >= 2 && ShippingUtils.IsServiceStandard(marketOrder.InitialServiceType)) { threshold = 2.5M; } var withEmptyThreashold = 0; var withNotEmptyThreashold = 0; foreach (var item in orderItems) { decimal?styleThreashold = null; if (item.StyleId.HasValue) { var featureValue = db.StyleFeatureTextValues.GetFeatureValueByStyleIdByFeatureId( item.StyleId.Value, StyleFeatureHelper.EXCESSIVE_SHIPMENT); if (featureValue != null && !String.IsNullOrEmpty(featureValue.Value)) { styleThreashold = StringHelper.TryGetDecimal(featureValue.Value); } } if (styleThreashold.HasValue) { threshold += styleThreashold.Value * item.QuantityOrdered; withNotEmptyThreashold++; } else { withEmptyThreashold++; } } //if (withEmptyThreashold > 0) // threshold += 1.0M; //if (withNotEmptyThreashold == 0) // threshold = 1.0M; if (actualShippingsCost > 0 && paidShppingCost > 0 && paidShppingCost + threshold < actualShippingsCost) { bool isOverchargeSkipped = false; decimal totalIntlListingPriceInUSD = 0M; decimal totalUsListingPrice = 0; if (ShippingUtils.IsInternational(marketOrder.FinalShippingCountry)) { #region Calc US Shipping Cost decimal?actualUsShippingCost = 0M; var shippingService = ShippingUtils.StandardServiceName; //ShippingUtils.InitialShippingServiceIncludeUpgrade(marketOrder.InitialServiceType.Replace("i:", ""), //convert to local //marketOrder.UpgradeLevel); decimal?paidUsShippingCost = ShippingUtils.GetRougePaidUSShippingAmount(shippingService, orderItems.Sum(i => i.QuantityOrdered)); var usRates = RateHelper.GetRougeChipestUSRate(_log, _stampsRateProvider, _fromAddress, marketOrder, shippingService, orderItems, orderItems); if (usRates.Any()) { actualUsShippingCost = usRates.Sum(r => r.Amount); } #endregion foreach (var orderItem in orderItems) { totalIntlListingPriceInUSD += PriceHelper.RougeConvertToUSD(orderItem.ItemPriceCurrency, orderItem.ItemPrice); var usListingPrice = GetUSListingPrice(db, orderItem); if (usListingPrice == null) { totalUsListingPrice = 0; break; } totalUsListingPrice += (usListingPrice * orderItem.QuantityOrdered) ?? 0; } decimal?usEarnedValue = ((totalUsListingPrice) + (paidUsShippingCost ?? 0) - (actualUsShippingCost ?? 0)); decimal?marketEarnedValue = (totalIntlListingPriceInUSD + paidShppingCost - actualShippingsCost.Value); decimal?howMachEarnedValue = null; if (actualUsShippingCost.HasValue && paidUsShippingCost.HasValue && totalUsListingPrice > 0 && actualShippingsCost.HasValue) { howMachEarnedValue = (totalIntlListingPriceInUSD + paidShppingCost - actualShippingsCost.Value) - //how much we have earned now (totalUsListingPrice + paidUsShippingCost.Value - actualUsShippingCost.Value); //how much we have earned if we sell it in US isOverchargeSkipped = howMachEarnedValue > -threshold; //NOTE: Threashold } if (!isOverchargeSkipped) { //var message = internationalOverchargeSkip ? "No Excessive Shipping cost" : "Excessive Shipping cost"; var message = ""; if (totalUsListingPrice > 0) { message = String.Format("Income disparity: {0}+{1}-{2}={3} vs {4} => income diff.: {5}", //MarketHelper.GetShortName((int)marketOrder.Market, marketOrder.MarketplaceId), (totalUsListingPrice).ToString("C", culture), (paidUsShippingCost ?? 0).ToString("C", culture), (actualUsShippingCost ?? 0).ToString("C", culture), usEarnedValue?.ToString("C", culture), marketEarnedValue?.ToString("C", culture), (howMachEarnedValue ?? 0).ToString("C", culture)); } else { isOverchargeSkipped = true; //SKIP message = "Excessive Shipping validation: no similar US listing"; } db.OrderComments.Add(new OrderComment() { OrderId = orderId, Message = message, Type = (int)CommentType.System, CreateDate = _time.GetAppNowTime(), }); db.Commit(); } } else { //сделай пока $3.02 threashold var localThreshold = Math.Max(threshold, 3.02M); if (paidShppingCost + localThreshold < actualShippingsCost) { var message = String.Format("Paid shipping ({0}) lower shipping cost ({1}) more than threshold ({2})", (paidShppingCost).ToString("C", culture), (actualShippingsCost ?? 0).ToString("C", culture), (localThreshold).ToString("C", culture)); db.OrderComments.Add(new OrderComment() { OrderId = orderId, Message = message, Type = (int)CommentType.System, CreateDate = _time.GetAppNowTime(), }); } else { //NOTE: Temp Do Nothing isOverchargeSkipped = true; } } if (!isOverchargeSkipped) { db.OrderNotifies.Add( ComposeNotify(orderId, (int)OrderNotifyType.OverchargedShpppingCost, 1, paidShppingCost + "<" + actualShippingsCost, _time.GetAppNowTime())); db.Commit(); } if (!isOverchargeSkipped) { foreach (var orderItem in orderItems) { if (orderItem.SourceListingId.HasValue) { var listing = db.Listings.Get(orderItem.SourceListingId.Value); if (listing != null) { SystemActionHelper.RequestPriceRecalculation(db, _actionService, listing.Id, null); if (listing.Market == (int)MarketType.Walmart) //NOTE: need to update Second Day flag { SystemActionHelper.RequestItemUpdate(db, _actionService, listing.Id, null); } } } } } return(new CheckResult() { IsSuccess = !isOverchargeSkipped }); } #endregion return(new CheckResult() { IsSuccess = false }); }
public bool IsAccept(OrderToTrackDTO orderToTrackInfo, string status, DateTime?statusDate, IList <TrackingRecord> records) { /*TASK: When tracking history contains “Undeliverable as Addressed” like order 114-8804539-8077829 * When it’s being scanned back in Hallandale (after that),and if there is no Notes in account after the day it was scanned as undeliverable, send client an email: * “Dear %Name%, * Your order of %List Of pajamas% being returned to us by USPS because the address you have provided for this order is undeliverable. * Please review full tracking history of this order at %link to USPS with tracking number%. * Please let us know how would you like us to proceed with your order once we get it back. * * Best Regards, * Customer Service” * * Please also add a note to the account: Order being returned, emailed customer. */ var today = _time.GetAppNowTime().Date; //NOTE: processing only fresh records if (statusDate.HasValue && statusDate.Value < today.AddDays(-10)) { _log.Info("Skip old status, pass more than 10 days"); return(false); } if (orderToTrackInfo.Carrier == ShippingServiceUtils.USPSCarrier) { //TASK: When tracking history contains “Undeliverable as Addressed” var undeliverableAsAddressStatus = records.FirstOrDefault(s => String.Compare(s.Message, "Undeliverable as Addressed", StringComparison.OrdinalIgnoreCase) == 0 || (s.Message ?? "").IndexOf("Addressee not available", StringComparison.OrdinalIgnoreCase) >= 0); if (undeliverableAsAddressStatus != null) { //TASK: sent only to US and CA, for other country we always do refund if (ShippingUtils.IsInternational(orderToTrackInfo.ShippingAddress.FinalCountry) && orderToTrackInfo.ShippingAddress.FinalCountry != "CA") { return(false); } _log.Info("Found \"Undeliverable As Addressed\""); var scanInHallandale = records.FirstOrDefault(r => r.Date > undeliverableAsAddressStatus.Date && _addressService.IsMine(r.AsAddressDto())); if (scanInHallandale != null) { _log.Info("Being scanned back"); //When it’s being scanned back in Hallandale (after that),and if there is no Notes in account after the day it was scanned as undeliverable, send client an email //NOTE: disable check and send message at same day when scanned back //if (scanInHallandale.Date.HasValue && _time.GetBizDaysCount(scanInHallandale.Date.Value, today) > 1) //{ // if (!records.Any(r => r.Date >= scanInHallandale.Date.Value // && !_addressService.IsMine(r.AsAddressDto()))) // { // _log.Info("no Notes in account after the day it was scanned. Send email."); // return true; // } // else // { // _log.Info("Found extra notes after package was scanned back"); // } //} return(true); } } } return(false); }
public void GetIntlRatesTest(string orderId, ShipmentProviderType type) { using (var db = _dbFactory.GetRWDb()) { var order = db.ItemOrderMappings.GetOrderWithItems(_weightService, orderId, unmaskReferenceStyle: false, includeSourceItems: true); var shippingService = ShippingUtils.InitialShippingServiceIncludeUpgrade(order.InitialServiceType, order.UpgradeLevel); //order.ShippingService var orderItemInfoes = OrderHelper.BuildAndGroupOrderItems(order.Items); var sourceOrderItemInfoes = OrderHelper.BuildAndGroupOrderItems(order.SourceItems); var providers = GetShipmentProviders(_company); var provider = providers.FirstOrDefault(p => p.Type == type); var companyAddress = new CompanyAddressService(_company); if (ShippingUtils.IsInternational(order.ShippingCountry)) { var rates = provider.GetInternationalRates( companyAddress.GetReturnAddress(order.GetMarketId()), companyAddress.GetPickupAddress(order.GetMarketId()), order.GetAddressDto(), _time.GetAppNowTime(), order.WeightD, null, order.IsInsured ? order.TotalPrice : 0, order.IsSignConfirmation, new OrderRateInfo() { ShippingService = shippingService, OrderNumber = order.OrderId, Items = orderItemInfoes, SourceItems = sourceOrderItemInfoes, TotalPrice = order.TotalPrice, Currency = order.TotalPriceCurrency, }, RetryModeType.Normal); Console.WriteLine(rates.Rates.Count); } else { var rates = provider.GetLocalRate( companyAddress.GetReturnAddress(order.GetMarketId()), companyAddress.GetPickupAddress(order.GetMarketId()), order.GetAddressDto(), _time.GetAppNowTime(), order.WeightD, null, order.IsInsured ? order.TotalPrice : 0, order.IsSignConfirmation, new OrderRateInfo() { ShippingService = shippingService, InitialServiceType = order.InitialServiceType, OrderNumber = order.OrderId, Items = orderItemInfoes, SourceItems = sourceOrderItemInfoes, TotalPrice = order.TotalPrice, Currency = order.TotalPriceCurrency, }, RetryModeType.Normal); Console.WriteLine(rates.Rates.Count); } } }
public void FillIBCRateTable() { using (var db = _dbFactory.GetRWDb()) { var newRateTable = new List <RateByCountryDTO>(); var addressList = new List <AddressDTO>() { //RateHelper.GetSampleUSAddress(), RateHelper.GetSampleCAAddress(), RateHelper.GetSampleUKAddress() }; var serviceFactory = new ServiceFactory(); var rateProviders = serviceFactory.GetShipmentProviders(_log, _time, _dbFactory, _weightService, _company.ShipmentProviderInfoList, null, null, null, null); var stampsRateProvider = rateProviders.FirstOrDefault(r => r.Type == ShipmentProviderType.IBC); var companyAddress = new CompanyAddressService(_company); var shippingSizes = new string[] { //"S", "XL" }; var internationalPackages = new string[] { "", "" }; for (var oz = 1; oz < 50; oz++) { //International Package Type: Regular, Flat //Shipping Size: S, XL foreach (var address in addressList) { foreach (var shippingSize in shippingSizes) { var packageType = shippingSize == "XL" ? PackageTypeCode.Regular : (ShippingUtils.IsInternational(address.Country) ? PackageTypeCode.LargeEnvelopeOrFlat : PackageTypeCode.Flat); var shippintType = ShippingUtils.IsInternational(address.Country) ? ShippingTypeCode.IStandard : ShippingTypeCode.Standard; var rate = RateHelper.GetRougeChipestRate(_log, stampsRateProvider, companyAddress.GetReturnAddress(MarketIdentifier.Empty()), address, oz, DateTime.Today, shippintType, packageType); if (rate != null && rate.Amount.HasValue) { _log.Info("Add rate: " + address.Country + ", " + oz + "oz, " + shippingSize + ", " + rate.Amount.Value + ", package=" + ((PackageTypeCode)rate.PackageTypeUniversal).ToString() + ", shippingType=" + ((ShippingTypeCode)rate.ServiceTypeUniversal).ToString()); newRateTable.Add(new RateByCountryDTO() { Cost = rate.Amount.Value, Country = address.Country, Weight = oz, PackageType = packageType.ToString(), //NOTE: need to use source package type, no matter what actual package is ((PackageTypeCode) rate.PackageTypeUniversal).ToString(), ShipmentProvider = stampsRateProvider.Type.ToString(), UpdateDate = _time.GetAppNowTime() }); } else { _log.Info("No rates: " + oz + "oz, " + shippingSize); } } } } var existRates = db.RateByCountries.GetAll(); foreach (var rate in newRateTable) { var exist = existRates.FirstOrDefault(r => r.Country == rate.Country && r.PackageType == rate.PackageType && r.Weight == rate.Weight); if (exist == null) { db.RateByCountries.Add(new RateByCountry() { Country = rate.Country, PackageType = rate.PackageType, Cost = rate.Cost, Weight = rate.Weight, ShipmentProvider = rate.ShipmentProvider, UpdateDate = rate.UpdateDate, }); } else { exist.Cost = rate.Cost; exist.ShipmentProvider = rate.ShipmentProvider; } } db.Commit(); } }
public CheckResult Check(IUnitOfWork db, DTOMarketOrder order, IList <ListingOrderDTO> items, AddressValidationStatus addressValidationStatus) { if (order.Id == 0) { throw new ArgumentOutOfRangeException("order.Id", "Should be non zero"); } if (order.OrderStatus == OrderStatusEnumEx.Pending) { throw new ArgumentException("order.OrderStatus", "Not supported status Pending"); } //International order has issue with PersonName if (ShippingUtils.IsInternational(order.FinalShippingCountry)) { if (String.IsNullOrEmpty(order.FinalShippingPhone)) { var emailInfo = new PhoneMissingEmailInfo(_emailService.AddressService, null, order.OrderId, (MarketType)order.Market, items, order.BuyerName, order.BuyerEmail); _emailService.SendEmail(emailInfo, CallSource.Service); _log.Info("Send phone missing email, orderId=" + order.Id); db.OrderEmailNotifies.Add(new OrderEmailNotify() { OrderNumber = order.OrderId, Reason = "System emailed, missing phone number", Type = (int)OrderEmailNotifyType.OutputPhoneMissingEmail, CreateDate = _time.GetUtcTime(), }); db.OrderComments.Add(new OrderComment() { OrderId = order.Id, Message = "[System] Missing phone email sent", Type = (int)CommentType.Address, CreateDate = _time.GetAppNowTime(), UpdateDate = _time.GetAppNowTime() }); db.Commit(); return(new CheckResult() { IsSuccess = false }); } } return(new CheckResult() { IsSuccess = true }); }
public virtual ActionResult ReCalcShippingService(long batchId, string orderIds, int?switchToProviderId, int?switchToMethodId) { LogI("ReCalcShippingService begin, orderIds=" + orderIds); IList <string> failedUpdate = new List <string>(); IList <string> successUpdate = new List <string>(); if (!string.IsNullOrEmpty(orderIds)) { var stringOrderIdList = orderIds.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var orderIdList = stringOrderIdList.Select(long.Parse).ToArray(); var rateProviders = ServiceFactory.GetShipmentProviders(LogService, Time, DbFactory, WeightService, AccessManager.Company.ShipmentProviderInfoList, null, null, null, null); var syncInfo = new EmptySyncInformer(LogService, SyncType.Orders); IList <DTOOrder> dtoOrders = Db.ItemOrderMappings.GetSelectedOrdersWithItems(WeightService, orderIdList, includeSourceItems: true).ToList(); foreach (var dtoOrder in dtoOrders) { //Ignore shipped orders if ((dtoOrder.Market != (int)MarketType.eBay && ShippingUtils.IsOrderShipped(dtoOrder.OrderStatus)) || dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.LabelPath))) { failedUpdate.Add(dtoOrder.OrderId); continue; } if (switchToProviderId.HasValue && dtoOrder.ShipmentProviderType != switchToProviderId.Value) { var skipChanges = false; if (switchToProviderId == (int)ShipmentProviderType.FedexOneRate) { if (ShippingUtils.IsInternational(dtoOrder.FinalShippingCountry)) { skipChanges = true; } } if (!skipChanges) { var dbOrder = Db.Orders.Get(dtoOrder.Id); dbOrder.ShipmentProviderType = switchToProviderId.Value; Db.Commit(); dtoOrder.ShipmentProviderType = switchToProviderId.Value; } } var synchronizer = new AmazonOrdersSynchronizer(LogService, AccessManager.Company, syncInfo, rateProviders, CompanyAddress, Time, WeightService, MessageService); if (synchronizer.UIUpdate(Db, dtoOrder, false, false, keepCustomShipping: false, switchToMethodId: switchToMethodId)) { successUpdate.Add(dtoOrder.OrderId); } else { failedUpdate.Add(dtoOrder.OrderId); } } } LogI("ReCalcShippingService result, failedUpdate=" + String.Join(", ", failedUpdate) + ", successUpdate=" + String.Join(", ", successUpdate)); return(new JsonResult { Data = ValueResult <IList <string> > .Success("", new List <string>() { String.Join(", ", failedUpdate), String.Join(", ", successUpdate) }), JsonRequestBehavior = JsonRequestBehavior.AllowGet }); }
public CheckResult <AddressDTO> CheckAddress(CallSource callSource, AddressDTO inputAddress) { var additionalData = new List <string>() { OrderNotifyType.AddressCheckMelissa.ToString() }; if (ShippingUtils.IsInternational(inputAddress.FinalCountry)) { return(new CheckResult <AddressDTO>() { IsSuccess = false, AdditionalData = additionalData }); } //The Check action will validate the individual input data pieces for validity and correct them if possible. //If the data is correctable, additional information will often be appended as well. US and Canada only. //Set the Server URL to the form input var url = "https://personator.melissadata.net/v3/WEB/ContactVerify/doContactVerify"; url += "?t="; //TransmissionReference url += "&id=" + _customerId; // "114035921"; url += "&act=Check"; //-Plus4 //Returns the 4-digit plus4 for the input address. If this column is requested, the PostalCode field will //only contain the 5-digit ZIP for U.S. addresses. //-PrivateMailBox //Returns the private mail box number for the address in the AddressLine field, if any. Private mailboxes //are private mail boxes in commercial mail receiving agencies, like a UPS Store. If requested, the Private //mailbox will be populated in this field instead of the Address field. //-Suite //Returns the suite for the address in the AddressLine field, if any. If requested, the suite will be //populated in this field instead of the Address field. url += "&cols=Plus4"; //Columns "Plus4,PrivateMailBox,Suite"; url += "&opt="; //Options url += "&first="; url += "&last="; url += "&full=" + HttpUtility.UrlEncode(inputAddress.FinalFullName); url += "&comp="; url += "&a1=" + HttpUtility.UrlEncode(inputAddress.FinalAddress1); url += "&a2=" + HttpUtility.UrlEncode(inputAddress.FinalAddress2); url += "&city=" + HttpUtility.UrlEncode(inputAddress.FinalCity); url += "&state=" + HttpUtility.UrlEncode(inputAddress.FinalState); url += "&postal=" + HttpUtility.UrlEncode(inputAddress.FinalZip + (!String.IsNullOrEmpty(inputAddress.FinalZipAddon) ? "-" + inputAddress.FinalZipAddon : "")); url += "&ctry=" + HttpUtility.UrlEncode(inputAddress.FinalCountry); url += "&lastlines="; url += "&freeform="; url += "&email="; url += "&phone=" + HttpUtility.UrlEncode(inputAddress.FinalPhone); url += "&reserved="; //url = url.Replace("#", "%23"); var uri = new Uri(url); CheckResult <AddressDTO> result = null; try { var request = (HttpWebRequest)WebRequest.Create(uri); using (var response = request.GetResponse() as HttpWebResponse) { using (var responseStream = response.GetResponseStream()) { var doc = new XmlDocument(); doc.Load(responseStream); result = ProcessResult(doc); result.AdditionalData = additionalData; } } } catch (Exception ex) { result = new CheckResult <AddressDTO>() { IsSuccess = false, Message = ex.Message, AdditionalData = additionalData }; } if (result.Data != null) { var outputAddress = result.Data; if (!String.IsNullOrEmpty(outputAddress.AddressKey)) { if (inputAddress.Address1 == outputAddress.Address1 && inputAddress.Address2 == outputAddress.Address2 && inputAddress.City == outputAddress.City && inputAddress.Country == outputAddress.Country && inputAddress.State == outputAddress.State && inputAddress.Zip == outputAddress.Zip && inputAddress.ZipAddon == outputAddress.ZipAddon) { result.Data = null; } } else { result.Data = null; } } return(result); }
public void Process(IUnitOfWork db, EmailReadingResult result) { if (result.Status != EmailMatchingResultStatus.New || !result.HasMatches) { return; } var subject = result.Email.Subject ?? ""; var returnRequest = subject.StartsWith("Return authorization request for order") || subject.StartsWith("Return authorisation request for order") || subject.StartsWith("Return authorisation notification for order") || subject.StartsWith("Return authorization notification for order"); if (returnRequest) { result.WasEmailProcessed = true; //NOTE: skipped comment added to other Rules _log.Info("ReturnRequsetEmailRule, WasEmailProcessed=" + result.WasEmailProcessed); var orderNumber = result.MatchedIdList.FirstOrDefault(); _log.Info("Received Return authorization request, orderNumber=" + orderNumber); if (_existanceCheck) { var existReturn = db.ReturnRequests.GetAll().FirstOrDefault(r => r.OrderNumber == orderNumber); if (existReturn != null) { //Already exist return; } } var order = db.Orders.GetByOrderNumber(orderNumber); var orderItems = db.Listings.GetOrderItems(order.Id); var orderShippings = db.OrderShippingInfos.GetByOrderIdAsDto(order.Id).Where(sh => sh.IsActive).ToList(); //Return codes: https://sellercentral.amazon.com/gp/help/help-page.html/ref=ag_200453320_cont_scsearch?ie=UTF8&itemID=200453320&language=en_CA /*Order ID: # 112-4884600-1049826 * Item: Toy Story Woody Buzz Boys 4 pc Cotton Pajamas Set (6) * Quantity: 1 * Return reason: Too small * Customer comments: I need 5T or 6T sizes. (Optional) * Details: ... (Optional) * Request received: February 27, 2016*/ /* * Order ID: # 114-8683360-8244230 * Item: Shopkins Girls' Little Girls' Luxe Plush 2-Piece Pajama Snuggle Set, Pink, 6 * Quantity: 1 * Return reason: Too small * * Item: Shopkins Girls' Little Girls' 2-Piece Fleece Pajama Set, Pink, 6 * Quantity: 1 * Return reason: Too small */ var messages = result.Email.Message.Split(new string[] { "<br />", "<br>", "<br/>", "/r/n" }, StringSplitOptions.RemoveEmptyEntries); // var regex = new Regex(@"Order ID: # (?<OrderId>.*) // ([\s\S]+)Item: (?<ItemName>.*) // ([\s\S]+)Quantity: (?<Quantity>.*) // ([\s\S]+)Return reason: (?<Reason>.*) // ([\s\S]+)Request received: (?<Date>.*)"); // var match = regex.Match(message); // string receiveDate = match.Groups["Date"].Value; // string orderId = match.Groups["OrderId"].Value; // string itemName = match.Groups["ItemName"].Value; // string quantity = match.Groups["Quantity"].Value; // string reasonText = match.Groups["Reason"].Value; var returns = new List <ReturnRequestDTO>(); ReturnRequestDTO currentReturn = null; foreach (var message in messages) { if (message.StartsWith("Item: ")) { currentReturn = new ReturnRequestDTO(); returns.Add(currentReturn); currentReturn.ItemName = message.Replace("Item: ", ""); } if (currentReturn != null) { if (message.StartsWith("Return reason: ")) { currentReturn.Reason = StringHelper.Substring(message.Replace("Return reason: ", ""), 255); } if (message.StartsWith("Quantity: ")) { currentReturn.Quantity = StringHelper.TryGetInt(message.Replace("Quantity: ", "")); } if (message.StartsWith("Request received:")) { currentReturn.ReceiveDate = DateHelper.FromDateString(message.Replace("Request received: ", "")); } if (message.StartsWith("Customer comments:")) { currentReturn.CustomerComments = StringHelper.Substring(message.Replace("Customer comments: ", ""), 255); } if (message.StartsWith("Details:")) { currentReturn.Details = StringHelper.Substring(message.Replace("Details: ", ""), 255); } } } //var reason = ReasonCode.None; //ListingOrderDTO itemToCheck = null; //var itemsToExchange = new List<StyleItemCache>(); foreach (var ret in returns) { var itemToCheck = orderItems.FirstOrDefault(i => i.Title == ret.ItemName); //If not found check all items if (itemToCheck == null && orderItems.Count == 1) { itemToCheck = orderItems.FirstOrDefault(); } _log.Info("Item to check=" + (itemToCheck != null ? itemToCheck.SKU : "[null}")); if (itemToCheck != null) { ret.StyleId = itemToCheck.StyleId; ret.StyleItemId = itemToCheck.StyleItemId; ret.SKU = itemToCheck.SKU; ret.StyleString = itemToCheck.StyleID; } } foreach (var ret in returns) { var requestDb = new ReturnRequest() { ItemName = StringHelper.Substring(ret.ItemName, 255), OrderNumber = orderNumber, Quantity = ret.Quantity, Reason = ret.Reason, CustomerComments = StringHelper.Substring(ret.CustomerComments, 255), Details = StringHelper.Substring(ret.Details, 255), ReceiveDate = ret.ReceiveDate, CreateDate = _time.GetAppNowTime(), StyleId = ret.StyleId, StyleItemId = ret.StyleItemId, SKU = ret.SKU, }; db.ReturnRequests.Add(requestDb); db.Commit(); } _log.Info("Request saved into DB"); if (!_enableSendEmail) { //Skip logic with composing comment / email message return; } if (ShippingUtils.IsInternational(order.ShippingCountry)) { //Don't offer exchange to international order return; } var comments = new List <string>(); foreach (var request in returns) { var reason = GetReasonCode(request.Reason); var itemsToExchange = GetItemsToExchange(db, request); if (reason == ReasonCode.TooSmall || reason == ReasonCode.TooLarge) { var itemsToExchangeWithQty = itemsToExchange.Where(i => i.RemainingQuantity > 0).ToList(); //TASK: Don’t send those emails to orders which can’t be returned already, because more than 30 days passed like order 105-5461372-1374643. //TASK: orders, which were placed Nov 1-Jan 31, can be returned/exchanged by January 31 var returnRequestToLate = false; if (order.OrderDate.HasValue) { returnRequestToLate = OrderHelper.AcceptReturnRequest(order.OrderDate.Value, order.EstDeliveryDate, orderShippings.Max(sh => sh.ActualDeliveryDate), result.Email.ReceiveDate, _time.GetAppNowTime()); } if (returnRequestToLate) { var message = String.Format("Return request received (reason: {0}, style: {1}). Return request came too late. No email was sent to client by the system.", request.Reason, request.StyleString); comments.Add(message); } else { //TASK: don’t send Too small/big emails to clients who already purchased bigger/smaller size of same pajama, like this client - 105-1300286-6499443. var alreadyPurchasedOrdersByCustomer = db.Orders.GetAll().Where(o => o.OrderStatus == OrderStatusEnumEx.Unshipped && o.BuyerEmail == order.BuyerEmail) .Select(o => o.Id).ToList(); var alreadyPurchasedItems = db.OrderItems.GetWithListingInfo() .Where(oi => alreadyPurchasedOrdersByCustomer.Contains(oi.OrderId.Value)) .ToList(); var alreadyPurchasedAnotherSize = false; if (request.StyleId.HasValue) { alreadyPurchasedAnotherSize = alreadyPurchasedItems.Any(i => i.StyleEntityId == request.StyleId && i.StyleItemId != request.StyleItemId); } if (alreadyPurchasedAnotherSize) { var message = String.Format("Return request received (reason: {0}, style: {1}). Customer already purchased bigger/smaller size of same pajama. No email was sent to client by the system.", request.Reason, request.StyleString); comments.Add(message); } else { if (itemsToExchangeWithQty.Any()) { var sizeList = itemsToExchangeWithQty .OrderBy(i => SizeHelper.GetSizeIndex(i.Size)) .Select(i => i.Size) .ToList(); var sizeString = String.Join(" or ", sizeList); _log.Info("Send email for customer: " + reason + ", sizes=" + sizeString); var commentText = String.Format("Return request received (reason: {0}, style: {1}).", request.Reason, request.StyleString, reason == ReasonCode.TooLarge ? "smaller" : "bigger"); comments.Add(commentText); //TEMP: Disabled email //var commentText = String.Format("Return request received (reason: {0}, style: {1}). System offered client {2} size. Exchange request email sent.", // request.Reason, // request.StyleString, // reason == ReasonCode.TooLarge ? "smaller" : "bigger"); //comments.Add(commentText); //var emailInfoToBuyer = new AcceptReturnRequestEmailInfo(null, // orderNumber, // (MarketType) order.Market, // reason == ReasonCode.TooLarge, // sizeString, // order.BuyerName, // order.BuyerEmail); //_emailService.SendEmail(emailInfoToBuyer, CallSource.Service); } else { var sizeList = itemsToExchange .OrderBy(i => SizeHelper.GetSizeIndex(i.Size)) .Select(i => i.Size) .ToList(); var sizeString = String.Join(", ", sizeList); var message = String.Format("Return request received (reason: {0}). System didn't find any items to offer exchange (style: {1}, size: {2}). No email was sent to client by the system.", request.Reason, request?.StyleString ?? "[null]", sizeString); comments.Add(message); } } } db.Commit(); } } if (comments.Any()) { db.OrderComments.Add(new OrderComment() { OrderId = order.Id, Message = "[System] " + String.Join(", ", comments), Type = (int)CommentType.ReturnExchange, CreateDate = _time.GetAppNowTime(), UpdateDate = _time.GetAppNowTime() }); } } }
public CheckResult Check(IUnitOfWork db, DTOMarketOrder order, IList <ListingOrderDTO> items, AddressValidationStatus addressValidationStatus) { if (order.Id == 0) { throw new ArgumentOutOfRangeException("order.Id", "Should be non zero"); } if (order.OrderStatus == OrderStatusEnumEx.Pending) { throw new ArgumentException("order.OrderStatus", "Not supported status Pending"); } //International order has issue with PersonName if (!AddressHelper.IsStampsValidPersonName(order.FinalPersonName) && (order.AddressValidationStatus == (int)AddressValidationStatus.InvalidRecipientName || ShippingUtils.IsInternationalState(order.FinalShippingState) || ShippingUtils.IsInternational(order.FinalShippingCountry))) { //If can resolved using BuyerName var nameKeywords = (order.FinalPersonName ?? "").Split(", .".ToCharArray()).Where(n => n.Length > 2).ToArray(); if (!nameKeywords.Any()) { nameKeywords = (order.FinalPersonName ?? "").Split(", .".ToCharArray()).ToArray(); } if (AddressHelper.IsStampsValidPersonName(order.BuyerName) //NOTE: #1 Exclude prefix Mr., initials, like a.cheszes //NOTE: #2 Include when name has only one letter && StringHelper.ContrainOneOfKeywords(order.BuyerName, nameKeywords)) { db.OrderComments.Add(new OrderComment() { OrderId = order.Id, Message = "[System] Incomplete recipient name was replaced with buyer name: " + order.FinalPersonName + "=>" + order.BuyerName, Type = (int)CommentType.Address, CreateDate = _time.GetAppNowTime() }); if (order.IsManuallyUpdated) { order.ManuallyPersonName = order.BuyerName; } else { order.PersonName = order.BuyerName; } return(new CheckResult() { IsSuccess = true, AdditionalData = new[] { order.PersonName } }); } //Send email else { var emailInfo = new IncompleteNameEmailInfo(_emailService.AddressService, null, order.OrderId, (MarketType)order.Market, order.GetAddressDto(), items, order.BuyerName, order.BuyerEmail); _emailService.SendEmail(emailInfo, CallSource.Service); _log.Info("Send incomplete person name email, orderId=" + order.Id); db.OrderEmailNotifies.Add(new OrderEmailNotify() { OrderNumber = order.OrderId, Reason = "System emailed, incomplete name", Type = (int)OrderEmailNotifyType.OutputIncompleteNameEmail, CreateDate = _time.GetUtcTime(), }); db.OrderComments.Add(new OrderComment() { OrderId = order.Id, Message = "[System] Incomplete name email sent", Type = (int)CommentType.Address, CreateDate = _time.GetAppNowTime(), UpdateDate = _time.GetAppNowTime() }); db.Commit(); return(new CheckResult() { IsSuccess = false, AdditionalData = new List <string>() { "OnHold" } }); } } return(new CheckResult() { IsSuccess = false }); }
public ApplyOrderResult Apply(ILogService log, IUnitOfWork db, IOrderHistoryService orderHistoryService, IQuantityManager quantityManager, DateTime when, long?by) { var dbOrder = db.Orders.GetById(EntityId); var addressChanged = false; var shipmentProviderChanged = false; var shouldRecalcRates = dbOrder.IsInsured != IsInsured || dbOrder.IsSignConfirmation != IsSignConfirmation; var manuallyAddress = ComposeAddressDto(); //NOTE: empty when fields was readonly if (!AddressHelper.IsEmptyManually(manuallyAddress)) { var originalAddress = dbOrder.GetAddressDto(); addressChanged = AddressHelper.CompareWithManuallyAllFields(originalAddress, manuallyAddress); shouldRecalcRates = shouldRecalcRates || AddressHelper.CompareWithManuallyBigChanges(originalAddress, manuallyAddress); if (addressChanged) { orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyPersonNameKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyPersonName : dbOrder.PersonName, ManuallyPersonName, by); dbOrder.ManuallyPersonName = ManuallyPersonName; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingAddress1Key, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingAddress1 : dbOrder.ShippingAddress1, ManuallyShippingAddress1, by); dbOrder.ManuallyShippingAddress1 = ManuallyShippingAddress1; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingAddress2Key, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingAddress2 : dbOrder.ShippingAddress2, ManuallyShippingAddress2, by); dbOrder.ManuallyShippingAddress2 = ManuallyShippingAddress2; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingCityKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingCity : dbOrder.ShippingCity, ManuallyShippingCity, by); dbOrder.ManuallyShippingCity = ManuallyShippingCity; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingCountryKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingCountry : dbOrder.ShippingCountry, ManuallyShippingCountry, by); dbOrder.ManuallyShippingCountry = ManuallyShippingCountry; dbOrder.ManuallyShippingState = !ShippingUtils.IsInternational(dbOrder.ManuallyShippingCountry) // == "US" ? ManuallyShippingUSState : ManuallyShippingState; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingZipKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingZip : dbOrder.ShippingZip, ManuallyShippingZip, by); dbOrder.ManuallyShippingZip = StringHelper.TrimWhitespace(ManuallyShippingZip); orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingZipAddonKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingZipAddon : dbOrder.ShippingZipAddon, ManuallyShippingZipAddon, by); dbOrder.ManuallyShippingZipAddon = StringHelper.TrimWhitespace(ManuallyShippingZipAddon); orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingPhoneKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingPhone : dbOrder.ShippingPhone, ManuallyShippingPhone, by); dbOrder.ManuallyShippingPhone = ManuallyShippingPhone; dbOrder.IsManuallyUpdated = true; } else { dbOrder.ManuallyPersonName = String.Empty; dbOrder.ManuallyShippingAddress1 = String.Empty; dbOrder.ManuallyShippingAddress2 = String.Empty; dbOrder.ManuallyShippingCity = String.Empty; dbOrder.ManuallyShippingCountry = String.Empty; dbOrder.ManuallyShippingState = String.Empty; dbOrder.ManuallyShippingZip = String.Empty; dbOrder.ManuallyShippingZipAddon = String.Empty; dbOrder.ManuallyShippingPhone = String.Empty; dbOrder.IsManuallyUpdated = false; } } dbOrder.InsuredValue = InsuredValue; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.IsInsuredKey, dbOrder.IsInsured, IsInsured, by); dbOrder.IsInsured = IsInsured; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.IsSignConfirmationKey, dbOrder.IsSignConfirmation, IsSignConfirmation, by); dbOrder.IsSignConfirmation = IsSignConfirmation; if (ManuallyShipmentProviderType.HasValue) { if (dbOrder.ShipmentProviderType != ManuallyShipmentProviderType.Value) { shipmentProviderChanged = true; shouldRecalcRates = true; } orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ShipmentProviderTypeKey, dbOrder.ShipmentProviderType, ManuallyShipmentProviderType, by); dbOrder.ShipmentProviderType = ManuallyShipmentProviderType.Value; } //dbOrder.OnHold = OnHold; dbOrder.UpdateDate = when; dbOrder.UpdatedBy = by; if (Items.All(i => i.NewListingId > 0)) //NOTE: only when enabled items edit { var changeNotes = ""; var itemSizeWasChanged = false; var joinItems = JoinItems(Items); var dbOrderItems = db.OrderItems.GetAll().Where(i => i.OrderId == dbOrder.Id).ToList(); var orderItemSources = db.OrderItemSources.GetAllAsDto().Where(i => i.OrderId == dbOrder.Id).ToList(); foreach (var item in joinItems) { var dbOrderItem = dbOrderItems.FirstOrDefault(im => im.ItemOrderIdentifier == item.ItemOrderId); //NOTE: Get source info for set proprotionally ItemPrice etc. var sourceItemOrderId = item.SourceItemOrderId; var sourceItemMapping = orderItemSources.FirstOrDefault(i => i.ItemOrderIdentifier == sourceItemOrderId); if (dbOrderItem != null) { log.Info("Updated orderItemId=" + item.ItemOrderId + ", qty=" + item.Quantity); } else { log.Info("Added orderItemId=" + item.ItemOrderId + ", qty=" + item.Quantity); dbOrderItem = db.OrderItemSources.CreateItemFromSourceDto(sourceItemMapping); dbOrderItem.CreateDate = when; db.OrderItems.Add(dbOrderItem); } dbOrderItem.ItemOrderIdentifier = item.ItemOrderId; dbOrderItem.QuantityOrdered = item.Quantity; dbOrderItem.ListingId = item.NewListingId; dbOrderItem.SourceListingId = sourceItemMapping.ListingId; dbOrderItem.SourceItemOrderIdentifier = sourceItemMapping.ItemOrderIdentifier; var newListing = db.Listings.GetViewListingsAsDto(withUnmaskedStyles: false) .FirstOrDefault(l => l.Id == item.NewListingId); var keepListingUpdateOnlyStyle = newListing.StyleItemId != dbOrderItem.StyleItemId; if (dbOrderItem.Id == 0 || item.NewListingId != item.ListingId || keepListingUpdateOnlyStyle) { var oldListing = db.Listings.GetViewListingsAsDto(withUnmaskedStyles: false) .FirstOrDefault(l => l.Id == sourceItemMapping.ListingId); if (newListing != null && oldListing != null) { itemSizeWasChanged = newListing.StyleItemId != oldListing.StyleItemId; if (itemSizeWasChanged) { var isStyleChanged = newListing.StyleString != oldListing.StyleString; changeNotes += (isStyleChanged ? "Order item" : "Size") + " was changed from: " + (isStyleChanged ? oldListing.StyleString + " - " : " ") + SizeHelper.ToVariation(oldListing.StyleSize, oldListing.StyleColor) + " to: " + (isStyleChanged ? newListing.StyleString + " - " : "") + SizeHelper.ToVariation(newListing.StyleSize, newListing.StyleColor); dbOrderItem.ReplaceType = (int)ItemReplaceTypes.Change; dbOrderItem.ReplaceDate = when; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ReplaceItemKey, dbOrderItem.StyleItemId, dbOrderItem.Id.ToString(), newListing.StyleItemId, null, by); var quantityOperation = new QuantityOperationDTO() { Type = (int)QuantityOperationType.Lost, QuantityChanges = new List <QuantityChangeDTO>() { new QuantityChangeDTO() { StyleId = oldListing.StyleId.Value, StyleItemId = oldListing.StyleItemId.Value, Quantity = dbOrderItem.QuantityOrdered, //NOTE: W/o sign means that the qty will be substracted } }, Comment = "Order edit, change style/size", }; quantityManager.AddQuantityOperation(db, quantityOperation, when, by); } //NOTE: Actualize current style info dbOrderItem.StyleId = newListing.StyleId; dbOrderItem.StyleItemId = newListing.StyleItemId; dbOrderItem.StyleString = newListing.StyleString; dbOrderItem.SourceStyleString = oldListing.StyleString; dbOrderItem.SourceStyleItemId = oldListing.StyleItemId; dbOrderItem.SourceStyleSize = oldListing.StyleSize; dbOrderItem.SourceStyleColor = oldListing.StyleColor; } } if (dbOrderItem.ItemOrderIdentifier != dbOrderItem.SourceItemOrderIdentifier) { var portionCoef = dbOrderItem.QuantityOrdered / (decimal)sourceItemMapping.QuantityOrdered; dbOrderItem.ItemPrice = sourceItemMapping.ItemPrice * portionCoef; dbOrderItem.ItemPriceInUSD = sourceItemMapping.ItemPriceInUSD * portionCoef; dbOrderItem.ShippingPrice = sourceItemMapping.ShippingPrice * portionCoef; dbOrderItem.ShippingPriceInUSD = sourceItemMapping.ShippingPriceInUSD * portionCoef; dbOrderItem.ShippingDiscount = sourceItemMapping.ShippingDiscount * portionCoef; dbOrderItem.ShippingDiscountInUSD = sourceItemMapping.ShippingDiscountInUSD * portionCoef; } else //NOTE: m.b. no needed, for now no cases, but can be found in future { dbOrderItem.ItemPrice = sourceItemMapping.ItemPrice; dbOrderItem.ItemPriceInUSD = sourceItemMapping.ItemPriceInUSD; dbOrderItem.ShippingPrice = sourceItemMapping.ShippingPrice; dbOrderItem.ShippingPriceInUSD = sourceItemMapping.ShippingPriceInUSD; dbOrderItem.ShippingDiscount = sourceItemMapping.ShippingDiscount; dbOrderItem.ShippingDiscountInUSD = sourceItemMapping.ShippingDiscountInUSD; } } db.Commit(); var toRemoveOrderItems = dbOrderItems.Where(oi => joinItems.All(i => i.ItemOrderId != oi.ItemOrderIdentifier) && oi.QuantityOrdered > 0).ToList(); //Keeping cancelled items with qty = 0 foreach (var toRemove in toRemoveOrderItems) { log.Info("Remove orderItem, ordrItemId=" + toRemove.ItemOrderIdentifier + ", qty=" + toRemove.QuantityOrdered); db.OrderItems.Remove(toRemove); itemSizeWasChanged = true; } db.Commit(); if (itemSizeWasChanged) { shouldRecalcRates = true; Comments.Add(new CommentViewModel() { Comment = changeNotes, Type = (int)CommentType.ReturnExchange }); } } if (!string.IsNullOrEmpty(ManuallyShippingGroupId)) { var groupId = int.Parse(ManuallyShippingGroupId); var shippings = db.OrderShippingInfos.GetByOrderId(EntityId).ToList(); var previousIsActiveMethodIds = String.Join(";", shippings.Where(sh => sh.IsActive).Select(sh => sh.ShippingMethodId).ToList()); var hasDropdown = shippings.Where(sh => sh.IsVisible).GroupBy(sh => sh.ShippingMethodId).Count() > 1; if (shippings.Any(sh => sh.ShippingGroupId == groupId)) { foreach (var shipping in shippings) { shipping.IsActive = shipping.ShippingGroupId == groupId; if (hasDropdown) //Keep is visible { shipping.IsVisible = shipping.IsVisible || shipping.ShippingGroupId == groupId; } else { shipping.IsVisible = shipping.ShippingGroupId == groupId; } } var newIsActiveMethodIds = String.Join(";", shippings.Where(sh => sh.IsActive).Select(sh => sh.ShippingMethodId).ToList()); orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ShippingMethodKey, previousIsActiveMethodIds, newIsActiveMethodIds, by); } else { //Can't change active shipping to not exists } } db.Commit(); //Update Package Sizes var activeShippings = db.OrderShippingInfos.GetByOrderId(EntityId) .Where(sh => sh.IsActive) .OrderBy(sh => sh.Id) .ToList(); for (var i = 0; i < activeShippings.Count; i++) { if (Packages != null && i < Packages.Count) { if (activeShippings[i].PackageLength != Packages[i].PackageLength) { log.Info("Changed length: " + activeShippings[i].PackageLength + "=>" + Packages[i].PackageLength); activeShippings[i].PackageLength = Packages[i].PackageLength; shouldRecalcRates = true; } if (activeShippings[i].PackageWidth != Packages[i].PackageWidth) { log.Info("Changed width: " + activeShippings[i].PackageWidth + "=>" + Packages[i].PackageWidth); activeShippings[i].PackageWidth = Packages[i].PackageWidth; shouldRecalcRates = true; } if (activeShippings[i].PackageHeight != Packages[i].PackageHeight) { log.Info("Changed height: " + activeShippings[i].PackageHeight + "=>" + Packages[i].PackageHeight); activeShippings[i].PackageHeight = Packages[i].PackageHeight; shouldRecalcRates = true; } } } db.Commit(); foreach (var comment in Comments) { if (comment.Id == 0) { log.Info("New comment: " + comment.Comment); } } db.OrderComments.AddComments( Comments.Select(c => new CommentDTO() { Id = c.Id, Message = c.Comment, Type = c.Type, }).ToList(), EntityId, when, by); return(new ApplyOrderResult() { RateRecalcRequested = shouldRecalcRates, AddressValidationRequested = addressChanged || dbOrder.AddressValidationStatus == (int)Core.Models.AddressValidationStatus.ExceptionCommunication || dbOrder.AddressValidationStatus == (int)Core.Models.AddressValidationStatus.Exception, ShipmentProviderChanged = shipmentProviderChanged }); }
public static CustomShippingViewModel Get(IUnitOfWork db, long orderId, long?defaultShippingMethodId) { var result = new CustomShippingViewModel(); var order = db.Orders.GetById(orderId); var isIntl = ShippingUtils.IsInternational(order.ShippingCountry); var shippingMethods = db.ShippingMethods.GetAllAsDto() .Where(m => m.ShipmentProviderType == order.ShipmentProviderType && m.IsInternational == isIntl && m.IsActive) .ToList(); result.PackageList = new List <SelectListItemTag>(); foreach (var shippingMethod in shippingMethods) { for (int i = 0; i <= 6; i++) { result.PackageList.Add(new SelectListItemTag() { Text = shippingMethod.Name + " - #" + (i + 1), Value = shippingMethod.Id.ToString() + "-" + (i + 1), }); } } var customShippings = db.OrderShippingInfos.GetAllAsDto() .Where(sh => sh.OrderId == orderId && sh.ShippingGroupId == RateHelper.CustomPartialGroupId) .OrderBy(sh => sh.ShippingNumber) .ToList(); var orderItems = db.Listings.GetOrderItems(orderId) .OrderBy(oi => oi.ItemOrderId) .ToList(); //var orderItems = db.OrderItems.GetWithListingInfo() // .Where(oi => oi.OrderId == orderId) // .OrderBy(oi => oi.ItemOrderId) // .ToList(); var itemToShipping = new List <OrderShippingInfoDTO>(); if (customShippings.Any()) { var shippingIds = customShippings.Select(sh => sh.Id).ToList(); itemToShipping = (from m in db.ItemOrderMappings.GetAll() join sh in db.OrderShippingInfos.GetAll() on m.ShippingInfoId equals sh.Id join sm in db.ShippingMethods.GetAll() on sh.ShippingMethodId equals sm.Id where shippingIds.Contains(m.ShippingInfoId) select new OrderShippingInfoDTO() { Id = m.ShippingInfoId, Items = new List <DTOOrderItem>() { new DTOOrderItem() { OrderItemEntityId = m.OrderItemId, Quantity = m.MappedQuantity } }, ShippingMethod = new ShippingMethodDTO() { Id = sm.Id, Name = sm.Name, ShortName = sm.ShortName, RequiredPackageSize = sm.RequiredPackageSize } }).ToList(); } var shippingNumbers = new Dictionary <long, int>(); var shippings = itemToShipping.GroupBy(sh => sh.Id).Select(sh => sh.First()).ToList(); var processedShippings = new List <OrderShippingInfoDTO>(); foreach (var shipping in shippings) { var count = processedShippings.Count(sh => sh.ShippingMethod.Id == shipping.ShippingMethod.Id); shippingNumbers.Add(shipping.Id, count + 1); processedShippings.Add(shipping); } ShippingMethodDTO defaultShippingMethod = null; if (defaultShippingMethodId.HasValue) { defaultShippingMethod = shippingMethods.FirstOrDefault(m => m.Id == defaultShippingMethodId.Value); } if (defaultShippingMethod == null) { defaultShippingMethod = shippingMethods.FirstOrDefault(m => m.Id == ShippingUtils.AmazonFedEx2DayOneRatePakShippingMethodId || m.Id == ShippingUtils.FedexOneRate2DayPak); } var defaultPackageNumber = defaultShippingMethod != null ? 1 : (int?)null; var items = new List <CustomShippingItemViewModel>(); foreach (var orderItem in orderItems) { for (int q = 0; q < orderItem.QuantityOrdered; q++) { var existCustomMapping = itemToShipping.FirstOrDefault(i => i.Items.First().OrderItemEntityId == orderItem.OrderItemEntityId && i.Items.First().Quantity > 0); if (existCustomMapping != null) { existCustomMapping.Items.First().Quantity--; } var image = orderItem.Picture; if (String.IsNullOrEmpty(image)) { image = orderItem.StyleImage; } if (orderItem.ReplaceType == (int)ItemReplaceTypes.Combined) { image = orderItem.StyleImage; } var pictureUrl = ImageHelper.GetFirstOrDefaultPicture(image); items.Add(new CustomShippingItemViewModel() { ASIN = orderItem.ASIN, StyleString = orderItem.StyleID, StyleSize = orderItem.StyleSize, Weight = orderItem.Weight ?? 0, PictureUrl = pictureUrl, OrderItemId = orderItem.OrderItemEntityId, ShippingInfoId = existCustomMapping != null ? existCustomMapping.Id : (long?)null, ShippingMethodName = existCustomMapping != null ? existCustomMapping.ShippingMethod.Name : defaultShippingMethod?.Name, ShippingMethodId = existCustomMapping != null ? existCustomMapping.ShippingMethod.Id : defaultShippingMethod?.Id, PackageNumber = existCustomMapping != null ? shippingNumbers[existCustomMapping.Id] : defaultPackageNumber, }); } } items.ForEach(i => { if (i.PackageNumber.HasValue && i.ShippingMethodId.HasValue) { i.PackageValue = i.ShippingMethodId.Value + "-" + i.PackageNumber; } }); result.Items = items.OrderBy(i => i.ShippingMethodId) .ThenBy(i => i.PackageNumber) .ThenBy(i => i.StyleString) //TODO: by location .ThenBy(i => SizeHelper.GetSizeIndex(i.StyleSize)) .ToList(); return(result); }