예제 #1
0
        public CheckResult Check(DTOOrder order,
                                 IList <ListingOrderDTO> orderItems)
        {
            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");
            }

            CheckResult result = new CheckResult()
            {
                IsSuccess = false
            };

            var serviceType = order.InitialServiceType;

            if (ShippingUtils.IsServiceTwoDays(serviceType) ||
                ShippingUtils.IsServiceNextDay(serviceType))
            {
                result = new CheckResult()
                {
                    IsSuccess = true
                };
            }

            return(result);
        }
        public static OrdersStatViewModel Get(IUnitOfWork db,
                                              MarketplaceKeeper marketplaceManager)
        {
            var model = new OrdersStatViewModel();

            var today = DateHelper.GetAppNowTime().Date;

            var orders = db.Orders.GetUnshippedOrders();

            model.TotalOrdersCount = orders.Count;
            var marketplaces = marketplaceManager.GetAll();

            model.Marketplaces = marketplaces.Select(m => new OrdersByMarketplaceInfo()
            {
                Market        = m.Market,
                MarketplaceId = m.MarketplaceId,
                OrderCount    = orders.Count(o => o.Market == m.Market &&
                                             (o.MarketplaceId == m.MarketplaceId || String.IsNullOrEmpty(m.MarketplaceId))),
                PaidExpeditedOrderCount = orders.Count(o => o.Market == m.Market &&
                                                       (o.MarketplaceId == m.MarketplaceId || String.IsNullOrEmpty(m.MarketplaceId)) &&
                                                       ShippingUtils.IsServiceExpedited(o.InitialServiceType)),
                SecondDayOrderCount = orders.Count(o => o.Market == m.Market &&
                                                   (o.MarketplaceId == m.MarketplaceId || String.IsNullOrEmpty(m.MarketplaceId)) &&
                                                   (ShippingUtils.IsServiceTwoDays(o.InitialServiceType) ||
                                                    ShippingUtils.IsServiceNextDay(o.InitialServiceType))),
            }).ToList();

            model.OverdueOrdersCount = orders.Count(o => o.LatestShipDate.HasValue &&
                                                    ShippingUtils.AlignMarketDateByEstDayEnd(o.LatestShipDate.Value, (MarketType)o.Market) < today);

            return(model);
        }
예제 #3
0
        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");
            }

            if (ShippingUtils.IsLatvia(order.FinalShippingCountry))
            {
                if ((order.ShippingZip ?? "").Contains("LV-"))
                {
                    return(new CheckResult()
                    {
                        IsSuccess = true,
                        AdditionalData = new[] { (order.ShippingZip ?? "").Replace("LV-", "LV") }
                    });
                }
            }

            return(new CheckResult()
            {
                IsSuccess = false
            });
        }
예제 #4
0
        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);
        }
예제 #5
0
        public bool UpdateOrder(IUnitOfWork db, ShippingDTO shipping)
        {
            _log.Info("Update order: id=" + shipping.OrderId + ", orderId=" + shipping.AmazonIdentifier + ", marketId=" + shipping.MarketOrderId);

            IList <OrderItemDTO> orderItems;

            if (shipping.IsFromMailPage)
            {
                orderItems = db.OrderItems.GetByOrderIdAsDto(shipping.OrderId)
                             //Remove canceled items with 0 price
                             .Where(m => m.ItemPrice > 0 || m.QuantityOrdered > 0).ToList();
            }
            else
            {
                orderItems = db.OrderItems.GetByShippingInfoIdAsDto(shipping.Id)
                             //Remove canceled items with 0 price
                             .Where(m => m.ItemPrice > 0 || m.QuantityOrdered > 0).ToList();
            }

            var allItemWasUpdated = true;

            foreach (var item in orderItems)
            {
                _log.Info("OrderItem, itemId=" + item.ItemOrderIdentifier);

                DateTime?orderDate = null;
                if (shipping.OrderDate.HasValue)
                {
                    orderDate = shipping.OrderDate.Value.ToUniversalTime();
                }
                var shippingDate = shipping.ShippingDate.ToUniversalTime();
                if (orderDate.HasValue && shippingDate < orderDate)
                {
                    shippingDate = orderDate.Value.AddHours(2);
                }

                var result = _api.UpdateOrder(shipping.MarketOrderId,
                                              item.ItemOrderIdentifier,
                                              shippingDate,
                                              shipping.TrackingNumber,
                                              ShippingUtils.FormattedToMarketCurrierName(shipping.ShippingMethod.CarrierName, shipping.ShippingMethod.IsInternational, MarketType.eBay));

                _log.Info(String.Format("Order date: {0}, shipping date: {1}", orderDate, shippingDate));

                allItemWasUpdated = allItemWasUpdated && result.IsSuccess;
                if (result.IsSuccess)
                {
                    _log.Info("Order was updated");
                }
                else
                {
                    _log.Info("Order update errors: ErrorCode=" + result.ErrorCode + ", Message=" + result.Details);
                }
            }

            return(allItemWasUpdated);
        }
예제 #6
0
        public void RefreshAmazonRates()
        {
            var syncInfo = new EmptySyncInformer(_log, SyncType.Orders);

            using (var db = _dbFactory.GetRWDb())
            {
                var toRefreshOrderIds = (from o in db.Orders.GetAll()
                                         join sh in db.OrderShippingInfos.GetAll() on o.Id equals sh.OrderId
                                         where o.OrderStatus == OrderStatusEnumEx.Unshipped &&
                                         sh.IsActive &&
                                         (o.Market == (int)MarketType.Amazon ||
                                          o.Market == (int)MarketType.AmazonAU ||
                                          o.Market == (int)MarketType.AmazonEU) &&
                                         (sh.ShippingMethodId == (int)ShippingUtils.AmazonFedExExpressSaverShippingMethodId || //TEMP: old
                                          sh.ShippingMethodId == (int)ShippingUtils.AmazonFedExHomeDeliveryShippingMethodId || //TEMP: old
                                          o.SourceShippingService == ShippingUtils.SecondDayServiceName ||
                                          o.SourceShippingService == ShippingUtils.NextDayServiceName ||
                                          o.OrderType == (int)OrderTypeEnum.Prime)
                                         select o.Id).ToList();

                _log.Info("Orders to update: " + String.Join(", ", toRefreshOrderIds.Select(o => o).ToList()));

                var orderIdList = toRefreshOrderIds.ToArray();
                if (!orderIdList.Any())
                {
                    return;
                }

                IList <DTOOrder> dtoOrders = db.ItemOrderMappings.GetSelectedOrdersWithItems(_weightService, orderIdList, includeSourceItems: true).ToList();
                foreach (var dtoOrder in dtoOrders)
                {
                    //Ignore shipped orders
                    if (ShippingUtils.IsOrderShipped(dtoOrder.OrderStatus) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.LabelPath)) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.TrackingNumber)))
                    {
                        _log.Info("OrderId: " + dtoOrder.Id + " (" + dtoOrder.OrderId + ") - Skipped (has shipped status or has tr#)");
                    }
                    else
                    {
                        _log.Info("Add recalc action for OrderId=" + dtoOrder.OrderId);

                        _actionService.AddAction(db,
                                                 SystemActionType.UpdateRates,
                                                 dtoOrder.OrderId,
                                                 new UpdateRatesInput()
                        {
                            OrderId = dtoOrder.Id
                        },
                                                 null,
                                                 null);
                    }
                }
            }
        }
예제 #7
0
        public virtual ActionResult GetOrderById(long orderId)
        {
            var rowOrderDto = Db.ItemOrderMappings.GetOrderWithItems(WeightService, orderId, false, true, unmaskReferenceStyles: true); //NOTE: Unmask for display
            var rowModel    = new OrderViewModel(rowOrderDto, AccessManager.IsFulfilment);

            rowModel.Items = rowOrderDto.Items.Select(i =>
                                                      new OrderItemViewModel(i,
                                                                             rowOrderDto.OnHold,
                                                                             ShippingUtils.IsOrderPartial(rowOrderDto.OrderStatus))).ToList();

            return(JsonGet(ValueResult <OrderViewModel> .Success("", rowModel)));
        }
        public void TestGetOneRateRates(string orderId)
        {
            var weightService  = new WeightService();
            var companyAddress = new CompanyAddressService(_company);

            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 serviceFactory = new ServiceFactory();

                var rateProviders = serviceFactory.GetShipmentProviders(_log,
                                                                        _time,
                                                                        _dbFactory,
                                                                        weightService,
                                                                        _company.ShipmentProviderInfoList,
                                                                        AppSettings.DefaultCustomType,
                                                                        AppSettings.LabelDirectory,
                                                                        AppSettings.LabelDirectory,
                                                                        AppSettings.LabelDirectory);

                var fedexRateProvider = rateProviders.FirstOrDefault(r => r.Type == ShipmentProviderType.FedexOneRate);

                var rates = fedexRateProvider.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);


                _log.Info("Rates: " + rates.Rates.Count);
            }
        }
예제 #9
0
        public void RefreshSuspiciousFedexRates()
        {
            var syncInfo = new EmptySyncInformer(_log, SyncType.Orders);

            using (var db = _dbFactory.GetRWDb())
            {
                var toRefreshOrderIds = (from o in db.Orders.GetAll()
                                         join sh in db.OrderShippingInfos.GetAll() on o.Id equals sh.OrderId
                                         where o.OrderStatus == OrderStatusEnumEx.Unshipped &&
                                         sh.IsActive &&
                                         (sh.ShippingMethodId == ShippingUtils.FedexOneRate2DayEnvelope ||
                                          sh.ShippingMethodId == ShippingUtils.FedexOneRate2DayPak) &&
                                         sh.StampsShippingCost > 12
                                         select o.Id).ToList();

                _log.Info("Orders to update: " + String.Join(", ", toRefreshOrderIds.Select(o => o).ToList()));

                var orderIdList = toRefreshOrderIds.ToArray();
                if (!orderIdList.Any())
                {
                    return;
                }

                IList <DTOOrder> dtoOrders = db.ItemOrderMappings.GetSelectedOrdersWithItems(_weightService, orderIdList, includeSourceItems: true).ToList();
                foreach (var dtoOrder in dtoOrders)
                {
                    //Ignore shipped orders
                    if (ShippingUtils.IsOrderShipped(dtoOrder.OrderStatus) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.LabelPath)) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.TrackingNumber)))
                    {
                        _log.Info("OrderId: " + dtoOrder.Id + " (" + dtoOrder.OrderId + ") - Skipped (has shipped status or has tr#)");
                    }
                    else
                    {
                        _log.Info("Add recalc action for OrderId=" + dtoOrder.OrderId);

                        _actionService.AddAction(db,
                                                 SystemActionType.UpdateRates,
                                                 dtoOrder.OrderId,
                                                 new UpdateRatesInput()
                        {
                            OrderId = dtoOrder.Id
                        },
                                                 null,
                                                 null);
                    }
                }
            }
        }
예제 #10
0
        public void ProcessResult(CheckResult result,
                                  Order dbOrder,
                                  DTOOrder order,
                                  IList <ListingOrderDTO> orderItems)
        {
            if (result.IsSuccess)
            {
                _log.Info("Send sign confirmation request order email, orderId=" + order.Id);

                var alreadySend = _db.OrderEmailNotifies.IsExist(order.OrderId,
                                                                 OrderEmailNotifyType.OutputSignConfirmationEmail);

                if (alreadySend)
                {
                    return;
                }

                var emailInfo = new SignConfirmationRequestEmailInfo(_emailService.AddressService,
                                                                     null,
                                                                     order.OrderId,
                                                                     (MarketType)order.Market,
                                                                     orderItems,
                                                                     //NOTE: make sense only express or not
                                                                     ShippingUtils.IsServiceNextDay(order.InitialServiceType) ? ShippingTypeCode.PriorityExpress : ShippingTypeCode.Standard,
                                                                     order.BuyerName,
                                                                     order.BuyerEmail);

                _emailService.SendEmail(emailInfo, CallSource.Service);

                _db.OrderEmailNotifies.Add(new OrderEmailNotify()
                {
                    OrderNumber = order.OrderId,
                    Reason      = "System emailed, request signconfirmation",
                    Type        = (int)OrderEmailNotifyType.OutputSignConfirmationEmail,
                    CreateDate  = _time.GetUtcTime(),
                });

                _db.OrderComments.Add(new OrderComment()
                {
                    OrderId    = order.Id,
                    Message    = "[System] Sign Confirmation email sent",
                    Type       = (int)CommentType.Address,
                    CreateDate = _time.GetAppNowTime(),
                    UpdateDate = _time.GetAppNowTime()
                });

                _db.Commit();
            }
        }
예제 #11
0
 private static IList <T> OrderByShippingThenLocation <T>(IList <T> orders) where T : ISortableEntity
 {
     //К3, К2, К1 (sorting order – isle, section, shelf, alphabetically product name).
     //alphabetically нужно так как могут быть несколько стайлов на одной полке
     return(orders.OrderByDescending(o => ShippingUtils.GetShippingMethodIndex(o.ShippingMethodId))
            .ThenBy(o => o.SortIsle)
            .ThenBy(o => o.SortSection)
            .ThenBy(o => o.SortShelf)
            .ThenBy(o => o.SortStyleString)
            .ThenBy(o => SizeHelper.GetSizeIndex(o.SortSize))
            .ThenBy(o => o.SortSize)
            .ThenBy(o => o.SortColor)
            .ThenBy(o => o.FirstItemName)
            .ThenBy(o => o.SortOrderId).ToList());
 }
예제 #12
0
 public void ProcessResult(CheckResult result, Order dbOrder)
 {
     if (result.IsSuccess)
     {
         if (ShippingUtils.IsCanada(dbOrder.ShippingCountry))
         {
             _log.Debug("IsPrime = false because of Canada");
             dbOrder.OrderType = (int)OrderTypeEnum.Default;
         }
     }
     //TASK: Remove automatic hold
     //if (result.IsSuccess)
     //{
     //    _log.Debug("Set OnHold by CheckPrime");
     //    dbOrder.OnHold = true;
     //}
 }
예제 #13
0
        public CheckResult Check(DTOMarketOrder order)
        {
            CheckResult result = new CheckResult()
            {
                IsSuccess = false
            };

            var serviceType = order.InitialServiceType;

            if (ShippingUtils.IsServiceSameDay(serviceType))
            {
                return(new CheckResult()
                {
                    IsSuccess = true
                });
            }

            return(result);
        }
        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);
        }
예제 #16
0
        public void LockBatch(IUnitOfWork db,
                              long batchId,
                              DateTime?when)
        {
            _log.Info("Lock batch, batchId=" + batchId);

            var orderIds = db.OrderBatches.GetOrderIdsForBatch(
                batchId,
                OrderStatusEnumEx.AllUnshippedWithShipped);

            var shippingList = db.OrderShippingInfos
                               .GetOrderInfoWithItems(_weightService,
                                                      orderIds.ToList(),
                                                      SortMode.ByLocation,
                                                      unmaskReferenceStyle: false,
                                                      includeSourceItems: false)
                               .ToList();

            shippingList = SortHelper.Sort(shippingList, SortMode.ByShippingMethodThenLocation).ToList();

            for (int i = 0; i < shippingList.Count; i++)
            {
                var mapping = new OrderToBatch()
                {
                    BatchId        = batchId,
                    ShippingInfoId = shippingList[i].Id,
                    SortIndex1     = ShippingUtils.GetShippingMethodIndex(shippingList[i].ShippingMethodId),
                    SortIndex2     = LocationHelper.GetLocationIndex(shippingList[i].SortIsle, shippingList[i].SortSection, shippingList[i].SortShelf),
                    SortIndex3     = SortHelper.GetStringIndex(shippingList[i].SortStyleString),
                    SortIndex4     = (decimal)SizeHelper.GetSizeIndex(shippingList[i].SortSize),
                    SortIndex5     = SortHelper.GetStringIndex(shippingList[i].SortColor),
                    //SortIndex6 = SortHelper.GetStringIndex(shippingList[i].FirstItemName),
                    CreateDate = when,
                };
                db.OrderToBatches.Add(mapping);
            }
            db.Commit();

            db.OrderBatches.LockBatch(batchId, when);
        }
예제 #17
0
        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");
            }

            if (ShippingUtils.IsCanada(order.FinalShippingCountry))
            {
                var state = order.FinalShippingState;
                if ((state ?? "").Length > 2)
                {
                    var stateAbbr = db.States.GetCodeByName(state);
                    if (!String.IsNullOrEmpty(stateAbbr))
                    {
                        return(new CheckResult()
                        {
                            IsSuccess = true,
                            AdditionalData = new[] { stateAbbr }
                        });
                    }
                }
            }

            return(new CheckResult()
            {
                IsSuccess = false
            });
        }
예제 #18
0
        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);
        }
예제 #20
0
        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 static MailViewModel GetByOrderId(IUnitOfWork db,
                                                 IWeightService weightService,
                                                 string id)
        {
            var order = db.Orders.GetMailDTOByOrderId(weightService, id);

            if (order == null)
            {
                return(new MailViewModel
                {
                    ToAddress = new AddressViewModel
                    {
                        Address1 = String.Empty,
                        Address2 = String.Empty,
                        FullName = String.Empty,
                        City = String.Empty,
                        USAState = String.Empty,
                        NonUSAState = String.Empty,
                        Country = String.Empty,
                        Zip = String.Empty,
                        Phone = String.Empty,
                        Email = String.Empty,
                        ShipDate = null
                    },
                    Items = new List <MailItemViewModel>(),
                    MarketplaceCode = 1,
                    Notes = String.Empty,
                    OrderStatus = String.Empty,
                    OrderID = String.Empty,
                    OrderEntityId = null,
                    IsPrime = false,

                    ShipmentProviderId = (int)ShipmentProviderType.Stamps,
                    HasBatchLabels = false,
                    HasMailLabels = false,

                    WeightLb = null,
                    WeightOz = null,
                });
            }
            else
            {
                return(new MailViewModel
                {
                    ToAddress = new AddressViewModel
                    {
                        Address1 = order.ToAddress.FinalAddress1,
                        Address2 = order.ToAddress.FinalAddress2,
                        FullName = order.ToAddress.FinalFullName,
                        City = order.ToAddress.FinalCity,
                        USAState = StringHelper.ToUpper(order.ToAddress.FinalState),
                        NonUSAState = StringHelper.ToUpper(order.ToAddress.FinalState),
                        Country = order.ToAddress.FinalCountry,
                        Zip = order.ToAddress.FinalZip,
                        ZipAddon = order.ToAddress.FinalZipAddon,
                        Phone = order.ToAddress.FinalPhone,
                        Email = order.ToAddress.BuyerEmail,
                        ShipDate = order.ToAddress.ShipDate
                    },
                    MarketplaceCode = 1,
                    Notes = "",

                    Market = order.Market,
                    MarketplaceId = order.MarketplaceId,

                    OrderStatus = order.OrderStatus,
                    OrderEntityId = order.OrderEntityId,
                    OrderID = order.OrderId,
                    IsPrime = order.OrderType == (int)OrderTypeEnum.Prime,
                    RequireAmazonProvider = ShippingUtils.RequireAmazonProvider(order.OrderType,
                                                                                order.Market,
                                                                                order.ToAddress.FinalCountry,
                                                                                order.SourceShippingService),

                    ShipmentProviderId = order.ShipmentProviderType,
                    HasBatchLabels = order.Labels.Any(l => l.LabelFromType == (int)LabelFromType.Batch),
                    HasMailLabels = order.Labels.Any(l => l.LabelFromType == (int)LabelFromType.Mail),

                    WeightLb = order.WeightLb,
                    WeightOz = order.WeightOz,

                    TotalPrice = order.TotalPrice,
                    TotalPriceCurrency = order.TotalPriceCurrency,

                    Items = order.Items.Select(i => new MailItemViewModel(i)).ToList(),

                    IsInsured = order.IsInsured
                });
            }
        }
        public static CallResult <List <ShippingMethodViewModel> > GetShippingOptionsWithRate(IUnitOfWork db,
                                                                                              ILogService log,
                                                                                              ITime time,
                                                                                              IShipmentApi rateProvider,
                                                                                              IShippingService shippingService,
                                                                                              AddressDTO fromAddress,
                                                                                              AddressDTO toAddress,
                                                                                              DateTime shipDate,
                                                                                              int weightLb,
                                                                                              decimal weightOz,
                                                                                              decimal insuredValue,
                                                                                              OrderRateInfo orderInfo)
        {
            var result        = new CallResult <List <ShippingMethodViewModel> >();
            var pickupAddress = fromAddress;

            var rateResult = rateProvider.GetAllRate(
                fromAddress,
                pickupAddress,
                toAddress,
                shipDate,
                (double)(weightLb * 16 + weightOz),
                null,
                0,
                false,
                orderInfo,
                RetryModeType.Fast);

            if (rateResult.Result != GetRateResultType.Success)
            {
                result.Status  = CallStatus.Fail;
                result.Message = rateResult.Message;
                return(result);
            }

            var methodList = GetShippingMethods(db,
                                                fromAddress.FinalCountry,
                                                toAddress.FinalCountry,
                                                weightLb,
                                                weightOz,
                                                rateProvider.Type);


            result.Data   = new List <ShippingMethodViewModel>();
            result.Status = CallStatus.Success;

            foreach (var method in methodList)
            {
                var rate = rateResult.Rates.FirstOrDefault(r => r.ServiceIdentifier == method.ServiceIdentifier);

                if (rate != null)
                {
                    //var deliveryDays = time.GetBizDaysCount(rate.ShipDate, rate.DeliveryDate);
                    var    deliveryDaysInfo = rate.DeliveryDaysInfo;
                    string providerPrefix   = "";
                    switch ((ShipmentProviderType)method.ShipmentProviderType)
                    {
                    case ShipmentProviderType.Amazon:
                        providerPrefix = "AMZ ";
                        break;

                    case ShipmentProviderType.Stamps:
                        providerPrefix = "";
                        break;

                    case ShipmentProviderType.Dhl:
                        providerPrefix = "";
                        break;

                    case ShipmentProviderType.DhlECom:
                        providerPrefix = "";
                        break;
                    }

                    var adjustedAmount = shippingService.ApplyCharges(method.Id, rate.Amount);

                    result.Data.Add(new ShippingMethodViewModel()
                    {
                        Id             = method.Id,
                        ProviderPrefix = providerPrefix,
                        Carrier        = method.CarrierName,
                        Name           = ShippingUtils.PrepareMethodNameToDisplay(method.Name, deliveryDaysInfo),
                        Rate           = adjustedAmount,
                    });
                }
            }

            return(result);
        }
예제 #23
0
        public bool IsAccept(OrderToTrackDTO orderToTrackInfo,
                             string status,
                             DateTime?statusDate,
                             IList <TrackingRecord> records)
        {
            var now   = _time.GetAppNowTime();
            var today = _time.GetAppNowTime().Date;

            var lastRecord    = records.FirstOrDefault();
            var packageGoBack = (lastRecord != null ? _addressService.IsMine(lastRecord.AsAddressDto()) : false) ||
                                orderToTrackInfo.DeliveredStatus == (int)DeliveredStatusEnum.DeliveredToSender;

            //почта после 60 дней за них не отвечает
            //старше 55 дней
            if (statusDate.HasValue &&
                statusDate.Value.AddDays(55) < today)
            {
                return(false);
            }

            if (packageGoBack)
            {
                return(false); //No actions if package go back
            }
            if (orderToTrackInfo.Carrier == ShippingServiceUtils.USPSCarrier)
            {
                if (statusDate.HasValue &&
                    !_time.IsBusinessDay(statusDate.Value) &&
                    _time.GetBizDaysCount(statusDate.Value, today) < 2)
                {
                    //TASK: Let’s not send Exception messages for First Class packages if they were not delivered on Weekends/holidays.
                    if (orderToTrackInfo.ShippingMethodId.HasValue
                        &&
                        ShippingUtils.GetShippingType(orderToTrackInfo.ShippingMethodId.Value) ==
                        ShippingTypeCode.Standard)
                    {
                        //Don’t send notice to first class orders which USPS tried to deliver on Saturday.
                        //They will automatically will redeliver it on the next business day.
                        return(false);
                    }


                    //TASK: if any package couldn’t be delivered to FF on weekends/holidays
                    if (AddressHelper.IsFFAddress(orderToTrackInfo.ShippingAddress))
                    {
                        return(false);
                    }
                }

                //TASK: If First Class order wasn’t delivered like 102-1600419-5915438 check again in 24 hours, and only then send notifications.
                if (orderToTrackInfo.ShippingMethodId.HasValue
                    &&
                    ShippingUtils.GetShippingType(orderToTrackInfo.ShippingMethodId.Value) == ShippingTypeCode.Standard)
                {
                    var statusNextBusiessDay = _time.AddBusinessDays(statusDate, 1);
                    if (statusNextBusiessDay > now)
                    {
                        return(false);
                    }
                }

                if (!String.IsNullOrEmpty(status) &&
                    (status.IndexOf("Notice Left", StringComparison.InvariantCultureIgnoreCase) >= 0 ||
                     status.IndexOf("Receptacle Blocked", StringComparison.CurrentCultureIgnoreCase) >= 0 ||
                     status.IndexOf("Available for Pickup", StringComparison.InvariantCultureIgnoreCase) >= 0 ||
                     status.IndexOf("Business Closed", StringComparison.OrdinalIgnoreCase) >= 0 ||
                     status.IndexOf("Undeliverable as Addressed", StringComparison.OrdinalIgnoreCase) >= 0 ||
                     status.IndexOf("Addressee not available", StringComparison.OrdinalIgnoreCase) >= 0) &&
                    statusDate.HasValue)
                {
                    return(true);
                }
            }

            if (orderToTrackInfo.Carrier == ShippingServiceUtils.DHLCarrier ||
                orderToTrackInfo.Carrier == ShippingServiceUtils.DHLMXCarrier)
            {
                if (!String.IsNullOrEmpty(status) &&
                    status.IndexOf("Delivery attempted; recipient not home", StringComparison.InvariantCultureIgnoreCase) >= 0 &&
                    statusDate.HasValue)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #24
0
        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
            });
        }
예제 #25
0
        public void ProcessSystemAction(CancellationToken cancelToken)
        {
            var syncInfo = new EmptySyncInformer(_log, SyncType.Orders);

            using (var db = _dbFactory.GetRWDb())
            {
                var updateRateActions = _actionService.GetUnprocessedByType(db, SystemActionType.UpdateRates, null, null);

                foreach (var action in updateRateActions)
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        return;
                    }

                    var actionStatus = SystemActionStatus.None;
                    try
                    {
                        var inputData = SystemActionHelper.FromStr <UpdateRatesInput>(action.InputData);
                        var orderId   = inputData.OrderId;
                        if (!orderId.HasValue && !String.IsNullOrEmpty(inputData.OrderNumber))
                        {
                            var order = db.Orders.GetByOrderNumber(inputData.OrderNumber);
                            orderId = order.Id;
                        }

                        if (orderId.HasValue)
                        {
                            var orderIdList            = new long[] { orderId.Value };
                            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))

                                    || dtoOrder.BatchId.HasValue) //NOTE: SKip orders in batch
                                {
                                    actionStatus = SystemActionStatus.Skipped;
                                }
                                else
                                {
                                    var markets = new MarketplaceKeeper(_dbFactory, false);
                                    markets.Init();
                                    var companyAddress = new CompanyAddressService(_company, markets.GetAll());
                                    var synchronizer   = new AmazonOrdersSynchronizer(_log,
                                                                                      _company,
                                                                                      syncInfo,
                                                                                      _rateProviders,
                                                                                      companyAddress,
                                                                                      _time,
                                                                                      _weightService,
                                                                                      _messageService);
                                    if (!synchronizer.UIUpdate(db, dtoOrder, false, false, keepCustomShipping: false, switchToMethodId: null))
                                    {
                                        actionStatus = SystemActionStatus.Fail;
                                    }
                                    else
                                    {
                                        actionStatus = SystemActionStatus.Done;
                                    }
                                }
                            }

                            _log.Info("Order rates was recalculated, actionId=" + action.Id + ", status=" + actionStatus);
                        }
                        else
                        {
                            actionStatus = SystemActionStatus.NotFoundEntity;
                            _log.Info("Can't find order, actionId=" + action.Id + ", orderId=" + inputData.OrderId + ", orderNumber=" + inputData.OrderNumber);
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Error("Fail recalculate order rates action, actionId=" + action.Id, ex);
                        actionStatus = SystemActionStatus.Fail;
                    }

                    _actionService.SetResult(db,
                                             action.Id,
                                             actionStatus,
                                             null,
                                             null);
                }

                db.Commit();
            }
        }
예제 #26
0
        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 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.OrderType != (int)OrderTypeEnum.Prime)
            {
                return new CheckResult()
                       {
                           IsSuccess = false
                       }
            }
            ;

            var serviceType = marketOrder.InitialServiceType;

            if (ShippingUtils.IsServiceTwoDays(serviceType) ||
                ShippingUtils.IsServiceNextDay(serviceType))
            {
                return new CheckResult()
                       {
                           IsSuccess = false
                       }
            }
            ;

            if (shippings != null)
            {
                //NOTE: send notification when Prime order has only express service optionas (when it is has originally priority service)
                var activeShipping = shippings.FirstOrDefault(sh => sh.IsActive);

                if (activeShipping != null &&
                    activeShipping.ShippingMethod != null &&
                    (activeShipping.ShippingMethod.Id == ShippingUtils.AmazonExpressFlatShippingMethodId ||
                     activeShipping.ShippingMethod.Id == ShippingUtils.AmazonExpressRegularShippingMethodId))
                {
                    _emailService.SendSystemEmail("Prime order issue #" + marketOrder.OrderId,
                                                  "Prime order hasn't priority rates",
                                                  EmailHelper.RafiEmail,
                                                  EmailHelper.SupportDgtexEmail);
                    _log.Info("Send prime notification email, orderId=" + marketOrder.Id);

                    db.OrderComments.Add(new OrderComment()
                    {
                        OrderId    = marketOrder.Id,
                        Message    = "[System] Prime order hasn't priority rates",
                        Type       = (int)CommentType.OutputEmail,
                        CreateDate = _time.GetAppNowTime(),
                        UpdateDate = _time.GetAppNowTime()
                    });
                    db.Commit();

                    return(new CheckResult()
                    {
                        IsSuccess = true
                    });
                }
            }

            return(new CheckResult()
            {
                IsSuccess = false
            });
        }
    }
}
예제 #28
0
        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();
            }
        }
예제 #29
0
        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);
        }
예제 #30
0
        private bool UpdateOrder(IUnitOfWork db, ShippingDTO shipping)
        {
            _log.Info("Update order: id=" + shipping.OrderId + ", orderId=" + shipping.AmazonIdentifier + ", marketId=" + shipping.MarketOrderId);

            IList <OrderItemDTO> orderItems;

            if (shipping.IsFromMailPage)
            {
                orderItems = db.OrderItems.GetByOrderIdAsDto(shipping.OrderId)
                             //Remove canceled items with 0 price
                             .Where(m => m.ItemPrice > 0 || m.QuantityOrdered > 0).ToList();
            }
            else
            {
                orderItems = db.OrderItems.GetByShippingInfoIdAsDto(shipping.Id)
                             //Remove canceled items with 0 price
                             .Where(m => m.ItemPrice > 0 || m.QuantityOrdered > 0).ToList();
            }

            OrderHelper.PrepareSourceItemOrderId(orderItems);
            orderItems = OrderHelper.GroupBySourceItemOrderId(orderItems);

            DateTime?orderDate = null;

            if (shipping.OrderDate.HasValue)
            {
                orderDate = shipping.OrderDate.Value.ToUniversalTime();
            }
            var shippingDate = shipping.ShippingDate.ToUniversalTime();

            if (orderDate.HasValue && shippingDate < orderDate)
            {
                shippingDate = orderDate.Value.AddHours(2);
            }


            var result = _api.SubmitTrackingInfo(shipping.MarketOrderId,
                                                 shipping.TrackingNumber,
                                                 MarketUrlHelper.GetTrackingUrl(shipping.TrackingNumber, shipping.ShippingMethod.CarrierName),
                                                 shipping.ShippingMethod,
                                                 shipping.ShippingMethod.Name,
                                                 ShippingUtils.GetShippingType(shipping.ShippingMethodId),
                                                 ShippingUtils.FormattedToMarketCurrierName(shipping.ShippingMethod.CarrierName, shipping.ShippingMethod.IsInternational, _api.Market),
                                                 shippingDate,
                                                 orderItems,
                                                 shipping.MessageIdentifier.ToString());

            if (result.Status == CallStatus.Success)
            {
                _log.Info("Order was updated");
            }
            else
            {
                _log.Info("Order update errors: Message=" + result.Message);

                /*
                 * Walmart.Api.WalmartException: No response, statusCode=InternalServerError.
                 * Details: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns4:errors xmlns:ns2="http://walmart.com/mp/orders" xmlns:ns3="http://walmart.com/mp/v3/orders" xmlns:ns4="http://walmart.com/"><ns4:error><ns4:code>INVALID_REQUEST_CONTENT.GMP_ORDER_API</ns4:code><ns4:field>data</ns4:field><ns4:description>Unable to process this request. The Line: 4 of PO: 4576930294354 is in SHIPPED status</ns4:description><ns4:info>Request content is invalid.</ns4:info><ns4:severity>ERROR</ns4:severity><ns4:category>DATA</ns4:category><ns4:causes/><ns4:errorIdentifiers/></ns4:error></ns4:errors> ---> System.Net.WebException: The remote server returned an error: (400) Bad Request.
                 */
            }

            return(result.Status == CallStatus.Success);
        }