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