Esempio n. 1
0
        /// <summary>
        /// Sends a recurring payment cancelled notification to the store owner.
        /// </summary>
        public static Task <CreateMessageResult> SendRecurringPaymentCancelledStoreOwnerNotificationAsync(this IMessageFactory factory, RecurringPayment recurringPayment, int languageId = 0)
        {
            Guard.NotNull(recurringPayment, nameof(recurringPayment));

            var order = recurringPayment.InitialOrder;

            return(factory.CreateMessageAsync(
                       MessageContext.Create(MessageTemplateNames.RecurringPaymentCancelledStoreOwner, languageId, order?.StoreId, order?.Customer),
                       true,
                       recurringPayment,
                       order));
        }
        /// <summary>
        /// Sends a "new VAT sumitted" notification to a store owner.
        /// </summary>
        public static Task <CreateMessageResult> SendNewVatSubmittedStoreOwnerNotificationAsync(this IMessageFactory factory, Customer customer, string vatName, string vatAddress, int languageId = 0)
        {
            Guard.NotNull(customer, nameof(customer));

            var model = new NamedModelPart("VatValidationResult")
            {
                ["Name"]    = vatName,
                ["Address"] = vatAddress
            };

            return(factory.CreateMessageAsync(MessageContext.Create(MessageTemplateNames.NewVatSubmittedStoreOwner, languageId, customer: customer), true, model));
        }
        /// <summary>
        /// Sends a 'Back in stock' notification message to a customer.
        /// </summary>
        /// <param name="factory">Message factory.</param>
        /// <param name="subscription">Back in stock subscription.</param>
        /// <returns>Create message result.</returns>
        public static async Task <CreateMessageResult> SendBackInStockNotificationAsync(this IMessageFactory factory, BackInStockSubscription subscription)
        {
            Guard.NotNull(subscription, nameof(subscription));

            var customer   = subscription.Customer;
            var languageId = customer.GenericAttributes.LanguageId ?? 0;

            return(await factory.CreateMessageAsync(
                       MessageContext.Create(MessageTemplateNames.BackInStockCustomer, languageId, subscription.StoreId, customer),
                       true,
                       subscription.Product));
        }
Esempio n. 4
0
        /// <summary>
        /// Sends a new return request message to the store owner.
        /// </summary>
        public static Task <CreateMessageResult> SendNewReturnRequestStoreOwnerNotificationAsync(this IMessageFactory factory, ReturnRequest returnRequest, OrderItem orderItem, int languageId = 0)
        {
            Guard.NotNull(returnRequest, nameof(returnRequest));
            Guard.NotNull(orderItem, nameof(orderItem));

            return(factory.CreateMessageAsync(
                       MessageContext.Create(MessageTemplateNames.NewReturnRequestStoreOwner, languageId, orderItem.Order?.StoreId, returnRequest.Customer),
                       true,
                       returnRequest,
                       orderItem,
                       orderItem.Order,
                       orderItem.Product));
        }
        /// <summary>
        /// Sends wishlist "email a friend" message.
        /// </summary>
        public static Task <CreateMessageResult> SendShareWishlistMessageAsync(this IMessageFactory factory, Customer customer,
                                                                               string fromEmail, string toEmail, string personalMessage, int languageId = 0)
        {
            Guard.NotNull(customer, nameof(customer));

            var model = new NamedModelPart("Wishlist")
            {
                ["PersonalMessage"] = personalMessage,
                ["From"]            = fromEmail,
                ["To"] = toEmail
            };

            return(factory.CreateMessageAsync(MessageContext.Create(MessageTemplateNames.ShareWishlist, languageId, customer: customer), true, model));
        }
Esempio n. 6
0
        /// <summary>
        /// Sends a gift card notification to the customer.
        /// </summary>
        public static Task <CreateMessageResult> SendGiftCardNotificationAsync(this IMessageFactory factory, GiftCard giftCard, int languageId = 0)
        {
            Guard.NotNull(giftCard, nameof(giftCard));

            var orderItem = giftCard.PurchasedWithOrderItem;
            var customer  = orderItem?.Order?.Customer;
            var storeId   = orderItem?.Order?.StoreId;

            return(factory.CreateMessageAsync(
                       MessageContext.Create(MessageTemplateNames.GiftCardCustomer, languageId, storeId, customer),
                       true,
                       giftCard,
                       orderItem,
                       orderItem?.Product));
        }
 /// <summary>
 /// Sends a newsletter subscription activation message.
 /// </summary>
 public static Task <CreateMessageResult> SendNewsletterSubscriptionActivationMessageAsync(this IMessageFactory factory, NewsletterSubscription subscription, int languageId = 0)
 {
     Guard.NotNull(subscription, nameof(subscription));
     return(factory.CreateMessageAsync(MessageContext.Create(MessageTemplateNames.NewsLetterSubscriptionActivation, languageId), true, subscription));
 }
 /// <summary>
 /// Sends password recovery message to a customer.
 /// </summary>
 public static Task <CreateMessageResult> SendCustomerPasswordRecoveryMessageAsync(this IMessageFactory factory, Customer customer, int languageId = 0)
 {
     Guard.NotNull(customer, nameof(customer));
     return(factory.CreateMessageAsync(MessageContext.Create(MessageTemplateNames.CustomerPasswordRecovery, languageId, customer: customer), true));
 }
        private async Task <ExistingStartMessageContext> ProcessStartMessageAsync(
            MessageChangeEvent change,
            EventEntity eventEntity,
            IComponent rootComponent,
            IComponent component,
            ExistingStartMessageContext existingStartMessageContext)
        {
            _logger.LogInformation("Applying change to component tree.");
            component.Status = change.AffectedComponentStatus;

            // This change may affect a component that we do not display on the status page.
            // Find the deepester ancestor of the component that is directly affected.
            _logger.LogInformation("Determining if change affects visible component tree.");
            var lowestVisibleComponent = rootComponent.GetDeepestVisibleAncestorOfSubComponent(component);

            if (lowestVisibleComponent == null || lowestVisibleComponent.Status == ComponentStatus.Up)
            {
                // The change does not bubble up to a component that we display on the status page.
                // Therefore, we shouldn't post a message about it.
                _logger.LogInformation("Change does not affect visible component tree. Will not post or edit any messages.");
                return(existingStartMessageContext);
            }

            // The change bubbles up to a component that we display on the status page.
            // We must post or update a message about it.
            if (existingStartMessageContext != null)
            {
                // There is an existing message we need to update.
                _logger.LogInformation("Found existing message, will edit it with information from new change.");
                // We must expand the scope of the existing message to include the component affected by this change.
                // In other words, if the message claims V2 Restore is down and V3 Restore is now down as well, we need to update the message to say Restore is down.
                var leastCommonAncestorPath = ComponentUtility.GetLeastCommonAncestorPath(existingStartMessageContext.AffectedComponent, lowestVisibleComponent);
                _logger.LogInformation("Least common ancestor component of existing message and this change is {LeastCommonAncestorPath}.", leastCommonAncestorPath);
                var leastCommonAncestor = rootComponent.GetByPath(leastCommonAncestorPath);
                if (leastCommonAncestor == null)
                {
                    // If the two components don't have a common ancestor, then they must not be a part of the same component tree.
                    // This should not be possible because it is asserted earlier that both these components are subcomponents of the root component.
                    throw new ArgumentException("Least common ancestor component of existing message and this change does not exist!", nameof(change));
                }

                if (leastCommonAncestor.Status == ComponentStatus.Up)
                {
                    // The least common ancestor of the component affected by the change and the component referred to by the existing message is unaffected!
                    // This should not be possible because the ancestor of any visible component should be visible (in other words, changes to visible components should always bubble up).
                    throw new ArgumentException("Least common ancestor of two visible components is unaffected!");
                }

                await _factory.UpdateMessageAsync(eventEntity, existingStartMessageContext.Timestamp, MessageType.Start, leastCommonAncestor);

                return(new ExistingStartMessageContext(existingStartMessageContext.Timestamp, leastCommonAncestor, leastCommonAncestor.Status));
            }
            else
            {
                // There is not an existing message we need to update.
                _logger.LogInformation("No existing message found. Creating new start message for change.");
                await _factory.CreateMessageAsync(eventEntity, change.Timestamp, change.Type, lowestVisibleComponent);

                return(new ExistingStartMessageContext(change.Timestamp, lowestVisibleComponent, lowestVisibleComponent.Status));
            }
        }