Skip to content

Commit 0a55f33

Browse files
Value connector updates
1 parent 8d978ef commit 0a55f33

File tree

5 files changed

+160
-116
lines changed

5 files changed

+160
-116
lines changed

src/Umbraco.Commerce.Deploy/Connectors/ValueConnectors/UmbracoCommercePriceValueConnector.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class UmbracoCommercePriceValueConnector(
4747
{
4848
var udi = new GuidUdi(UmbracoCommerceConstants.UdiEntityType.Currency, kvp.Key);
4949

50-
// Because we store Guid IDs anyway we don't neceserily need to fetch
50+
// Because we store Guid IDs anyway we don't necessarily need to fetch
5151
// the Currency entity to look anything up, it's mostly a question
5252
// of whether we want to validate the Currency exists. I'm not sure
5353
// whether this should really be the responsibility of the property editor
@@ -84,7 +84,7 @@ public class UmbracoCommercePriceValueConnector(
8484

8585
foreach (KeyValuePair<string, decimal?> kvp in srcDict)
8686
{
87-
if (UdiHelper.TryParseGuidUdi(kvp.Key, out GuidUdi udi) && udi.EntityType == UmbracoCommerceConstants.UdiEntityType.Currency)
87+
if (UdiHelper.TryParseGuidUdi(kvp.Key, out GuidUdi? udi) && udi!.EntityType == UmbracoCommerceConstants.UdiEntityType.Currency)
8888
{
8989
CurrencyReadOnly? currencyEntity = umbracoCommerceApi.GetCurrency(udi.Guid);
9090
if (currencyEntity != null)

src/Umbraco.Commerce.Deploy/Connectors/ValueConnectors/UmbracoCommerceStoreEntityPickerValueConnector.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,12 @@ public class UmbracoCommerceStoreEntityPickerValueConnector(
6767
IContextCache contextCache,
6868
CancellationToken cancellationToken = default)
6969
{
70-
if (string.IsNullOrWhiteSpace(value) || !UdiHelper.TryParseGuidUdi(value, out GuidUdi udi))
70+
if (string.IsNullOrWhiteSpace(value) || !UdiHelper.TryParseGuidUdi(value, out GuidUdi? udi))
7171
{
7272
return null;
7373
}
7474

75-
EntityBase? entity =
76-
await GetEntityAsync(udi.EntityType, udi.Guid, cancellationToken).ConfigureAwait(false);
75+
EntityBase? entity = await GetEntityAsync(udi!.EntityType, udi.Guid, cancellationToken).ConfigureAwait(false);
7776

7877
return entity != null ? entity.Id.ToString() : null;
7978
}
@@ -104,6 +103,10 @@ public class UmbracoCommerceStoreEntityPickerValueConnector(
104103
return UmbracoCommerceConstants.UdiEntityType.TaxClass;
105104
case "EmailTemplate":
106105
return UmbracoCommerceConstants.UdiEntityType.EmailTemplate;
106+
case "ExportTemplate":
107+
return UmbracoCommerceConstants.UdiEntityType.ExportTemplate;
108+
case "PrintTemplate":
109+
return UmbracoCommerceConstants.UdiEntityType.PrintTemplate;
107110
case "Discount": // Not sure if discounts should transfer as these are "user generated"
108111
return UmbracoCommerceConstants.UdiEntityType.Discount;
109112
}
@@ -132,6 +135,10 @@ public class UmbracoCommerceStoreEntityPickerValueConnector(
132135
return Task.FromResult<EntityBase?>(umbracoCommerceApi.GetTaxClass(id));
133136
case UmbracoCommerceConstants.UdiEntityType.EmailTemplate:
134137
return Task.FromResult<EntityBase?>(umbracoCommerceApi.GetEmailTemplate(id));
138+
case UmbracoCommerceConstants.UdiEntityType.ExportTemplate:
139+
return Task.FromResult<EntityBase?>(umbracoCommerceApi.GetExportTemplate(id));
140+
case UmbracoCommerceConstants.UdiEntityType.PrintTemplate:
141+
return Task.FromResult<EntityBase?>(umbracoCommerceApi.GetPrintTemplate(id));
135142
case UmbracoCommerceConstants.UdiEntityType.Discount: // Not sure if discounts should transfer as these are "user generated"
136143
return Task.FromResult<EntityBase?>(umbracoCommerceApi.GetDiscount(id));
137144
}

src/Umbraco.Commerce.Deploy/Connectors/ValueConnectors/UmbracoCommerceStorePickerValueConnector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public class UmbracoCommerceStorePickerValueConnector(
5353
IContextCache contextCache,
5454
CancellationToken cancellationToken = default)
5555
{
56-
if (string.IsNullOrWhiteSpace(value) || !UdiHelper.TryParseGuidUdi(value, out GuidUdi udi) || udi.EntityType != UmbracoCommerceConstants.UdiEntityType.Store)
56+
if (string.IsNullOrWhiteSpace(value) || !UdiHelper.TryParseGuidUdi(value, out GuidUdi? udi) || udi!.EntityType != UmbracoCommerceConstants.UdiEntityType.Store)
5757
{
5858
return null;
5959
}
Lines changed: 127 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,127 @@
1-
// using System;
2-
// using System.Collections.Generic;
3-
// using System.Linq;
4-
// using System.Text.Json.Serialization;
5-
// using Umbraco.Commerce.Core.Api;
6-
// using Umbraco.Cms.Core;
7-
// using Umbraco.Cms.Core.Deploy;
8-
// using Umbraco.Cms.Core.Models;
9-
// using Umbraco.Cms.Core.Services;
10-
// using Umbraco.Deploy.Core.Connectors.ValueConnectors.Services;
11-
// using Microsoft.Extensions.Logging;
12-
// using Newtonsoft.Json;
13-
// using Umbraco.Deploy.Infrastructure.Connectors.ValueConnectors;
14-
// using Umbraco.Cms.Core.Models.Blocks;
15-
// using Umbraco.Deploy.Core.Migrators;
16-
// using Umbraco.Deploy.Infrastructure.Extensions;
17-
//
18-
// namespace Umbraco.Commerce.Deploy.Connectors.ValueConnectors
19-
// {
20-
// /// <summary>
21-
// /// A Deploy connector for the Umbraco Commerce Variants Editor property editor
22-
// /// </summary>
23-
// public class UmbracoCommerceVariantsEditorValueConnector : BlockValueConnectorBase<UmbracoCommerceVariantsEditorValueConnector.VariantsBlockEditorValue>, IValueConnector
24-
// {
25-
// private readonly IUmbracoCommerceApi _umbracoCommerceApi;
26-
//
27-
// public override IEnumerable<string> PropertyEditorAliases => new[] { "Umbraco.Commerce.VariantsEditor" };
28-
//
29-
// public UmbracoCommerceVariantsEditorValueConnector(
30-
// IUmbracoCommerceApi umbracoCommerceApi,
31-
// IContentTypeService contentTypeService,
32-
// Lazy<ValueConnectorCollection> valueConnectors,
33-
// PropertyTypeMigratorCollection propertyTypeMigrators,
34-
// ILogger<UmbracoCommerceVariantsEditorValueConnector> logger)
35-
// : base(contentTypeService, valueConnectors, propertyTypeMigrators, logger)
36-
// {
37-
// _umbracoCommerceApi = umbracoCommerceApi;
38-
// }
39-
//
40-
// public override string ToArtifact(object value, IPropertyType propertyType, ICollection<ArtifactDependency> dependencies, IContextCache contextCache)
41-
// {
42-
// if (value is string input && input.TryParseJson(out VariantsBlockEditorValue result) && result != null)
43-
// {
44-
// // Recursive
45-
// result.Content = ToArtifact(result.Content, dependencies, contextCache).ToList();
46-
// result.Settings = ToArtifact(result.Settings, dependencies, contextCache).ToList();
47-
//
48-
// var productAttributeAliases = result.Layout.Items.SelectMany(x => x.Config.Attributes.Keys)
49-
// .Distinct();
50-
//
51-
// foreach (var productAttributeAlias in productAttributeAliases)
52-
// {
53-
// var productAttribute = _umbracoCommerceApi.GetProductAttribute(result.StoreId.Value, productAttributeAlias);
54-
// if (productAttribute != null)
55-
// {
56-
// dependencies.Add(new UmbracoCommerceArtifactDependency(productAttribute.GetUdi()));
57-
// }
58-
// }
59-
//
60-
// return JsonConvert.SerializeObject(result, Formatting.None);
61-
// }
62-
//
63-
// return null;
64-
// }
65-
//
66-
// public override object FromArtifact(string value, IPropertyType propertyType, object currentValue, IDictionary<string, string> propertyEditorAliases, IContextCache contextCache)
67-
// {
68-
// if (value is string input && input.TryParseJson(out VariantsBlockEditorValue result) && result != null)
69-
// {
70-
// // Recursive
71-
// result.Content = FromArtifact(result.Content, propertyEditorAliases, contextCache).ToList();
72-
// result.Settings = FromArtifact(result.Settings, propertyEditorAliases, contextCache).ToList();
73-
//
74-
// return JsonConvert.SerializeObject(result, Formatting.None);
75-
// }
76-
//
77-
// return null;
78-
// }
79-
//
80-
// object IValueConnector.FromArtifact(string value, IPropertyType propertyType, object currentValue, IContextCache contextCache)
81-
// => FromArtifact(value, propertyType, currentValue, contextCache);
82-
//
83-
// string IValueConnector.ToArtifact(object value, IPropertyType propertyType, ICollection<ArtifactDependency> dependencies, IContextCache contextCache)
84-
// => ToArtifact(value, propertyType, dependencies, contextCache);
85-
//
86-
// public class BaseValue
87-
// {
88-
// public Guid? StoreId { get; set; }
89-
// }
90-
//
91-
// public class VariantsBlockEditorValue : BlockValue
92-
// {
93-
// public override string PropertyEditorAlias => "Umbraco.Commerce.VariantsEditor";
94-
// }
95-
//
96-
// public class VariantsBlockEditorLayoutItem : IBlockLayoutItem
97-
// {
98-
// public Udi? ContentUdi { get; set; }
99-
// public Udi? SettingsUdi { get; set; }
100-
// public ProductVariantConfig Config { get; set; }
101-
// }
102-
//
103-
// public class ProductVariantConfig
104-
// {
105-
// public IDictionary<string, string> Attributes { get; set; } = new Dictionary<string, string>();
106-
//
107-
// public bool IsDefault { get; set; }
108-
// }
109-
// }
110-
// }
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text.Json.Nodes;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Umbraco.Commerce.Core.Api;
8+
using Umbraco.Cms.Core;
9+
using Umbraco.Cms.Core.Deploy;
10+
using Umbraco.Cms.Core.Models;
11+
using Umbraco.Cms.Core.Services;
12+
using Umbraco.Deploy.Core.Connectors.ValueConnectors.Services;
13+
using Microsoft.Extensions.Logging;
14+
using Umbraco.Deploy.Infrastructure.Connectors.ValueConnectors;
15+
using Umbraco.Cms.Core.Models.Blocks;
16+
using Umbraco.Cms.Core.Serialization;
17+
using Umbraco.Commerce.Core.Models;
18+
using Umbraco.Deploy.Core.Migrators;
19+
20+
namespace Umbraco.Commerce.Deploy.Connectors.ValueConnectors
21+
{
22+
/// <summary>
23+
/// A Deploy connector for the Umbraco Commerce Variants Editor property editor
24+
/// </summary>
25+
public class UmbracoCommerceVariantsEditorValueConnector(
26+
IUmbracoCommerceApi umbracoCommerceApi,
27+
IContentTypeService contentTypeService,
28+
Lazy<ValueConnectorCollection> valueConnectors,
29+
PropertyTypeMigratorCollection propertyTypeMigrators,
30+
IJsonSerializer jsonSerializer,
31+
ILogger<UmbracoCommerceVariantsEditorValueConnector> logger)
32+
: BlockEditorValueConnectorBase<UmbracoCommerceVariantsEditorValueConnector.VariantsBlockEditorValue>(
33+
jsonSerializer, contentTypeService, valueConnectors, propertyTypeMigrators, logger), IValueConnector
34+
{
35+
public override IEnumerable<string> PropertyEditorAliases => new[] { "Umbraco.Commerce.VariantsEditor" };
36+
37+
public override async Task<string?> ToArtifactAsync(object? value, IPropertyType propertyType, ICollection<ArtifactDependency> dependencies, IContextCache contextCache,
38+
CancellationToken cancellationToken = default)
39+
{
40+
if (value is null)
41+
{
42+
return null;
43+
}
44+
45+
if (!jsonSerializer.TryDeserialize(value, out VariantsBlockEditorValueBase? storeValue) || !storeValue.StoreId.HasValue)
46+
{
47+
return null;
48+
}
49+
50+
if (!jsonSerializer.TryDeserialize(value, out VariantsBlockEditorValue? result))
51+
{
52+
return null;
53+
}
54+
55+
await ToArtifactAsync(result, dependencies, contextCache, cancellationToken).ConfigureAwait(false);
56+
57+
IEnumerable<string>? productAttributeAliases = result.GetLayouts()?.SelectMany(x => x.Config.Attributes.Keys)
58+
.Distinct();
59+
60+
if (productAttributeAliases != null)
61+
{
62+
foreach (var productAttributeAlias in productAttributeAliases)
63+
{
64+
ProductAttributeReadOnly? productAttribute = umbracoCommerceApi.GetProductAttribute(storeValue.StoreId.Value, productAttributeAlias);
65+
if (productAttribute != null)
66+
{
67+
dependencies.Add(new UmbracoCommerceArtifactDependency(productAttribute.GetUdi()));
68+
}
69+
}
70+
}
71+
72+
return jsonSerializer.Serialize(result);
73+
74+
}
75+
76+
public override async Task<object?> FromArtifactAsync(string? value, IPropertyType propertyType, object? currentValue,
77+
IDictionary<string, string>? propertyEditorAliases, IContextCache contextCache,
78+
CancellationToken cancellationToken = new CancellationToken())
79+
{
80+
var artifact = await base.FromArtifactAsync(value, propertyType, currentValue, propertyEditorAliases,
81+
contextCache, cancellationToken).ConfigureAwait(false);
82+
83+
if (artifact == null)
84+
{
85+
return null;
86+
}
87+
88+
// If we have an artifact, value can't be null so we can just parse it for a store id
89+
if (!jsonSerializer.TryDeserialize(value!, out VariantsBlockEditorValueBase? storeValue) || !storeValue.StoreId.HasValue)
90+
{
91+
return artifact;
92+
}
93+
94+
JsonObject? artifactJson = jsonSerializer.Deserialize<JsonObject>(artifact.ToString()!);
95+
96+
artifactJson!.Remove("storeId");
97+
artifactJson!.Add("storeId", storeValue.StoreId);
98+
99+
return jsonSerializer.Serialize(artifactJson);
100+
}
101+
102+
private class VariantsBlockEditorValueBase
103+
{
104+
public Guid? StoreId { get; set; }
105+
}
106+
107+
public class VariantsBlockEditorValue : BlockValue<VariantsBlockEditorLayoutItem>
108+
{
109+
public override string PropertyEditorAlias => "Umbraco.Commerce.VariantsEditor";
110+
}
111+
112+
public class VariantsBlockEditorLayoutItem : IBlockLayoutItem
113+
{
114+
public Udi? ContentUdi { get; set; }
115+
116+
public Udi? SettingsUdi { get; set; }
117+
public ProductVariantConfig Config { get; set; }
118+
}
119+
120+
public class ProductVariantConfig
121+
{
122+
public IDictionary<string, string> Attributes { get; set; } = new Dictionary<string, string>();
123+
124+
public bool IsDefault { get; set; }
125+
}
126+
}
127+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Collections.Generic;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace Umbraco.Commerce.Extensions;
6+
7+
internal static class AsyncEnumerableExtensions
8+
{
9+
public static async Task<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> items, CancellationToken cancellationToken = default)
10+
{
11+
var results = new List<T>();
12+
13+
await foreach (T item in items.WithCancellation(cancellationToken).ConfigureAwait(false))
14+
{
15+
results.Add(item);
16+
}
17+
18+
return results;
19+
}
20+
}

0 commit comments

Comments
 (0)