Skip to content

Commit

Permalink
Fixed merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
dgon-jd committed Aug 8, 2023
2 parents c0d8209 + e896a2a commit b61b9ae
Show file tree
Hide file tree
Showing 12 changed files with 424 additions and 108 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches: [ "main" ]

env:
PACKAGE_VERSION: 1.2.9
PACKAGE_VERSION: 1.2.14

jobs:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,17 @@ public override List<string> ValidateInstance(AttributeInstance? instance, bool
return errors;
}

if (instance is not DateRangeAttributeInstance)
if (instance is not DateRangeAttributeInstance dateRangeAttribute)
{
errors.Add("Cannot validate attribute. Expected attribute type: DateRange)");
errors.Add("Cannot validate attribute. Expected attribute type: DateRange");
return errors;
}

if (dateRangeAttribute.Value != null
&& (DateRangeAttributeType == DateRangeAttributeType.DateRange && dateRangeAttribute.Value.To == null)
)
{
errors.Add("DateRange attribute value To is missing");
return errors;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using CloudFabric.EAV.Enums;
using CloudFabric.EAV.Enums;
using CloudFabric.EAV.Domain.Events.Configuration.Attributes;
using CloudFabric.EAV.Domain.Models.Base;
using CloudFabric.EventSourcing.EventStore;
Expand Down Expand Up @@ -33,10 +33,11 @@ public SerialAttributeConfiguration(Guid id,

public override List<string> ValidateInstance(AttributeInstance? instance, bool requiredAttributesCanBeNull = false)
{
List<string> errors = base.ValidateInstance(instance, requiredAttributesCanBeNull);
List<string> errors = new();

if (instance == null)
{
errors = base.ValidateInstance(instance, requiredAttributesCanBeNull);
return errors;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
namespace CloudFabric.EAV.Domain.Models.Attributes;
namespace CloudFabric.EAV.Domain.Models.Attributes;

public class SerialAttributeInstance : AttributeInstance
{
public long Value { get; set; }
/// <summary>
/// Nullable because it's auto-generated
/// and should be stored before auto-generated value can be calculated.
/// /// </summary>
public long? Value { get; set; }

public override object? GetValue()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ private static Type GetRequestTypeFromAttributeType(EavAttributeType attributeTy
case EavAttributeType.Image:
return typeof(ImageAttributeInstanceCreateUpdateRequest);
case EavAttributeType.Array:
return typeof(ArrayAttributeConfigurationCreateUpdateRequest);
return typeof(ArrayAttributeInstanceCreateUpdateRequest);
case EavAttributeType.Money:
return typeof(MoneyAttributeConfigurationCreateUpdateRequest);
return typeof(MoneyAttributeInstanceCreateUpdateRequest);
default:
throw new InvalidOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace CloudFabric.EAV.Models.RequestModels.Attributes;
namespace CloudFabric.EAV.Models.RequestModels.Attributes;

public class SerialAttributeInstanceCreateUpdateRequest : AttributeInstanceCreateUpdateRequest
{
public long? Value { get; set; }
}
56 changes: 0 additions & 56 deletions CloudFabric.EAV.Service/EAVEntityInstanceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -474,60 +474,4 @@ await GetAttributeConfigurationsForEntityConfiguration(

return (_mapper.Map<EntityInstanceViewModel>(entityInstance), null);
}

private void InitializeAttributeInstanceWithExternalValuesFromEntity(
EntityConfiguration entityConfiguration,
AttributeConfiguration attributeConfiguration,
AttributeInstance? attributeInstance
)
{
switch (attributeConfiguration.ValueType)
{
case EavAttributeType.Serial:
{
if (attributeInstance == null)
{
return;
}

var serialAttributeConfiguration = attributeConfiguration as SerialAttributeConfiguration;

var serialInstance = attributeInstance as SerialAttributeInstance;

if (serialAttributeConfiguration == null || serialInstance == null)
{
throw new ArgumentException("Invalid attribute type");
}

EntityConfigurationAttributeReference? entityAttribute = entityConfiguration.Attributes
.FirstOrDefault(x => x.AttributeConfigurationId == attributeConfiguration.Id);

if (entityAttribute == null)
{
throw new NotFoundException("Attribute not found");
}

var existingAttributeValue =
entityAttribute.AttributeConfigurationExternalValues.FirstOrDefault();

long? deserializedValue = null;

if (existingAttributeValue != null)
{
deserializedValue = JsonSerializer.Deserialize<long>(existingAttributeValue.ToString()!);
}

var newExternalValue = existingAttributeValue == null
? serialAttributeConfiguration.StartingNumber
: deserializedValue += serialAttributeConfiguration.Increment;

serialInstance.Value = newExternalValue!.Value;

entityConfiguration.UpdateAttrributeExternalValues(attributeConfiguration.Id,
new List<object> { newExternalValue }
);
}
break;
}
}
}
187 changes: 180 additions & 7 deletions CloudFabric.EAV.Service/EAVService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,91 @@ private async Task<bool> CheckAttributesListMachineNameUnique(



/// <summary>
/// Update entity configuration external values.
/// </summary>
/// <remarks>
/// Specialized method to update entity configuration external value with updating arrtibute instance value -
/// this means new instance value is not out of external value logic, and can be overwritten to it.
/// Intended use: update with a new value an attribute instance
/// whose value was initialized from the external entity configuration values.
///
/// Note that after exetuting this method entity configuration aggregate repository has uncommited events,
/// use .SaveAsync() for saving.
/// </remarks>
/// <param name="entityConfiguration"></param>
/// <param name="attributeConfiguration"></param>
/// <param name="attributeInstance"></param>
/// <returns>
/// List of validation errors or null if everithing is fine.
/// </returns>
private List<string>? UpdateEntityExternalValuesDuringInstanceUpdate(
EntityConfiguration entityConfiguration,
AttributeConfiguration attributeConfiguration,
AttributeInstance? attributeInstance
)
{
switch (attributeConfiguration.ValueType)
{
case EavAttributeType.Serial:
{
if (attributeInstance == null)
{
return null;
}

var validationErrors = new List<string>();

var serialAttributeConfiguration = attributeConfiguration as SerialAttributeConfiguration;

var serialInstance = attributeInstance as SerialAttributeInstance;

if (serialAttributeConfiguration == null || serialInstance == null)
{
validationErrors.Add("Invalid attribute type.");
}

if (serialInstance != null && !serialInstance.Value.HasValue)
{
validationErrors.Add("Updating serial number value can not be empty.");
}

EntityConfigurationAttributeReference? entityAttribute = entityConfiguration.Attributes
.FirstOrDefault(x => x.AttributeConfigurationId == attributeConfiguration.Id);

if (entityAttribute == null)
{
validationErrors.Add("Attribute configuration is not found.");
}

if (validationErrors.Count > 0)
{
return validationErrors;
}

var existingAttributeValue =
entityAttribute!.AttributeConfigurationExternalValues.First();

long? deserializedValue = JsonSerializer.Deserialize<long>(existingAttributeValue!.ToString()!);

if (serialInstance!.Value <= deserializedValue!.Value)
{
validationErrors.Add("Serial number value can not be less than the already existing one.");
return validationErrors;
}

var newExternalValue = serialInstance.Value;

entityConfiguration.UpdateAttrributeExternalValues(attributeConfiguration.Id,
new List<object> { newExternalValue! }
);

return null;
}
}
return null;
}

private async Task<ProjectionQueryResult<AttributeConfigurationListItemViewModel>> GetAttributesByIds(
List<Guid> attributesIds, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -987,8 +1072,13 @@ private JsonDocument SerializeEntityInstanceToJsonSingleLanguage(
return JsonSerializer.SerializeToDocument(entityInstanceViewModel, serializerOptions);
}

public async Task<(TViewModel, ProblemDetails)> UpdateEntityInstance(string partitionKey,
TUpdateRequest updateRequest, CancellationToken cancellationToken)
public async Task<(TViewModel, ProblemDetails)> UpdateEntityInstance(
string partitionKey,
TUpdateRequest updateRequest,
bool dryRun = false,
bool requiredAttributesCanBeNull = false,
CancellationToken cancellationToken = default
)
{
TEntityType? entityInstance =
await _entityInstanceRepository.LoadAsync(updateRequest.Id, partitionKey, cancellationToken);
Expand Down Expand Up @@ -1028,6 +1118,13 @@ await GetAttributeConfigurationsForEntityConfiguration(
.First(c => c.MachineName == attributeMachineNameToRemove);
updateRequest.AttributesToAddOrUpdate.RemoveAll(a =>
a.ConfigurationAttributeMachineName == attributeMachineNameToRemove);

if (requiredAttributesCanBeNull)
{
entityInstance.RemoveAttributeInstance(attributeMachineNameToRemove);
continue;
}

// validation against null will check if the attribute is required
List<string> errors = attrConfiguration.ValidateInstance(null);

Expand All @@ -1054,7 +1151,7 @@ await GetAttributeConfigurationsForEntityConfiguration(
}

var newAttribute = _mapper.Map<AttributeInstance>(newAttributeRequest);
List<string> errors = attrConfig.ValidateInstance(newAttribute);
List<string> errors = attrConfig.ValidateInstance(newAttribute, requiredAttributesCanBeNull);

if (errors.Count == 0)
{
Expand All @@ -1065,11 +1162,22 @@ await GetAttributeConfigurationsForEntityConfiguration(
{
if (!newAttribute.Equals(currentAttribute))
{
entityInstance.UpdateAttributeInstance(newAttribute);
var updateExternalValuesErrors = UpdateEntityExternalValuesDuringInstanceUpdate(entityConfiguration, attrConfig, newAttribute);

if (updateExternalValuesErrors == null)
{
entityInstance.UpdateAttributeInstance(newAttribute);
}
else
{
validationErrors.Add(newAttribute.ConfigurationAttributeMachineName, updateExternalValuesErrors.ToArray());
}
}
}
else
{
InitializeAttributeInstanceWithExternalValuesFromEntity(entityConfiguration, attrConfig, newAttribute);

entityInstance.AddAttributeInstance(
_mapper.Map<AttributeInstance>(newAttributeRequest)
);
Expand All @@ -1086,10 +1194,19 @@ await GetAttributeConfigurationsForEntityConfiguration(
return (null, new ValidationErrorResponse(validationErrors))!;
}

var saved = await _entityInstanceRepository.SaveAsync(_userInfo, entityInstance, cancellationToken);
if (!saved)
if (!dryRun)
{
//TODO: Throw a error when ready
var entityConfigurationSaved = await _entityConfigurationRepository
.SaveAsync(_userInfo, entityConfiguration, cancellationToken)
.ConfigureAwait(false);

var entityInstanceSaved = await _entityInstanceRepository
.SaveAsync(_userInfo, entityInstance, cancellationToken)
.ConfigureAwait(false);
if (!entityInstanceSaved || !entityConfigurationSaved)
{
//TODO: Throw a error when ready
}
}

return (_mapper.Map<TViewModel>(entityInstance), null)!;
Expand Down Expand Up @@ -1280,4 +1397,60 @@ await _attributeConfigurationRepository.LoadAsyncOrThrowNotFound(
}

#endregion

internal void InitializeAttributeInstanceWithExternalValuesFromEntity(
EntityConfiguration entityConfiguration,
AttributeConfiguration attributeConfiguration,
AttributeInstance? attributeInstance
)
{
switch (attributeConfiguration.ValueType)
{
case EavAttributeType.Serial:
{
if (attributeInstance == null)
{
return;
}

var serialAttributeConfiguration = attributeConfiguration as SerialAttributeConfiguration;

var serialInstance = attributeInstance as SerialAttributeInstance;

if (serialAttributeConfiguration == null || serialInstance == null)
{
throw new ArgumentException("Invalid attribute type");
}

EntityConfigurationAttributeReference? entityAttribute = entityConfiguration.Attributes
.FirstOrDefault(x => x.AttributeConfigurationId == attributeConfiguration.Id);

if (entityAttribute == null)
{
throw new NotFoundException("Attribute not found");
}

var existingAttributeValue =
entityAttribute.AttributeConfigurationExternalValues.FirstOrDefault();

long? deserializedValue = null;

if (existingAttributeValue != null)
{
deserializedValue = JsonSerializer.Deserialize<long>(existingAttributeValue.ToString()!);
}

var newExternalValue = existingAttributeValue == null
? serialAttributeConfiguration.StartingNumber
: deserializedValue += serialAttributeConfiguration.Increment;

serialInstance.Value = newExternalValue!.Value;

entityConfiguration.UpdateAttrributeExternalValues(attributeConfiguration.Id,
new List<object> { newExternalValue }
);
}
break;
}
}
}
Loading

0 comments on commit b61b9ae

Please sign in to comment.