示例#1
0
        private void ValidateLineItemStatusChange(List <HSLineItem> previousLineItemStates, LineItemStatusChanges lineItemStatusChanges, VerifiedUserType userType)
        {
            /* need to validate 3 things on a lineitem status change
             *
             * 1) user making the request has the ability to make that line item change based on usertype
             * 2) there are sufficient amount of the previous quantities for each lineitem
             */

            // 1)
            var allowedLineItemStatuses = LineItemStatusConstants.ValidLineItemStatusSetByUserType[userType];

            Require.That(allowedLineItemStatuses.Contains(lineItemStatusChanges.Status), new ErrorCode("Not authorized to set this status on a lineItem", 400, $"Not authorized to set line items to {lineItemStatusChanges.Status}"));

            // 2)
            var areCurrentQuantitiesToSupportChange = lineItemStatusChanges.Changes.All(lineItemChange =>
            {
                return(ValidateCurrentQuantities(previousLineItemStates, lineItemChange, lineItemStatusChanges.Status));
            });

            Require.That(areCurrentQuantitiesToSupportChange, new ErrorCode("Invalid lineItem status change", 400, $"Current lineitem quantity statuses on the order are not sufficient to support the requested change"));
        }
示例#2
0
        /// <summary>
        /// Validates LineItemStatus Change, Updates Line Item Statuses, Updates Order Statuses, Sends Necessary Emails
        /// </summary>

        // all line item status changes should go through here
        public async Task <List <HSLineItem> > UpdateLineItemStatusesAndNotifyIfApplicable(OrderDirection orderDirection, string orderID, LineItemStatusChanges lineItemStatusChanges, VerifiedUserContext verifiedUser = null)
        {
            var userType         = verifiedUser?.UserType ?? "noUser";
            var verifiedUserType = userType.Reserialize <VerifiedUserType>();

            var buyerOrderID            = orderID.Split('-')[0];
            var previousLineItemsStates = await _oc.LineItems.ListAllAsync <HSLineItem>(OrderDirection.Incoming, buyerOrderID);

            ValidateLineItemStatusChange(previousLineItemsStates.ToList(), lineItemStatusChanges, verifiedUserType);
            var updatedLineItems = await Throttler.RunAsync(lineItemStatusChanges.Changes, 100, 5, (lineItemStatusChange) =>
            {
                var newPartialLineItem = BuildNewPartialLineItem(lineItemStatusChange, previousLineItemsStates.ToList(), lineItemStatusChanges.Status);
                // if there is no verified user passed in it has been called from somewhere else in the code base and will be done with the client grant access
                return(verifiedUser != null ? _oc.LineItems.PatchAsync <HSLineItem>(orderDirection, orderID, lineItemStatusChange.ID, newPartialLineItem, verifiedUser.AccessToken) : _oc.LineItems.PatchAsync <HSLineItem>(orderDirection, orderID, lineItemStatusChange.ID, newPartialLineItem));
            });

            var buyerOrder = await _oc.Orders.GetAsync <HSOrder>(OrderDirection.Incoming, buyerOrderID);

            var allLineItemsForOrder = await _oc.LineItems.ListAllAsync <HSLineItem>(OrderDirection.Incoming, buyerOrderID);

            var lineItemsChanged            = allLineItemsForOrder.Where(li => lineItemStatusChanges.Changes.Select(li => li.ID).Contains(li.ID)).ToList();
            var supplierIDsRelatingToChange = lineItemsChanged.Select(li => li.SupplierID).Distinct().ToList();
            var relatedSupplierOrderIDs     = supplierIDsRelatingToChange.Select(supplierID => $"{buyerOrderID}-{supplierID}").ToList();

            var statusSync        = SyncOrderStatuses(buyerOrder, relatedSupplierOrderIDs, allLineItemsForOrder.ToList());
            var notifictionSender = HandleLineItemStatusChangeNotification(verifiedUserType, buyerOrder, supplierIDsRelatingToChange, lineItemsChanged, lineItemStatusChanges);

            await statusSync;
            await notifictionSender;

            return(updatedLineItems.ToList());
        }
示例#3
0
        private async Task HandleLineItemStatusChangeNotification(VerifiedUserType setterUserType, HSOrder buyerOrder, List <string> supplierIDsRelatedToChange, List <HSLineItem> lineItemsChanged, LineItemStatusChanges lineItemStatusChanges)
        {
            try
            {
                var suppliers = await Throttler.RunAsync(supplierIDsRelatedToChange, 100, 5, supplierID => _oc.Suppliers.GetAsync <HSSupplier>(supplierID));

                // currently the only place supplier name is used is when there should be lineitems from only one supplier included on the change, so we can just take the first supplier
                var statusChangeTextDictionary = LineItemStatusConstants.GetStatusChangeEmailText(suppliers.First().Name);

                foreach (KeyValuePair <VerifiedUserType, EmailDisplayText> entry in statusChangeTextDictionary[lineItemStatusChanges.Status])
                {
                    var userType  = entry.Key;
                    var emailText = entry.Value;

                    var firstName = "";
                    var lastName  = "";
                    var email     = "";

                    if (userType == VerifiedUserType.buyer)
                    {
                        firstName = buyerOrder.FromUser.FirstName;
                        lastName  = buyerOrder.FromUser.LastName;
                        email     = buyerOrder.FromUser.Email;
                        await _sendgridService.SendLineItemStatusChangeEmail(buyerOrder, lineItemStatusChanges, lineItemsChanged.ToList(), firstName, lastName, email, emailText);
                    }
                    else if (userType == VerifiedUserType.admin)
                    {
                        // Loop over seller users, pull out THEIR boolean, as well as the List<string> of AddtlRcpts
                        var sellerUsers = await _oc.AdminUsers.ListAsync <HSSellerUser>();

                        var tos = new List <EmailAddress>();
                        foreach (var seller in sellerUsers.Items)
                        {
                            if (seller?.xp?.OrderEmails ?? false)
                            {
                                tos.Add(new EmailAddress(seller.Email));
                            }
                            ;
                            if (seller?.xp?.AddtlRcpts?.Any() ?? false)
                            {
                                foreach (var rcpt in seller.xp.AddtlRcpts)
                                {
                                    tos.Add(new EmailAddress(rcpt));
                                }
                                ;
                            }
                            ;
                        }
                        ;
                        var shouldNotify = !(LineItemStatusConstants.LineItemStatusChangesDontNotifySetter.Contains(lineItemStatusChanges.Status) && setterUserType == VerifiedUserType.admin);
                        if (shouldNotify)
                        {
                            await _sendgridService.SendLineItemStatusChangeEmailMultipleRcpts(buyerOrder, lineItemStatusChanges, lineItemsChanged.ToList(), tos, emailText);
                        }
                    }
                    else
                    {
                        var shouldNotify = !(LineItemStatusConstants.LineItemStatusChangesDontNotifySetter.Contains(lineItemStatusChanges.Status) && setterUserType == VerifiedUserType.supplier);
                        if (shouldNotify)
                        {
                            await Throttler.RunAsync(suppliers, 100, 5, async supplier =>
                            {
                                if (supplier?.xp?.NotificationRcpts?.Any() ?? false)
                                {
                                    var tos = new List <EmailAddress>();
                                    foreach (var rcpt in supplier.xp.NotificationRcpts)
                                    {
                                        tos.Add(new EmailAddress(rcpt));
                                    }
                                    ;
                                    await _sendgridService.SendLineItemStatusChangeEmailMultipleRcpts(buyerOrder, lineItemStatusChanges, lineItemsChanged.ToList(), tos, emailText);
                                }
                            });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // track in app insights
                // to find go to Transaction Search > Event Type = Event > Filter by any of these custom properties or event name "Email.LineItemEmailFailed"
                var customProperties = new Dictionary <string, string>
                {
                    { "Message", "Attempt to email line item changes failed" },
                    { "BuyerOrderID", buyerOrder.ID },
                    { "BuyerID", buyerOrder.FromCompanyID },
                    { "UserEmail", buyerOrder.FromUser.Email },
                    { "UserType", setterUserType.ToString() },
                    { "ErrorResponse", JsonConvert.SerializeObject(ex.Message, Newtonsoft.Json.Formatting.Indented) }
                };
                _telemetry.TrackEvent("Email.LineItemEmailFailed", customProperties);
                return;
            }
        }