예제 #1
0
        public override object ConvertFrom(CultureInfo culture, object value)
        {
            // Obj > Dict
            var dict = CommonHelper.ObjectToDictionary(value);
            var to   = typeof(T);

            if (to == typeof(RouteValueDictionary))
            {
                return(new RouteValueDictionary(dict));
            }
            else if (to == typeof(Dictionary <string, object>))
            {
                return((Dictionary <string, object>)dict);
            }
            else if (to == typeof(ExpandoObject))
            {
                var expando = new ExpandoObject();
                expando.Merge(dict);
                return(expando);
            }
            else if (to == typeof(HybridExpando))
            {
                var expando = new HybridExpando();
                expando.Merge(dict);
                return(expando);
            }
            else
            {
                return(dict);
            }
        }
예제 #2
0
        protected virtual object CreateContactModelPart(MessageContext messageContext)
        {
            var settings = _services.Settings.LoadSetting <ContactDataSettings>(messageContext.Store.Id);
            var contact  = new HybridExpando(settings, true) as dynamic;

            // Aliases
            contact.Phone = new
            {
                Company = settings.CompanyTelephoneNumber.NullEmpty(),
                Hotline = settings.HotlineTelephoneNumber.NullEmpty(),
                Mobile  = settings.MobileTelephoneNumber.NullEmpty(),
                Fax     = settings.CompanyFaxNumber.NullEmpty()
            };

            contact.Email = new
            {
                Company   = settings.CompanyEmailAddress.NullEmpty(),
                Webmaster = settings.WebmasterEmailAddress.NullEmpty(),
                Support   = settings.SupportEmailAddress.NullEmpty(),
                Contact   = settings.ContactEmailAddress.NullEmpty()
            };

            PublishModelPartCreatedEvent <ContactDataSettings>(settings, contact);

            return(contact);
        }
예제 #3
0
        protected virtual object CreateModelPart(Store part, MessageContext messageContext)
        {
            Guard.NotNull(messageContext, nameof(messageContext));
            Guard.NotNull(part, nameof(part));

            var host     = messageContext.BaseUri.ToString();
            var logoInfo = _services.PictureService.GetPictureInfo(messageContext.Store.LogoPictureId);

            // Issue: https://github.com/smartstoreag/SmartStoreNET/issues/1321

            var m = new Dictionary <string, object>
            {
                { "Email", messageContext.EmailAccount.Email },
                { "EmailName", messageContext.EmailAccount.DisplayName },
                { "Name", part.Name },
                { "Url", host },
                { "Cdn", part.ContentDeliveryNetwork },
                { "PrimaryStoreCurrency", part.PrimaryStoreCurrency?.CurrencyCode },
                { "PrimaryExchangeRateCurrency", part.PrimaryExchangeRateCurrency?.CurrencyCode },
                { "Logo", CreateModelPart(logoInfo, messageContext, host, null, new Size(400, 75)) },
                { "Company", CreateCompanyModelPart(messageContext) },
                { "Contact", CreateContactModelPart(messageContext) },
                { "Bank", CreateBankModelPart(messageContext) },
                { "Copyright", T("Content.CopyrightNotice", messageContext.Language.Id, DateTime.Now.Year.ToString(), part.Name).Text }
            };

            var he = new HybridExpando(true);

            he.Merge(m, true);

            PublishModelPartCreatedEvent <Store>(part, he);

            return(he);
        }
		protected virtual object CreateBankModelPart(MessageContext messageContext)
		{
			var settings = _services.Settings.LoadSetting<BankConnectionSettings>(messageContext.Store.Id);
			var m = new HybridExpando(settings, true);
			PublishModelPartCreatedEvent<BankConnectionSettings>(settings, m);
			return m;
		}
예제 #5
0
        public virtual void AddModelPart(object part, MessageContext messageContext, string name = null)
        {
            var model = messageContext.Model;

            name = name.NullEmpty() ?? ResolveModelName(part);

            object modelPart = null;

            switch (part)
            {
            case INamedModelPart x:
                modelPart = x;
                break;

            case IModelPart x:
                MergeModelBag(x, model, messageContext);
                break;

            case Order x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case Domain.Entities.Data.Post x:
                modelPart = CreateModelPart(x, messageContext);
                break;
            }

            if (modelPart != null)
            {
                if (name.IsEmpty())
                {
                    throw new Exception($"Could not resolve a model key for part '{modelPart.GetType().Name}'. Use an instance of 'NamedModelPart' class to pass model with name.");
                }

                if (model.TryGetValue(name, out var existing))
                {
                    // A model part with the same name exists in model already...
                    if (existing is IDictionary <string, object> x)
                    {
                        // but it's a dictionary which we can easily merge with
                        x.Merge(FastProperty.ObjectToDictionary(modelPart));
                    }
                    else
                    {
                        // Wrap in HybridExpando and merge
                        var he = new HybridExpando(existing, true);
                        he.Merge(FastProperty.ObjectToDictionary(modelPart));
                        model[name] = he;
                    }
                }
                else
                {
                    // Put part to model as new property
                    model[name] = modelPart;
                }
            }
        }
예제 #6
0
        protected virtual object CreateModelPart(Order part, MessageContext messageContext)
        {
            var allow = new HashSet <string>
            {
                nameof(part.Id),
                nameof(part.OrderNumber),
                nameof(part.OrderGuid),
                nameof(part.StoreId),
                nameof(part.OrderStatus),
                nameof(part.PaymentStatus),
                nameof(part.ShippingStatus),
                nameof(part.VatNumber),
                nameof(part.AffiliateId),
                nameof(part.CustomerIp),
                nameof(part.CardType),
                nameof(part.CardName),
                nameof(part.MaskedCreditCardNumber),
                nameof(part.DirectDebitAccountHolder),
                nameof(part.DirectDebitBankCode),                 // TODO: (mc) Liquid > Bank data (?)
                nameof(part.PurchaseOrderNumber),
                nameof(part.ShippingMethod),
                nameof(part.PaymentMethodSystemName),
                nameof(part.ShippingRateComputationMethodSystemName)
                // TODO: (mc) Liquid > More whitelisting?
            };

            var m = new HybridExpando(part, allow, MemberOptMethod.Allow);
            var d = (dynamic)m;

            d.ID      = part.Id;
            d.Billing = CreateModelPart(part.BillingAddress, messageContext);
            if (part.ShippingAddress != null)
            {
                d.Shipping = part.ShippingAddress.IsPostalDataEqual(part.BillingAddress) ? null : CreateModelPart(part.ShippingAddress, messageContext);
            }
            d.CustomerEmail   = part.BillingAddress.Email.NullEmpty();
            d.CustomerComment = part.CustomerOrderComment.NullEmpty();
            d.Status          = part.OrderStatus.ToString();
            d.CreatedOn       = part.CreatedOnUtc;

            // Payment method
            var paymentMethodName = part.PaymentMethodSystemName;

            d.PaymentMethod = paymentMethodName.NullEmpty();

            m.Properties["OrderNumber"] = part.Id;

            d.Items  = part.OrderItems.Select(x => CreateModelPart(x, messageContext)).ToList();
            d.Totals = CreateOrderTotalsPart(part, messageContext);

            return(m);
        }
예제 #7
0
        protected virtual object CreateCompanyModelPart(MessageContext messageContext)
        {
            var     settings = _services.Settings.LoadSetting <CompanyInformationSettings>(messageContext.Store.Id);
            dynamic m        = new HybridExpando(settings, true);

            m.NameLine    = Concat(settings.Salutation, settings.Title, settings.Firstname, settings.Lastname);
            m.StreetLine  = Concat(settings.Street, settings.Street2);
            m.CityLine    = Concat(settings.ZipCode, settings.City);
            m.CountryLine = Concat(settings.CountryName, settings.Region);

            PublishModelPartCreatedEvent <CompanyInformationSettings>(settings, m);
            return(m);
        }
예제 #8
0
        public void CanRenderHybridExpando()
        {
            var now   = DateTime.UtcNow;
            var order = new Order
            {
                BillingAddress = new Address {
                    FirstName = "John", LastName = "Doe"
                },
                Customer = new Customer {
                    Email = "*****@*****.**"
                },
                OrderTotal = (decimal)9999.99
            };

            var product1 = new SmartStore.Core.Domain.Catalog.Product {
                Name = "TV"
            };
            var product2 = new SmartStore.Core.Domain.Catalog.Product {
                Name = "Shoe"
            };

            order.OrderItems.Add(new OrderItem {
                Quantity = 2, Product = product1, PriceInclTax = 5000
            });
            order.OrderItems.Add(new OrderItem {
                Quantity = 3, Product = product2, PriceInclTax = (decimal)4999.99
            });

            var data         = new HybridExpando();
            var orderExpando = new HybridExpando(order);

            data["Order"]          = new HybridExpando(order);
            orderExpando["Custom"] = "Custom";

            var result = Render("{{ Order.OrderItems.size }} items, total: {{ Order.OrderTotal }} EUR", _deCulture, data);

            Assert.AreEqual("2 items, total: 9999,99 EUR", result);

            result = Render("{% for item in Order.OrderItems %}<div>{{ item.Quantity }}x{{ item.Product.Name | Upcase }}</div>{% endfor %}", _deCulture, data);
            Assert.AreEqual("<div>2xTV</div><div>3xSHOE</div>", result);

            result = Render("{% for item in Order.OrderItems %}{{ forloop.rindex }}{% unless forloop.last %}-{% endunless %}{% endfor %}", _deCulture, data);
            Assert.AreEqual("2-1", result);
        }
예제 #9
0
        protected virtual object CreateCompanyModelPart(MessageContext messageContext)
        {
            var     settings       = _services.Settings.LoadSetting <CompanyInformationSettings>(messageContext.Store.Id);
            var     countryService = _services.Resolve <ICountryService>();
            var     country        = countryService.GetCountryById(settings.CountryId);
            dynamic m = new HybridExpando(settings, true);

            m.NameLine   = Concat(settings.Salutation, settings.Title, settings.Firstname, settings.Lastname);
            m.StreetLine = Concat(settings.Street, settings.Street2);
            m.CityLine   = Concat(settings.ZipCode, settings.City);

            if (country != null)
            {
                m.CountryLine = Concat(country.GetLocalized(x => x.Name), settings.Region);
            }

            PublishModelPartCreatedEvent <CompanyInformationSettings>(settings, m);
            return(m);
        }
예제 #10
0
        protected virtual async Task <object> CreateModelPartAsync(Order part, MessageContext messageContext)
        {
            Guard.NotNull(messageContext, nameof(messageContext));
            Guard.NotNull(part, nameof(part));

            var allow = new HashSet <string>
            {
                nameof(part.Id),
                nameof(part.OrderNumber),
                nameof(part.OrderGuid),
                nameof(part.StoreId),
                nameof(part.OrderStatus),
                nameof(part.PaymentStatus),
                nameof(part.ShippingStatus),
                nameof(part.CustomerTaxDisplayType),
                nameof(part.TaxRatesDictionary),
                nameof(part.VatNumber),
                nameof(part.AffiliateId),
                nameof(part.CustomerIp),
                nameof(part.CardType),
                nameof(part.CardName),
                nameof(part.MaskedCreditCardNumber),
                nameof(part.DirectDebitAccountHolder),
                nameof(part.DirectDebitBankCode), // TODO: (mc) Liquid > Bank data (?)
                nameof(part.PurchaseOrderNumber),
                nameof(part.ShippingMethod),
                nameof(part.PaymentMethodSystemName),
                nameof(part.ShippingRateComputationMethodSystemName)
                // TODO: (mc) Liquid > More whitelisting?
            };

            var m = new HybridExpando(part, allow, MemberOptMethod.Allow);
            var d = m as dynamic;

            d.ID      = part.Id;
            d.Billing = await CreateModelPartAsync(part.BillingAddress, messageContext);

            if (part.ShippingAddress != null)
            {
                d.Shipping = part.ShippingAddress == part.BillingAddress ? null : await CreateModelPartAsync(part.ShippingAddress, messageContext);
            }
            d.CustomerEmail   = part.BillingAddress.Email.NullEmpty();
            d.CustomerComment = part.CustomerOrderComment.NullEmpty();
            d.Disclaimer      = GetTopicAsync("Disclaimer", messageContext);
            d.ConditionsOfUse = GetTopicAsync("ConditionsOfUse", messageContext);
            d.Status          = part.OrderStatus.GetLocalizedEnum(messageContext.Language.Id);
            d.CreatedOn       = ToUserDate(part.CreatedOnUtc, messageContext);
            d.PaidOn          = ToUserDate(part.PaidDateUtc, messageContext);

            // TODO: (mh) (core) Uncomment when available.
            // Payment method
            var paymentMethodName = part.PaymentMethodSystemName;

            //var paymentMethod = _services.Resolve<IProviderManager>().GetProvider<IPaymentMethod>(part.PaymentMethodSystemName);
            //if (paymentMethod != null)
            //{
            //    paymentMethodName = GetLocalizedValue(messageContext, paymentMethod.Metadata, nameof(paymentMethod.Metadata.FriendlyName), x => x.FriendlyName);
            //}
            d.PaymentMethod = paymentMethodName.NullEmpty();

            d.Url = part.Customer != null && !part.Customer.IsGuest()
                ? BuildActionUrl("Details", "Order", new { id = part.Id, area = "" }, messageContext)
                : null;

            // Overrides
            // TODO: (mh) (core) Uncomment when available.
            //m.Properties["OrderNumber"] = part.GetOrderNumber().NullEmpty();
            m.Properties["AcceptThirdPartyEmailHandOver"] = GetBoolResource(part.AcceptThirdPartyEmailHandOver, messageContext);

            // Items, Totals & Co.
            d.Items  = part.OrderItems.Where(x => x.Product != null).Select(async x => await CreateModelPartAsync(x, messageContext)).ToList();
            d.Totals = await CreateOrderTotalsPartAsync(part, messageContext);

            // Checkout Attributes
            if (part.CheckoutAttributeDescription.HasValue())
            {
                d.CheckoutAttributes = HtmlUtils.ConvertPlainTextToTable(HtmlUtils.ConvertHtmlToPlainText(part.CheckoutAttributeDescription)).NullEmpty();
            }

            await PublishModelPartCreatedEventAsync(part, m);

            return(m);
        }
예제 #11
0
        public virtual void AddModelPart(object part, MessageContext messageContext, string name = null)
        {
            Guard.NotNull(part, nameof(part));
            Guard.NotNull(messageContext, nameof(messageContext));

            var model = messageContext.Model;

            name = name.NullEmpty() ?? ResolveModelName(part);

            object modelPart = null;

            switch (part)
            {
            case INamedModelPart x:
                modelPart = x;
                break;

            case IModelPart x:
                MergeModelBag(x, model, messageContext);
                break;

            case Order x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case Product x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case Customer x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case Address x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case Shipment x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case OrderNote x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case RecurringPayment x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case ReturnRequest x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case GiftCard x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case NewsLetterSubscription x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case Campaign x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case ProductReview x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case BlogComment x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case NewsComment x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case ForumTopic x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case ForumPost x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case Forum x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case PrivateMessage x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case IEnumerable <GenericAttribute> x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case PollVotingRecord x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case ProductReviewHelpfulness x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case ForumSubscription x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            case BackInStockSubscription x:
                modelPart = CreateModelPart(x, messageContext);
                break;

            default:
                var partType = part.GetType();
                modelPart = part;

                if (partType.IsPlainObjectType() && !partType.IsAnonymous())
                {
                    var evt = new MessageModelPartMappingEvent(part);
                    _services.EventPublisher.Publish(evt);

                    if (evt.Result != null && !object.ReferenceEquals(evt.Result, part))
                    {
                        modelPart = evt.Result;
                        name      = evt.ModelPartName.NullEmpty() ?? ResolveModelName(evt.Result) ?? name;
                    }
                    else
                    {
                        modelPart = part;
                    }

                    modelPart = evt.Result ?? part;
                    name      = evt.ModelPartName.NullEmpty() ?? name;
                }

                break;
            }

            if (modelPart != null)
            {
                if (name.IsEmpty())
                {
                    throw new SmartException($"Could not resolve a model key for part '{modelPart.GetType().Name}'. Use an instance of 'NamedModelPart' class to pass model with name.");
                }

                if (model.TryGetValue(name, out var existing))
                {
                    // A model part with the same name exists in model already...
                    if (existing is IDictionary <string, object> x)
                    {
                        // but it's a dictionary which we can easily merge with
                        x.Merge(FastProperty.ObjectToDictionary(modelPart), true);
                    }
                    else
                    {
                        // Wrap in HybridExpando and merge
                        var he = new HybridExpando(existing, true);
                        he.Merge(FastProperty.ObjectToDictionary(modelPart), true);
                        model[name] = he;
                    }
                }
                else
                {
                    // Put part to model as new property
                    model[name] = modelPart;
                }
            }
        }
예제 #12
0
        private static List <dynamic> GetLocalized <TEntity>(
            DataExporterContext ctx,
            TEntity entity,
            params Expression <Func <TEntity, string> >[] keySelectors)
            where TEntity : BaseEntity, ILocalizedEntity
        {
            if (ctx.Languages.Count <= 1)
            {
                return(null);
            }

            var translations = ctx.GetTranslations <TEntity>();

            if (translations == null)
            {
                return(null);
            }

            var slugs  = ctx.GetUrlRecords <TEntity>();
            var result = new List <dynamic>();

            foreach (var language in ctx.Languages)
            {
                var languageCulture = language.Value.LanguageCulture.EmptyNull().ToLower();

                // Add slug.
                if (slugs != null)
                {
                    var value = slugs.GetSlug(language.Value.Id, entity.Id, false);
                    if (value.HasValue())
                    {
                        dynamic exp = new HybridExpando();
                        exp.Culture     = languageCulture;
                        exp.LocaleKey   = "SeName";
                        exp.LocaleValue = value;

                        result.Add(exp);
                    }
                }

                // Add localized property value.
                foreach (var keySelector in keySelectors)
                {
                    var    member    = keySelector.Body as MemberExpression;
                    var    propInfo  = member.Member as PropertyInfo;
                    string localeKey = propInfo.Name;
                    var    value     = translations.GetValue(language.Value.Id, entity.Id, localeKey);

                    // We do not export empty values to not fill databases with it.
                    if (value.HasValue())
                    {
                        dynamic exp = new HybridExpando();
                        exp.Culture     = languageCulture;
                        exp.LocaleKey   = localeKey;
                        exp.LocaleValue = value;

                        result.Add(exp);
                    }
                }
            }

            return(result.Any() ? result : null);
        }