public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            var orderIdList = new List <string>();

            if (result.MatchedIdList != null)
            {
                orderIdList.AddRange(result.MatchedIdList);
            }

            orderIdList = orderIdList.Distinct().ToList();

            foreach (var orderId in orderIdList)
            {
                var existDb = db.FeedbackBlackLists.GetAll().FirstOrDefault(o => o.OrderId == orderId);
                if (existDb == null)
                {
                    _log.Debug("Add to black list orderId=" + orderId);
                    db.FeedbackBlackLists.Add(new FeedbackBlackList()
                    {
                        OrderId    = orderId,
                        Reason     = "[Auto] Has related email messages",
                        CreateDate = _time.GetAppNowTime()
                    });
                }
            }
            db.Commit();
        }
Exemple #2
0
        public void TestProcessSampleReturnRequestEmail()
        {
            var smtpSettings  = SettingsBuilder.GetSmtpSettingsFromAppSettings();
            var emailService  = new EmailService(_log, smtpSettings, _addressService);
            var actionService = new SystemActionService(_log, _time);

            var rule = new ReturnRequestEmailRule(_log, _time, emailService, actionService, _company, false, true);

            using (var db = _dbFactory.GetRWDb())
            {
                var email = db.Emails.Get(4687);

                var matchingResult = new EmailReadingResult()
                {
                    Email = new EmailDTO()
                    {
                        Subject = email.Subject,
                        Message = email.Message,
                    },
                    Status        = EmailMatchingResultStatus.New,
                    MatchedIdList = new string[] { "002-1602056-5981826" }
                };

                rule.Process(db, matchingResult);
            }
        }
Exemple #3
0
        public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            var wasModified = false;
            var body        = EmailHelper.CutOutBody(result.Email.Message, out wasModified);

            if (wasModified)
            {
                _log.Info("Body was updated, emailId=" + result.Email.Id);

                var email = db.Emails.Get(result.Email.Id);
                email.Message = body;
                db.Commit();
            }

            //if (result.Email.From.Contains("ebay.com"))
            //{
            //    RegexOptions options = RegexOptions.None;
            //    Regex regex = new Regex("(<br/>|<br>){2,}", options);
            //    var ebayBody = regex.Replace(result.Email.Message, " ");

            //    var email = db.Emails.Get(result.Email.Id);
            //    email.Message = ebayBody;
            //    db.Commit();

            //    _log.Info("Prepared eBay body, emailId=" + email.Id);
            //}
        }
        public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            if (result.Status == EmailMatchingResultStatus.New
                //&& result.HasMatches //NOTE: also mark w/o matches
                && result.Email.Type != (int)IncomeEmailTypes.Test &&
                (EmailHelper.GetFolderType(result.Folder) == EmailFolders.Sent ||
                 EmailHelper.IsAutoCommunicationAddress(result.Email.From)))
            {
                //Get by subject
                var subject     = EmailHelper.GetWoReplySubject(result.Email.Subject);
                var existEmails = db.Emails
                                  .GetFiltered(e => e.Subject == subject &&
                                               String.IsNullOrEmpty(e.AnswerMessageID) &&
                                               e.FolderType == (int)EmailFolders.Inbox)
                                  .ToList();
                existEmails = existEmails.Where(e => !String.IsNullOrEmpty(e.From) && e.From.Contains(result.Email.To)).ToList();

                //If no results, all unanswered with the same order ids
                if (!existEmails.Any() ||
                    (result.Email.To ?? "").Contains("relay.walmart.com"))    //NOTE: For Walmart always add unanswered emails related to order; each email has own from address; so multiple equal emails would be unanswered!
                {
                    var emailIds = db.EmailToOrders
                                   .GetAll()
                                   .Where(eo => result.MatchedIdList.Contains(eo.OrderId))
                                   .Select(eo => eo.EmailId)
                                   .Distinct()
                                   .ToList();
                    existEmails = db.Emails
                                  .GetFiltered(e => emailIds.Contains(e.Id) &&
                                               String.IsNullOrEmpty(e.AnswerMessageID) &&
                                               e.FolderType == (int)EmailFolders.Inbox)
                                  .ToList();
                }

                if (existEmails.Any())
                {
                    foreach (var email in existEmails)
                    {
                        if (email.ReceiveDate < result.Email.ReceiveDate && email.ReceiveDate > result.Email.ReceiveDate.AddDays(-10)) //Mark Answered only previos emails, during 10 days
                        {
                            _log.Info("Mark as answered, emailId=" + email.Id + ", subject=" + email.Subject);
                            email.AnswerMessageID = result.Email.MessageID;
                            if (email.ResponseStatus != (int)EmailResponseStatusEnum.ResponsePromised)
                            {
                                email.ResponseStatus = (int)EmailResponseStatusEnum.ReceivedFromMailbox;
                            }
                        }
                    }
                    db.Commit();
                }
                else
                {
                    _log.Info("No emails to mark as answered");
                }
            }
        }
 public void Process(IUnitOfWork db,
                     EmailReadingResult result)
 {
     if (result.Status == EmailMatchingResultStatus.New &&
         result.Email.Type == (int)IncomeEmailTypes.DhlInvoice)
     {
         var attachment = result.Email.Attachments.FirstOrDefault();
         if (attachment != null)
         {
             _log.Info("Process DHL Invoice, path=" + attachment.PhysicalPath);
             var dhlService = new DhlInvoiceService(_log, _time, _dbFactory);
             var records    = dhlService.GetRecordsFromFile(attachment.PhysicalPath);
             dhlService.ProcessRecords(records, ShipmentProviderType.Dhl);
         }
     }
 }
 public void Process(IUnitOfWork db, EmailReadingResult result)
 {
     if (result.Email.FolderType == (int)EmailFolders.Sent)
     {
         if (result.Headers != null && result.Headers[EmailHelper.UserNameHeadersKey] != null)
         {
             var userId = result.Headers[EmailHelper.UserNameHeadersKey];
             _log.Info("Headers contain userId=" + userId);
             var user = db.Users.GetAllAsDto().FirstOrDefault(u => !u.Deleted && u.Id.ToString() == userId);
             if (user != null)
             {
                 var email = db.Emails.Get(result.Email.Id);
                 email.CreatedBy = user.Id;
                 db.Commit();
             }
         }
     }
 }
Exemple #7
0
        public void Process(IUnitOfWork db,
                            EmailReadingResult result)
        {
            if (result.Status == EmailMatchingResultStatus.New &&
                result.HasMatches)
            {
                var cancelRequested =
                    (result.Email.Subject ?? "").IndexOf("Order cancellation request from Amazon customer", StringComparison.OrdinalIgnoreCase) >= 0 ||
                    ((result.Email.Subject ?? "").IndexOf("Walmart.com Customer:", StringComparison.OrdinalIgnoreCase) >= 0 &&
                     (result.Email.Subject ?? "").IndexOf("Cancel Order", StringComparison.OrdinalIgnoreCase) >= 0) ||    //NOTE: Walmart subject may have differenct spaces count
                    ((result.Email.Subject ?? "").IndexOf("Walmart.ca Customer:", StringComparison.OrdinalIgnoreCase) >= 0 &&
                     (result.Email.Subject ?? "").IndexOf("Order cancellation request", StringComparison.OrdinalIgnoreCase) >= 0) ||
                    (StringHelper.IsEqualNoCase(result.Email.Subject, "Please contact the customer - Request Cancel"));

                if (cancelRequested)
                {
                    _log.Info("Received OrderCancellation request, orderNumbers=" + String.Join(", ", result.MatchedIdList));

                    var orders = db.Orders.GetAllByCustomerOrderNumbers(result.MatchedIdList);
                    if (orders.Count > 1)
                    {
                        throw new ArgumentException("Multiple orders suite to canceled order Id, orderNumbers=" + String.Join(", ", result.MatchedIdList), "orderId");
                    }

                    if (orders.Any())
                    {
                        foreach (var order in orders)
                        {
                            _log.Info("Received OrderCancellation request, orderNumber=" + order.AmazonIdentifier);
                            var orderNumber = order.AmazonIdentifier;

                            CancelOrder(db, result, orderNumber, order);
                        }
                    }
                    else
                    {
                        var orderNumber = result.MatchedIdList.FirstOrDefault();
                        _log.Info("Received OrderCancellation request, orderNumber=" + orderNumber);
                        _log.Info("Order not found");
                        CancelOrder(db, result, result.MatchedIdList.FirstOrDefault(), null);
                    }
                }
            }
        }
Exemple #8
0
        public void RecheckAllRefundEmails()
        {
            var smtpSettings  = SettingsBuilder.GetSmtpSettingsFromAppSettings();
            var emailService  = new EmailService(_log, smtpSettings, _addressService);
            var actionService = new SystemActionService(_log, _time);

            var rule = new RefundEmailRule(_log, _time, emailService, actionService, _company,
                                           enableSendEmail: false,
                                           existanceCheck: true);

            using (var db = _dbFactory.GetRWDb())
            {
                var fromDate = DateTime.Now.AddDays(-35);
                var emails   = db.Emails.GetAll()
                               .Where(e => e.CreateDate > fromDate &&
                                      e.Subject.Contains("Refund initiated for order"))
                               .ToList();
                var emailToOrderList = db.EmailToOrders.GetAll().ToList();

                foreach (var email in emails)
                {
                    var emailToOrder = emailToOrderList.FirstOrDefault(e => e.EmailId == email.Id);

                    if (emailToOrder == null)
                    {
                        continue;
                    }

                    var matchingResult = new EmailReadingResult()
                    {
                        Email = new EmailDTO()
                        {
                            Subject = email.Subject,
                            Message = email.Message,
                        },
                        Status        = EmailMatchingResultStatus.New,
                        MatchedIdList = new string[] { emailToOrder.OrderId }
                    };

                    rule.Process(db, matchingResult);
                }
            }
        }
Exemple #9
0
        public void TestProcessOrderCancellationEmail(long emailId)
        {
            var smtpSettings  = SettingsBuilder.GetSmtpSettingsFromAppSettings();
            var emailService  = new EmailService(_log, smtpSettings, _addressService);
            var actionService = new SystemActionService(_log, _time);

            var emailProcessingService = new EmailProcessingService(
                _log,
                _dbFactory,
                emailService,
                actionService,
                _company,
                _time);

            using (var db = _dbFactory.GetRWDb())
            {
                var email = db.Emails.Get(emailId);

                var matchingResult = new EmailReadingResult()
                {
                    Email = new EmailDTO()
                    {
                        Subject = email.Subject,
                        Message = email.Message,
                    },
                    Status        = EmailMatchingResultStatus.New,
                    MatchedIdList = new string[] { "4442088617765" }
                };

                IList <IEmailRule> rules = new List <IEmailRule>()
                {
                    //new SetSystemTypesEmailRule(_log, _time),
                    //new AddMatchIdsEmailRule(_log, _time),
                    new CancellationEmailRule(_log, _time, emailService, actionService, _company),
                };

                emailProcessingService.ProcessEmails(new List <EmailReadingResult>()
                {
                    matchingResult
                }, rules);
            }
        }
Exemple #10
0
        public void RecheckSetSystemTypeRule(long emailId)
        {
            var smtpSettings  = SettingsBuilder.GetSmtpSettingsFromAppSettings();
            var emailService  = new EmailService(_log, smtpSettings, _addressService);
            var actionService = new SystemActionService(_log, _time);

            var rule = new SetSystemTypesEmailRule(_log, _time);

            using (var db = _dbFactory.GetRWDb())
            {
                var fromDate = DateTime.Now.AddDays(-35);
                var emails   = db.Emails.GetAll()
                               .Where(e => e.Id == emailId)
                               .ToList();
                var emailToOrderList = db.EmailToOrders.GetAll().ToList();

                foreach (var email in emails)
                {
                    var emailToOrder = emailToOrderList.FirstOrDefault(e => e.EmailId == email.Id);

                    if (emailToOrder == null)
                    {
                        continue;
                    }

                    var matchingResult = new EmailReadingResult()
                    {
                        Email = new EmailDTO()
                        {
                            From    = email.From,
                            Subject = email.Subject,
                            Message = email.Message,
                        },
                        Status        = EmailMatchingResultStatus.New,
                        MatchedIdList = new string[] { emailToOrder.OrderId }
                    };

                    rule.Process(db, matchingResult);
                }
            }
        }
Exemple #11
0
        private void CancelOrder(IUnitOfWork db,
                                 EmailReadingResult result,
                                 string orderNumber,
                                 Order order)
        {
            if (!String.IsNullOrEmpty(orderNumber))
            {
                var itemId = EmailHelper.ExtractWalmartItemId(result.Email.Message);

                _log.Info("ItemId=" + itemId);

                var existCancellationActions = _systemAction.GetByTypeAndTag(db,
                                                                             SystemActionType.UpdateOnMarketCancelOrder, orderNumber);
                var isExistCancelRequest = existCancellationActions.Any();

                if (existCancellationActions.Any() &&
                    order != null &&
                    (order.Market == (int)MarketType.Walmart ||
                     order.Market == (int)MarketType.WalmartCA))   //NOTE: for Walmart checking by item cancallation
                {
                    var existItemCancallation = false;
                    foreach (var action in existCancellationActions)
                    {
                        var data = JsonConvert.DeserializeObject <CancelOrderInput>(action.InputData);
                        if (data.ItemId == itemId)
                        {
                            existItemCancallation = true;
                        }
                    }
                    isExistCancelRequest = existItemCancallation;
                }

                if (!isExistCancelRequest)
                {
                    result.WasEmailProcessed = true;
                    _log.Info("CancellationEmailRule, WasEmailProcessed=" + result.WasEmailProcessed);

                    var comment = "";

                    //NOTE: "system to cancel that order if it wasn’t shipped and it’s not assigned to Active Batch yet, and send client an email"
                    //NOTE: if no order in system
                    if (order == null ||
                        ((order.OrderStatus == OrderStatusEnumEx.Unshipped ||
                          order.OrderStatus == OrderStatusEnumEx.Pending ||
                          order.OrderStatus == OrderStatusEnumEx.Canceled) &&
                         !order.BatchId.HasValue))
                    {
                        _log.Info("Order status was changed to Canceled, orderNumber=" + orderNumber);

                        SystemActionHelper.AddCancelationActionSequences(db,
                                                                         _systemAction,
                                                                         order.Id,
                                                                         orderNumber,
                                                                         itemId,
                                                                         result.Email.Id,
                                                                         result.Email.From,
                                                                         (order != null && (order.Market == (int)MarketType.Walmart || order.Market == (int)MarketType.WalmartCA)) ? result.Email.Subject : null,
                                                                         EmailHelper.ExtractShortMessageBody(result.Email.Message, 200, true),
                                                                         null,
                                                                         CancelReasonType.PerBuyerRequest);

                        if (order != null && order.Market != (int)MarketType.Walmart && order.Market != (int)MarketType.WalmartCA)
                        //NOTE: Exclude Walmart, cancellation happen only for one item
                        {
                            order.OrderStatus = OrderStatusEnumEx.Canceled;
                        }
                        //if (order != null && (order.Market == (int) MarketType.Walmart || order.Market == (int)MarketType.WalmartCA))
                        //{
                        //    if (!order.BatchId.HasValue) //Only when not in batch
                        //    {
                        //        var orderItemLineCount = db.OrderItems.GetByOrderIdAsDto(order.Id).Count();
                        //        if (orderItemLineCount > 1)
                        //        {
                        //            _log.Info("Walmart Order set OnHold, in case it has more then one item line = " + orderItemLineCount);
                        //            order.OnHold = true;

                        //            db.OrderComments.Add(new OrderComment()
                        //            {
                        //                OrderId = order.Id,
                        //                Message = String.Format("[System] Partial email cancellation request, 1 / {0} order lines", orderItemLineCount),
                        //                Type = (int)CommentType.ReturnExchange,
                        //                LinkedEmailId = result.Email.Id,
                        //                CreateDate = _time.GetAppNowTime(),
                        //                UpdateDate = _time.GetAppNowTime(),
                        //            });
                        //        }
                        //    }
                        //}

                        if (order != null)
                        {
                            comment = "Marked as cancelled + emailed";

                            db.OrderNotifies.Add(new OrderNotify()
                            {
                                OrderId    = order.Id,
                                Status     = 1,
                                Type       = (int)OrderNotifyType.CancellationRequest,
                                Params     = itemId,
                                Message    = "Email cancelation request in progress",
                                CreateDate = _time.GetAppNowTime(),
                            });
                        }
                    }
                    else
                    {
                        var commentText =
                            "[System] Email cancelation request wasn't processed. Order already shipped.";

                        if (order.OrderStatus != OrderStatusEnumEx.Shipped)
                        {
                            db.OrderNotifies.Add(new OrderNotify()
                            {
                                OrderId    = order.Id,
                                Status     = 1,
                                Type       = (int)OrderNotifyType.CancellationRequest,
                                Params     = itemId,
                                Message    = "Email cancelation request, order in batch",
                                CreateDate = _time.GetAppNowTime(),
                            });
                        }
                        else
                        {
                            _systemAction.AddAction(db,
                                                    SystemActionType.SendEmail,
                                                    orderNumber,
                                                    new SendEmailInput()
                            {
                                EmailType      = EmailTypes.RejectOrderCancellationToBuyer,
                                OrderId        = orderNumber,
                                ReplyToEmail   = result.Email.From,
                                ReplyToSubject = result.Email.Subject,
                            },
                                                    null,
                                                    null);

                            commentText += " Email was sent to customer.";
                        }

                        db.OrderComments.Add(new OrderComment()
                        {
                            OrderId       = order.Id,
                            Message       = commentText,
                            Type          = (int)CommentType.ReturnExchange,
                            LinkedEmailId = result.Email.Id,
                            CreateDate    = _time.GetAppNowTime(),
                            UpdateDate    = _time.GetAppNowTime(),
                        });

                        comment = "Cancellation skipped";
                    }

                    db.OrderEmailNotifies.Add(new OrderEmailNotify()
                    {
                        OrderNumber = orderNumber,
                        Type        = (int)OrderEmailNotifyType.InputOrderCancelledEmail,
                        Reason      = comment,
                        CreateDate  = _time.GetUtcTime()
                    });

                    db.Commit();
                }
                else
                {
                    _log.Info("Repeated OrderCancellation email, no action");
                }
            }
            else
            {
                _log.Info("Can't OrderCancellation, no order number!");
            }
        }
Exemple #12
0
        public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            if (result.Status == EmailMatchingResultStatus.New &&
                result.HasMatches)
            {
                var subject = (result.Email.Subject ?? "");
                var today   = _time.GetAppNowTime().Date;

                //TASK: 1.	Emails which have these in subjects: "Order delivery inquiry" or " Where's My Stuff?”
                //CHANGE: When client sends an email with subject “Package didn’t arrive..” like 113-7086092-7521857, process it same way as emails with subject “Lost Package”…
                var isWhereMyStaff = subject.StartsWith("Order delivery inquiry", StringComparison.OrdinalIgnoreCase) ||
                                     subject.IndexOf("Where's My Stuff?", StringComparison.OrdinalIgnoreCase) >= 0 ||
                                     subject.IndexOf("Where's My Stuff ?", StringComparison.OrdinalIgnoreCase) >= 0 ||
                                     subject.IndexOf("Package didn’t arrive:", StringComparison.OrdinalIgnoreCase) >= 0 ||
                                     subject.IndexOf("Package didn?t arrive", StringComparison.OrdinalIgnoreCase) >= 0 ||
                                     subject.IndexOf("Shipping inquiry", StringComparison.InvariantCultureIgnoreCase) >= 0;    //NOTE: actually came with ? instead of '

                if (isWhereMyStaff)
                {
                    _log.Info("Received 'Where my stuff'");
                    var orderNumber = result.MatchedIdList.FirstOrDefault();
                    if (!String.IsNullOrEmpty(orderNumber))
                    {
                        //TASK: 2.	 Which were successfully delivered to client.
                        var order         = db.Orders.GetByOrderNumber(orderNumber);
                        var shippingInfos = db.OrderShippingInfos.GetByOrderIdAsDto(order.Id).Where(sh => sh.IsActive).ToList();
                        //a.	 delivered to client (not returned to us)
                        var delivered    = shippingInfos.Any() && shippingInfos.All(sh => sh.DeliveredStatus == (int)DeliveredStatusEnum.Delivered);
                        var deliveryDate = shippingInfos.Select(sh => sh.ActualDeliveryDate).FirstOrDefault();
                        //b.	Delivered within last 2 month.
                        if (delivered && deliveryDate.HasValue && deliveryDate > today.AddMonths(-2))
                        {
                            _log.Info("Package was delivered, withing last 2 month");

                            var alreadySendLostTemplate = db.OrderEmailNotifies.IsExist(order.AmazonIdentifier,
                                                                                        OrderEmailNotifyType.OutputLostPackageEmail);

                            //3.	To which we didn’t answer yet with Lost Package template
                            if (!alreadySendLostTemplate)
                            {
                                _log.Info("Not send package lost template");

                                var orderEmails = db.Emails.GetAllByOrderId(order.AmazonIdentifier)
                                                  .Select(m => new
                                {
                                    m.Id,
                                    m.ReceiveDate,
                                    m.Subject
                                }).ToList();
                                var isAnyOtherSimilarEmails = orderEmails.Any(e => e.Id != result.Email.Id &&
                                                                              (e.ReceiveDate <= result.Email.ReceiveDate &&
                                                                               e.Subject.Contains("Where's My Stuff?") ||
                                                                               e.Subject.Contains("Order delivery inquiry")));

                                var isAnyOtherEmailAfterDelivery = deliveryDate.HasValue && orderEmails.Any(e => e.Id != result.Email.Id &&
                                                                                                            e.ReceiveDate >= deliveryDate.Value);

                                //4.	If it’s the first email with that subject ("Order delivery inquiry" or " Where's My Stuff?”)
                                if (!isAnyOtherSimilarEmails && !isAnyOtherEmailAfterDelivery)
                                {
                                    _log.Info("Pass to Order Delivery Inquiry Rule");

                                    OrderShippingInfoDTO shippingInfo   = null;
                                    ShippingMethodDTO    shippingMethod = null;
                                    if (shippingInfos.Any())
                                    {
                                        shippingInfo = shippingInfos.OrderByDescending(sh => sh.ActualDeliveryDate)
                                                       .FirstOrDefault(i => i.IsActive);
                                        if (shippingInfo != null)
                                        {
                                            shippingMethod = db.ShippingMethods.GetByIdAsDto(shippingInfo.ShippingMethodId);
                                        }
                                    }
                                    var emailInfo = new LostPackageEmailInfo(_emailService.AddressService,
                                                                             null,
                                                                             order.AmazonIdentifier,
                                                                             (MarketType)order.Market,
                                                                             shippingInfo != null ? shippingInfo.ActualDeliveryDate : null,
                                                                             shippingInfo != null ? shippingInfo.TrackingStateEvent : null,
                                                                             shippingMethod != null ? shippingMethod.CarrierName : null,
                                                                             shippingInfo != null ? shippingInfo.TrackingNumber : null,
                                                                             order.GetAddressDto(),
                                                                             order.BuyerName,
                                                                             order.BuyerEmail);

                                    _emailService.SendEmail(emailInfo, CallSource.Service);

                                    db.OrderEmailNotifies.Add(new OrderEmailNotify()
                                    {
                                        OrderNumber = order.CustomerOrderId,
                                        Type        = (int)OrderEmailNotifyType.OutputLostPackageEmail,
                                        Reason      = "Email: " + StringHelper.Substring(subject, 40),
                                        CreateDate  = _time.GetUtcTime()
                                    });

                                    db.OrderComments.Add(new OrderComment()
                                    {
                                        OrderId    = order.Id,
                                        Type       = (int)CommentType.OutputEmail,
                                        Message    = "[System] \"Lost Package\" email sent",
                                        CreateDate = _time.GetAppNowTime(),
                                    });

                                    db.Commit();

                                    result.WasEmailProcessed = true;
                                }
                                else
                                {
                                    if (isAnyOtherSimilarEmails)
                                    {
                                        _log.Info("Similar email was found");
                                    }
                                    if (isAnyOtherEmailAfterDelivery)
                                    {
                                        _log.Info("Other email was found after delivery");
                                    }
                                }
                            }
                            else
                            {
                                _log.Info("Already sent Lost Package template");
                            }
                        }
                        else
                        {
                            _log.Info("Package not yet delivered");
                        }
                    }
                }
            }
        }
        public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            if (result.Status == EmailMatchingResultStatus.New &&
                result.HasMatches)
            {
                var subject = result.Email.Subject;

                var isChangeAddressRequest =
                    subject.StartsWith("Change shipping address inquiry", StringComparison.OrdinalIgnoreCase);

                if (isChangeAddressRequest)
                {
                    var orderNumber = result.MatchedIdList.FirstOrDefault();
                    _log.Info("Received change shipping address inquiry request, orderNumber=" + orderNumber);

                    if (!String.IsNullOrEmpty(orderNumber))
                    {
                        var isExistAddressNotChangedResponse = db.OrderEmailNotifies.IsExist(orderNumber,
                                                                                             OrderEmailNotifyType.OutputAddressNotChanged);
                        if (!isExistAddressNotChangedResponse) //NOTE: First remove change shipping address
                        {
                            var order = db.Orders.GetByOrderNumber(orderNumber);
                            if (order.OrderStatus == OrderStatusEnumEx.Shipped)
                            {
                                result.WasEmailProcessed = true;
                                _log.Info("AddressNotChangedEmailRule, WasEmailProcessed=" + result.WasEmailProcessed);

                                var emailInfo = new AddressNotChangedEmailInfo(_emailService.AddressService,
                                                                               null,
                                                                               orderNumber,
                                                                               (MarketType)order.Market,
                                                                               order.BuyerName,
                                                                               order.BuyerEmail);

                                emailInfo.ReplyToSubject = result.Email.Subject;

                                _emailService.SendEmail(emailInfo, CallSource.Service);

                                var commentText =
                                    "[System] Change shipping address inquiry came after the order shipped. Email was sent to customer.";

                                db.OrderComments.Add(new OrderComment()
                                {
                                    OrderId    = order.Id,
                                    Message    = commentText,
                                    Type       = (int)CommentType.Address,
                                    CreateDate = _time.GetAppNowTime(),
                                    UpdateDate = _time.GetAppNowTime()
                                });

                                db.Commit();
                            }
                            else
                            {
                                _log.Info("AddressNotChangedEmailRule, orderStatus=" + order.OrderStatus);
                            }
                        }
                        else
                        {
                            _log.Info("Repeated change shipping address inquiry email, no action");
                        }
                    }
                    else
                    {
                        _log.Info("Can't checked change shipping address inquiry, no matching orders!");
                    }
                }
            }
        }
        public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            result.Email.FolderType = (int)EmailHelper.GetFolderType(result.Folder);

            var type = IncomeEmailTypes.Default;

            if (result.Email.From.Contains("auto-communication@amazon"))
            {
                type = IncomeEmailTypes.SystemAutoCopy;
            }

            //Ex: FW: Return authorization request for order # 112-7446790-9716267
            if (result.Email.From.Contains("order-update@amazon"))
            {
                if (result.Email.Subject != null &&
                    (result.Email.Subject.StartsWith("Return authorization", StringComparison.InvariantCultureIgnoreCase) ||
                     result.Email.Subject.StartsWith("Return authorisation", StringComparison.InvariantCultureIgnoreCase)))
                {
                    type = IncomeEmailTypes.ReturnRequest;
                }
                else
                {
                    type = IncomeEmailTypes.System;
                }
            }

            if (result.Email.From.Contains("Your Immediate Response Required: Charge Dispute Inquiry"))
            {
                type = IncomeEmailTypes.SystemNotification;
            }

            if (result.Email.From.Contains("order-update@amazon"))
            {
                if (StringHelper.ContainsNoCase(result.Email.Subject,
                                                "Action Required: Unshipped Prime orders that need to be shipped today"))
                {
                    type = IncomeEmailTypes.SystemNotification;
                }
            }

            //Your Immediate Response Required: Charge Dispute Inquiry

            if (result.Email.From.Contains("seller-answers@amazon"))
            {
                type = IncomeEmailTypes.System;
            }

            if (result.Email.From.Contains("*****@*****.**") ||
                (result.Email.Subject != null &&
                 StringHelper.ContainsNoCase(result.Email.Subject, "A-to-z Guarantee Claim for Order")))
            {
                type = IncomeEmailTypes.AZClaim;
            }

            if (result.Email.From.Contains("*****@*****.**") &&
                (result.Email.Subject != null &&
                 (result.Email.Subject.StartsWith("Action required: Claim received on order", StringComparison.InvariantCultureIgnoreCase) ||
                  StringHelper.ContainsNoCase(result.Email.Subject, "Claim received on order"))))
            {
                type = IncomeEmailTypes.AZClaim;
            }

            if (result.Email.From.Contains("*****@*****.**") &&
                (result.Email.Subject != null &&
                 (result.Email.Subject.StartsWith("Claim Decision on Order ", StringComparison.InvariantCultureIgnoreCase))))
            {
                type = IncomeEmailTypes.System;
            }

            if (result.Email.From.Contains("*****@*****.**") &&
                (result.Email.Subject != null &&
                 result.Email.Subject.StartsWith("Refund initiated for order", StringComparison.InvariantCultureIgnoreCase)))
            {
                type = IncomeEmailTypes.SystemNotification;
            }

            //if (result.Email.From.Contains("*****@*****.**"))
            //NOTE: Need to exclude return request
            if (result.Email.From.Contains("*****@*****.**") &&
                result.Email.Subject != null &&
                (result.Email.Subject.StartsWith("Your eBay listing is confirmed:", StringComparison.InvariantCultureIgnoreCase) ||
                 result.Email.Subject.StartsWith("Your eBay item sold!", StringComparison.InvariantCultureIgnoreCase)))
            {
                type = IncomeEmailTypes.SystemNotification;
            }

            if (result.Email.Subject != null &&
                result.Email.Subject.Contains(".csv") &&
                //result.Email.To == "*****@*****.**" &&
                result.Email.Attachments != null &&
                result.Email.Attachments.Count > 0)
            {
                type = IncomeEmailTypes.DhlInvoice;
            }

            if (result.Email.Subject != null &&
                (result.Email.Subject.StartsWith("Order cancellation request from Amazon customer", StringComparison.InvariantCultureIgnoreCase) ||
                 result.Email.Subject.StartsWith("Solicitud de cancelación de pedido del cliente de Amazon", StringComparison.InvariantCultureIgnoreCase)))
            {
                type = IncomeEmailTypes.CancellationRequest;
            }

            if (result.Email.Subject != null &&
                result.Email.FolderType == (int)EmailFolders.Sent &&
                (result.Email.Subject.StartsWith("Test", StringComparison.InvariantCultureIgnoreCase) ||
                 result.Email.Subject.StartsWith("[Test", StringComparison.InvariantCultureIgnoreCase) ||
                 result.Email.Subject.StartsWith("Launch", StringComparison.InvariantCultureIgnoreCase) ||
                 result.Email.Subject.StartsWith("Print", StringComparison.InvariantCultureIgnoreCase) ||
                 result.Email.Subject.StartsWith("[System", StringComparison.InvariantCultureIgnoreCase) ||
                 StringHelper.ContainsNoCase(result.Email.Subject, "commercentric.com]")))
            {
                type = IncomeEmailTypes.Test;
            }

            result.Email.Type = (int)type;

            var email = db.Emails.Get(result.Email.Id);

            email.FolderType = result.Email.FolderType;
            email.Type       = result.Email.Type;
            db.Commit();
        }
        public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            if (result.Status == EmailMatchingResultStatus.New &&
                result.HasMatches)
            {
                var subject = result.Email.Subject ?? "";
                if (EmailHelper.IsAutoCommunicationAddress(result.Email.From) &&
                    subject.StartsWith("Your e-mail to"))
                {
                    return; //NOTE: Skip processing our emails to customer
                }

                _log.Info("AddCommentEmailRule, WasEmailProcessed=" + result.WasEmailProcessed);
                if (!result.WasEmailProcessed)
                {
                    //var orderNumber = result.MatchedIdList.FirstOrDefault();
                    var orders = db.Orders.GetAllByCustomerOrderNumbers(result.MatchedIdList);

                    var message = " > " + EmailHelper.ExtractShortSubject(result.Email.Subject);
                    message += " > " + EmailHelper.ExtractShortMessageBody(result.Email.Message, 200, true);
                    var commentText = "Customers Email" + message;
                    commentText = StringHelper.Substring(commentText, 110);

                    if (orders.Any())
                    {
                        foreach (var order in orders)
                        {
                            if ((order.OrderStatus == OrderStatusEnumEx.Unshipped ||
                                 order.OrderStatus == OrderStatusEnumEx.Pending))
                            {
                                db.OrderComments.Add(new OrderComment()
                                {
                                    OrderId       = order.Id,
                                    Message       = commentText,
                                    Type          = (int)CommentType.IncomingEmail,
                                    LinkedEmailId = result.Email.Id,
                                    CreateDate    = _time.GetAppNowTime(),
                                    UpdateDate    = _time.GetAppNowTime()
                                });

                                OrderBatchDTO batch = null;
                                if (order.BatchId.HasValue)
                                {
                                    batch = db.OrderBatches.GetAsDto(order.BatchId.Value);
                                }

                                if (batch == null || !batch.IsLocked) //Exclude set onHold to orders in locked batch
                                {
                                    order.OnHold           = true;
                                    order.OnHoldUpdateDate = _time.GetAppNowTime();
                                }

                                db.Commit();

                                _log.Info("Comment was added, orderId=" + order.AmazonIdentifier
                                          + ", customerOrderId=" + order.CustomerOrderId
                                          + ", comment=" + commentText);
                            }
                        }
                    }
                    else
                    {
                        _log.Info("No exist orders");
                        foreach (var orderNumber in result.MatchedIdList)
                        {
                            _log.Info("Action add comment was added, orderId=" + orderNumber);
                            _actionService.AddAction(db,
                                                     SystemActionType.AddComment,
                                                     orderNumber,
                                                     new AddCommentInput()
                            {
                                OrderNumber   = orderNumber,
                                Message       = message,
                                Type          = (int)CommentType.IncomingEmail,
                                LinkedEmailId = result.Email.Id,
                            },
                                                     null,
                                                     null);
                        }
                    }
                }
            }
        }
Exemple #16
0
        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 void Process(IUnitOfWork db, EmailReadingResult result)
        {
            if (result.Status != EmailMatchingResultStatus.New ||
                !result.HasMatches)
            {
                return;
            }

            var subject       = result.Email.Subject ?? "";
            var refundRequest = subject.StartsWith("Refund initiated for order");

            if (refundRequest)
            {
                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);

                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();

                //-- Refund Amount: $15.66
                var amountText = StringHelper.GetTextBetween(result.Email.Message, "Refund Amount: ", new string[] { "\r", "\n", " " });
                amountText = StringHelper.RemoveWhitespace(amountText ?? "").Replace("$", "");
                var amountValue = StringHelper.TryGetDecimal(amountText);
                if (!amountValue.HasValue ||
                    amountValue == 0)
                {
                    return;
                }

                if (_existanceCheck)
                {
                    var existRefunds = db.SystemActions.GetAll().Where(r => r.Tag == orderNumber &&
                                                                       r.Type == (int)SystemActionType.UpdateOnMarketReturnOrder).ToList();
                    if (existRefunds.Any())
                    {
                        foreach (var existRefund in existRefunds)
                        {
                            var data        = JsonConvert.DeserializeObject <ReturnOrderInput>(existRefund.InputData);
                            var existAmount = RefundHelper.GetAmount(data);
                            if (existAmount == amountValue)
                            {
                                //Already exist
                                if (existRefund.Status == (int)SystemActionStatus.Fail)
                                {
                                    _log.Info("Mark exist refund as done: " + amountValue + ", order: " + data.OrderNumber);
                                    existRefund.Status = (int)SystemActionStatus.Done;
                                    db.Commit();
                                }
                                else
                                {
                                    _log.Info("Already exist");
                                }
                                return;
                            }
                            else
                            {
                                //Not exist
                            }
                        }
                    }
                }

                _systemAction.AddAction(db,
                                        SystemActionType.UpdateOnMarketReturnOrder,
                                        order.AmazonIdentifier,
                                        new ReturnOrderInput()
                {
                    OrderId      = order.Id,
                    OrderNumber  = order.AmazonIdentifier,
                    RefundAmount = amountValue,
                    RefundReason = (int)RefundReasonCodes.Return
                },
                                        null,
                                        null,
                                        SystemActionStatus.Done);

                _log.Info("Refund added to DB, amount=" + amountValue);
            }
        }
Exemple #18
0
        public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            if (result.Status != EmailMatchingResultStatus.New)
            {
                return;
            }

            var fromAddress = result.Email.From;
            var toAddress   = result.Email.To;

            var orderIdList = new List <string>();

            var marketFromInfo = MarketHelper.GetMarketNameByEmailAddress(fromAddress);
            var marketToInfo   = MarketHelper.GetMarketNameByEmailAddress(toAddress);

            //At first process only specified marketplaces
            if (marketFromInfo.Market == MarketType.eBay ||
                marketToInfo.Market == MarketType.eBay)
            {
                if (!orderIdList.Any())
                {
                    orderIdList.AddRange(EmailParserHelper.GetEBayAssociatedOrderIds(result.Email.Message));
                }
            }

            if (marketFromInfo.Market == MarketType.Walmart ||
                marketToInfo.Market == MarketType.Walmart)
            {
                if (!orderIdList.Any())
                {
                    orderIdList.AddRange(EmailParserHelper.GetWalmartAssociatedOrderIds(result.Email.Subject).ToList());
                }

                if (!orderIdList.Any())
                {
                    orderIdList.AddRange(EmailParserHelper.GetWalmartAssociatedOrderIds(result.Email.Message));
                }
            }

            if (marketFromInfo.Market == MarketType.WalmartCA ||
                marketToInfo.Market == MarketType.WalmartCA ||
                marketFromInfo.Market == MarketType.Walmart ||
                marketToInfo.Market == MarketType.Walmart)
            {
                if (!orderIdList.Any())
                {
                    orderIdList.AddRange(EmailParserHelper.GetWalmartCAAssociatedOrderIds(result.Email.Subject).ToList());
                }

                if (!orderIdList.Any())
                {
                    orderIdList.AddRange(EmailParserHelper.GetWalmartCAAssociatedOrderIds(result.Email.Message));
                }
            }

            //Amazon
            //NOTE: Default amazon body processing
            if (!orderIdList.Any())
            {
                orderIdList.AddRange(EmailParserHelper.GetAmazonAssociatedOrderIds(result.Email.Subject).ToList());
            }
            if (!orderIdList.Any())
            {
                orderIdList.AddRange(EmailParserHelper.GetAmazonAssociatedOrderIds(result.Email.Message)); //Use body only when subject hasn't any orderId (Amazon orders get a lot of trash numbers)
            }
            var emailOrderIds = new List <string>();

            if (result.Email.FolderType == (int)EmailFolders.Inbox)
            {
                var orderByEmail = db.Orders.GetAll()
                                   .OrderByDescending(o => o.OrderDate)
                                   .FirstOrDefault(o => o.BuyerEmail == fromAddress);

                if (orderByEmail != null &&
                    !orderIdList.Contains(orderByEmail.CustomerOrderId))    //NOTE: ignore OrderId if already exist in Subject/Bodu
                {
                    emailOrderIds.Add(orderByEmail.CustomerOrderId);
                }
            }

            if (result.Email.FolderType == (int)EmailFolders.Sent)
            {
                var orderByEmail = db.Orders.GetAll()
                                   .OrderByDescending(o => o.OrderDate)
                                   .FirstOrDefault(o => o.BuyerEmail == toAddress);

                if (orderByEmail != null &&
                    !orderIdList.Contains(orderByEmail.CustomerOrderId))    //NOTE: ignore OrderId if already exist in Subject/Bodu
                {
                    emailOrderIds.Add(orderByEmail.CustomerOrderId);
                }
            }

            if (!orderIdList.Any())
            {
                if (result.Email.FolderType == (int)EmailFolders.Inbox)
                {
                    //NOTE: checking other emails from that address, if we have any assigned recently (not more than 3 months) and haven't multiple options assign it
                    var checkFromDate       = _time.GetAppNowTime().AddMonths(-3);
                    var otherAssignedEmails = (from e in db.Emails.GetAll()
                                               join eToO in db.EmailToOrders.GetAll() on e.Id equals eToO.EmailId
                                               where e.From == fromAddress &&
                                               e.ReceiveDate > checkFromDate
                                               select eToO.OrderId).Distinct().ToList();
                    if (otherAssignedEmails.Count() == 1)
                    {
                        emailOrderIds.Add(otherAssignedEmails.First());
                    }
                }
            }

            orderIdList.AddRange(emailOrderIds);
            orderIdList = orderIdList.Distinct().ToList();

            _log.Info("Id: " + result.Email.Id + ", order matches: " + String.Join(", ", orderIdList));
            if (orderIdList.Any())
            {
                var orders = db.Orders.GetAllByCustomerOrderNumbers(orderIdList);
                if (orders.Any())
                {
                    var newOrderIdList = new List <string>();
                    foreach (var order in orders)
                    {
                        if (!newOrderIdList.Contains(order.CustomerOrderId))
                        {
                            _log.Info("Add CustomerOrderId matchId: " + order.CustomerOrderId);
                            newOrderIdList.Add(order.CustomerOrderId);
                        }
                    }
                    if (newOrderIdList.Any(o => !emailOrderIds.Contains(o)))
                    {
                        newOrderIdList = newOrderIdList.Where(o => !emailOrderIds.Contains(o)).ToList(); //NOTE: remove from orderIdList by email orderId when exist other orderIds, email orderId is optional, uses when no other order mappings
                    }
                    orderIdList = newOrderIdList;                                                        //NOTE: Replace OrderIds with real orderIds (ex. Walmart Purchase Order # with Customer Order #)
                }

                foreach (var orderId in orderIdList)
                {
                    _log.Info("Add new Order match, orderId=" + orderId);
                    db.EmailToOrders.Add(new EmailToOrder()
                    {
                        EmailId    = result.Email.Id,
                        OrderId    = orderId,
                        CreateDate = _time.GetAppNowTime()
                    });
                }
                db.Commit();
            }
            else
            {
                _log.Info("No order matches");
            }

            result.MatchedIdList = orderIdList.ToArray();
        }
        private void GetEmail(IDbFactory dbFactory, ImapClient imap, DateTime scanDate, uint uid, string folder)
        {
            _threadExceptions.Clear();

            using (var db = dbFactory.GetRWDb())
            {
                //TODO: checking by UID only if UIDValidity the same after select folder
                var folderType = EmailHelper.GetFolderType(folder);
                var existEmail = db.Emails.GetByUid(uid, folderType);

                if (existEmail == null)
                {
                    _log.Info("Start email processing, uid: " + uid + ", folder=" + folder);
                    try
                    {
                        EmailReadingResult readingResult = null;

                        _log.Info("Start GetMessageHeaders()");
                        var messageHeaders = imap.GetMessage(uid, FetchOptions.HeadersOnly, false, folder);
                        _log.Info("Eng GetMessageHeaders()");

                        //TODO: Now not working (no logic to read labels from headers)
                        var labels = EmailParserHelper.GetMessageLabels(messageHeaders.Headers);
                        _log.Info("Labels: " + labels);

                        var messageID    = EmailParserHelper.GetMessageID(messageHeaders.Headers);
                        var existPOEmail = db.Emails.GetByMessageID(messageID);
                        if (existPOEmail != null)
                        {
                            db.Emails.UpdateUID(existPOEmail.Id, uid);
                            _log.Info("UID updated:" + uid + "for exist email, subject: " + existPOEmail.Subject);

                            readingResult = new EmailReadingResult()
                            {
                                Email   = existPOEmail,
                                Headers = messageHeaders.Headers,
                                Folder  = folder,
                                Status  = EmailMatchingResultStatus.Existing
                            };
                        }
                        else
                        {
                            _log.Info("Start GetMessage()");
                            var message = imap.GetMessage(uid, FetchOptions.Normal, false, folder);
                            _log.Info("Eng GetMessage(). Subject: " + message.Subject + Environment.NewLine);

                            readingResult = SaveEmail(db, message, uid, folder, scanDate);
                        }

                        _emailProcessResultList.Add(readingResult);

                        switch (readingResult.Status)
                        {
                        case EmailMatchingResultStatus.New:
                            newUidList.Add(new EmailDTO()
                            {
                                Id  = readingResult.Email.Id,
                                UID = readingResult.Email.UID
                            });
                            break;

                        case EmailMatchingResultStatus.Existing:
                            existingUidList.Add(new EmailDTO()
                            {
                                Id  = readingResult.Email.Id,
                                UID = readingResult.Email.UID
                            });
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Fatal(string.Format("Not processed Uid: {0}", uid), ex);
                        _threadExceptions.Add(new Exception(string.Format("Not processed Uid: {0}", uid), ex));
                    }

                    _log.Info("End email processing. Uid: " + uid);
                }
                else
                {
                    existingUidList.Add(new EmailDTO()
                    {
                        Id  = existEmail.Id,
                        UID = uid
                    });
                }
            }
        }
Exemple #20
0
        public void Process(IUnitOfWork db, EmailReadingResult result)
        {
            if (result.Status == EmailMatchingResultStatus.New &&
                result.HasMatches)
            {
                var noHtml  = StringHelper.TrimTags(result.Email.Message ?? "");
                var message = StringHelper.Substring(noHtml, 70).ToLower();
                //to remove the signature confirmation
                var removeSignConfirmation =
                    message.IndexOf("remove signature confirmation", StringComparison.OrdinalIgnoreCase) >= 0 ||
                    message.IndexOf("remove signature", StringComparison.OrdinalIgnoreCase) >= 0 ||
                    message.IndexOf("remove the signature", StringComparison.OrdinalIgnoreCase) >= 0;

                if (removeSignConfirmation)
                {
                    var orderNumber = result.MatchedIdList.FirstOrDefault();
                    _log.Info("Received RemoveSignatureConfirmation request, orderNumber=" + orderNumber);

                    if (!String.IsNullOrEmpty(orderNumber))
                    {
                        var isExistRemoveSignConfirmation = db.OrderEmailNotifies.IsExist(orderNumber,
                                                                                          OrderEmailNotifyType.InputRemoveSignConfirmationEmail);
                        if (!isExistRemoveSignConfirmation) //NOTE: First remove sign confirmation request
                        {
                            result.WasEmailProcessed = true;
                            _log.Info("RemoveSignatureEmailRule, WasEmailProcessed=" + result.WasEmailProcessed);

                            var comment = String.Empty;
                            var order   = db.Orders.GetByOrderNumber(orderNumber);
                            //var now = _time.GetAppNowTime();
                            //var isWeekday = db.Dates.IsWorkday(_time.GetAppNowTime());

                            if (order.OrderStatus == OrderStatusEnumEx.Shipped
                                //|| (isWeekday && now.Hour > 15)
                                )
                            {
                                //comment = "Skipped. Order already shipped or request came after 3PM on weekday";
                                var commentText = "";
                                if (order.OrderStatus == OrderStatusEnumEx.Shipped)
                                {
                                    commentText = "[System] Remove signature confirmation request came after the order shipped";
                                    comment     = "Skipped. Order already shipped";
                                }
                                //if (isWeekday && now.Hour > 15)
                                //{
                                //    commentText = "[System] Remove signature confirmation request came after 3PM on weekday";
                                //    comment = "Skipped. Request came after 3PM on weekday";
                                //}
                                db.OrderComments.Add(new OrderComment()
                                {
                                    OrderId    = order.Id,
                                    Message    = commentText,
                                    Type       = (int)CommentType.Address,
                                    CreateDate = _time.GetAppNowTime(),
                                    UpdateDate = _time.GetAppNowTime()
                                });

                                var emailInfo = new RejectRemoveSignConfirmationEmailInfo(_emailService.AddressService,
                                                                                          null,
                                                                                          orderNumber,
                                                                                          (MarketType)order.Market,
                                                                                          order.BuyerName,
                                                                                          order.BuyerEmail);

                                _emailService.SendEmail(emailInfo, CallSource.Service);
                            }
                            else
                            {
                                //Tring to remove signature

                                if (order.OrderStatus == OrderStatusEnumEx.Unshipped ||
                                    order.OrderStatus == OrderStatusEnumEx.PartiallyShipped ||
                                    order.OrderStatus == OrderStatusEnumEx.Pending)
                                {
                                    if (order.IsSignConfirmation)
                                    {
                                        order.IsSignConfirmation = false;
                                        _log.Info("Updated IsSignConfirmation=false, orderNumber=" + order.AmazonIdentifier);

                                        db.OrderComments.Add(new OrderComment()
                                        {
                                            OrderId    = order.Id,
                                            Message    = "[System] Signature confirmation was removed per buyer request",
                                            Type       = (int)CommentType.Address,
                                            CreateDate = _time.GetAppNowTime(),
                                            UpdateDate = _time.GetAppNowTime()
                                        });

                                        _actionService.AddAction(db,
                                                                 SystemActionType.UpdateRates,
                                                                 order.AmazonIdentifier,
                                                                 new UpdateRatesInput()
                                        {
                                            OrderId = order.Id
                                        },
                                                                 null,
                                                                 null);

                                        var orderItems = db.Listings.GetOrderItems(order.Id);
                                        var emailInfo  = new AcceptRemoveSignConfirmationEmailInfo(_emailService.AddressService,
                                                                                                   null,
                                                                                                   orderNumber,
                                                                                                   (MarketType)order.Market,
                                                                                                   orderItems,
                                                                                                   order.BuyerName,
                                                                                                   order.BuyerEmail);

                                        _emailService.SendEmail(emailInfo, CallSource.Service);

                                        comment = "Sign confirmation removed + emailed";
                                    }
                                    else
                                    {
                                        db.OrderComments.Add(new OrderComment()
                                        {
                                            OrderId    = order.Id,
                                            Message    = "[System] Remove signature confirmation request skipped. Signature confirmation was already removed",
                                            Type       = (int)CommentType.Address,
                                            CreateDate = _time.GetAppNowTime(),
                                            UpdateDate = _time.GetAppNowTime()
                                        });

                                        comment = "Skipped. Already removed";
                                    }
                                }
                                else
                                {
                                    //NOTE: If OrderStatus=Canceled
                                    comment = "Skipped. Order status=" + order.OrderStatus;
                                }
                            }

                            var dbBuyer = db.Buyers.GetFiltered(b => b.Email == result.Email.From).FirstOrDefault();
                            if (dbBuyer != null)
                            {
                                dbBuyer.RemoveSignConfirmation     = true;
                                dbBuyer.RemoveSignConfirmationDate = _time.GetUtcTime();
                                _log.Info("Set RemoveSignConfirmation=true, buyerEmail=" + result.Email.From);
                            }
                            else
                            {
                                _log.Info("Can't find buyerEmail=" + result.Email.From);
                            }

                            db.OrderEmailNotifies.Add(new OrderEmailNotify()
                            {
                                OrderNumber = orderNumber,
                                Type        = (int)OrderEmailNotifyType.InputRemoveSignConfirmationEmail,
                                Reason      = comment,
                                CreateDate  = _time.GetUtcTime()
                            });

                            db.Commit();
                        }
                        else
                        {
                            _log.Info("Repeated RemoveSignConfirmation email, no action");
                        }
                    }
                    else
                    {
                        _log.Info("Can't RemoveSignConfirmation, no matching orders!");
                    }
                }
            }
        }