Add ToonDescription metadata to entities and DTOs
Expanded use of the ToonDescription attribute across core entities and DTOs to provide rich metadata, including business rules, purposes, and status flags. Added class-level and property-level annotations to improve self-documentation and support automated tooling. Introduced new computed properties with ToonDescription in ProductDto, StockQuantityHistoryDto, and StockTakingItem. Updated ToonTypeRelation with an Entity constant. Enhanced test coverage for Toon metadata. Cleaned up imports and removed obsolete test_debug.ps1 script. Updated settings.local.json to support additional Bash commands for tooling. These changes improve introspectability and support for serialization, UI, and API documentation.
This commit is contained in:
parent
3700bfdb29
commit
dd3c1c58c0
|
|
@ -6,7 +6,11 @@
|
||||||
"Bash(find:*)",
|
"Bash(find:*)",
|
||||||
"Bash(grep:*)",
|
"Bash(grep:*)",
|
||||||
"Bash(dotnet test:*)",
|
"Bash(dotnet test:*)",
|
||||||
"Bash(dotnet build:*)"
|
"Bash(dotnet build:*)",
|
||||||
|
"Bash(ls:*)",
|
||||||
|
"Bash(while read:*)",
|
||||||
|
"Bash(do sed -i '1a using AyCode.Core.Serializers.Toons;\\\\n' \"$f\")",
|
||||||
|
"Bash(done)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,15 +71,15 @@ public class OrderDto : MgOrderDto<OrderItemDto, ProductDto>, IOrderDto
|
||||||
public DateTime DateOfReceiptOrCreated => DateOfReceipt ?? CreatedOnUtc;
|
public DateTime DateOfReceiptOrCreated => DateOfReceipt ?? CreatedOnUtc;
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrNull<DateTime>(nameof(IOrderDto.DateOfReceipt))")]
|
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrNull<DateTime>('DateOfReceipt')")]
|
||||||
public DateTime? DateOfReceipt => GenericAttributes.GetValueOrNull<DateTime>(nameof(IOrderDto.DateOfReceipt));
|
public DateTime? DateOfReceipt => GenericAttributes.GetValueOrNull<DateTime>(nameof(IOrderDto.DateOfReceipt));
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault(nameof(IOrderDto.RevisorId), 0)")]
|
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault('RevisorId', 0)")]
|
||||||
public int RevisorId => GenericAttributes.GetValueOrDefault(nameof(IOrderDto.RevisorId), 0);
|
public int RevisorId => GenericAttributes.GetValueOrDefault(nameof(IOrderDto.RevisorId), 0);
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault(nameof(IOrderDto.MeasurementOwnerId), 0)")]
|
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault('MeasurementOwnerId', 0)")]
|
||||||
public int MeasurementOwnerId => GenericAttributes.GetValueOrDefault(nameof(IOrderDto.MeasurementOwnerId), 0);
|
public int MeasurementOwnerId => GenericAttributes.GetValueOrDefault(nameof(IOrderDto.MeasurementOwnerId), 0);
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace FruitBank.Common.Dtos;
|
||||||
|
|
||||||
[LinqToDB.Mapping.Table(Name = nameof(OrderItem))]
|
[LinqToDB.Mapping.Table(Name = nameof(OrderItem))]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(nameof(OrderItem))]
|
[System.ComponentModel.DataAnnotations.Schema.Table(nameof(OrderItem))]
|
||||||
[ToonDescription($"Data transfer object for {nameof(OrderItem)}", TypeRelation = ToonTypeRelation.DtoOf, RelatedTypes = [typeof(OrderItem)])]
|
[ToonDescription("Order item with measurements, pallets, and validation", TypeRelation = ToonTypeRelation.DtoOf, RelatedTypes = [typeof(OrderItem)])]
|
||||||
public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
{
|
{
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
|
@ -35,6 +35,7 @@ public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
public OrderDto OrderDto { get; set; }
|
public OrderDto OrderDto { get; set; }
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Status flag", BusinessRule = "get => IsMeasuredAndValid()")]
|
||||||
public bool IsMeasured
|
public bool IsMeasured
|
||||||
{
|
{
|
||||||
get => IsMeasuredAndValid();
|
get => IsMeasuredAndValid();
|
||||||
|
|
@ -42,7 +43,7 @@ public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
[ToonDescription(BusinessRule = "get => ProductDto!.IsMeasurable", Constraints = "[#SmartTypeConstraints], readonly")]
|
[ToonDescription(Purpose = "Status flag", BusinessRule = "get => ProductDto!.IsMeasurable")]
|
||||||
public bool IsMeasurable
|
public bool IsMeasurable
|
||||||
{
|
{
|
||||||
get => ProductDto!.IsMeasurable;
|
get => ProductDto!.IsMeasurable;
|
||||||
|
|
@ -50,7 +51,7 @@ public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
[ToonDescription(BusinessRule = "get => OrderItemPallets.Sum(x => x.TrayQuantity)", Constraints = "[#SmartTypeConstraints], readonly")]
|
[ToonDescription(BusinessRule = "get => OrderItemPallets.Sum(x => x.TrayQuantity)")]
|
||||||
public int TrayQuantity
|
public int TrayQuantity
|
||||||
{
|
{
|
||||||
get => OrderItemPallets.Sum(x => x.TrayQuantity);
|
get => OrderItemPallets.Sum(x => x.TrayQuantity);
|
||||||
|
|
@ -58,7 +59,7 @@ public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
[ToonDescription(BusinessRule = "get => double.Round(OrderItemPallets.Sum(x => x.NetWeight), 1)", Constraints = "[#SmartTypeConstraints], readonly")]
|
[ToonDescription(BusinessRule = "get => double.Round(OrderItemPallets.Sum(x => x.NetWeight), 1)")]
|
||||||
public double NetWeight
|
public double NetWeight
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -76,7 +77,7 @@ public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
[ToonDescription(BusinessRule = "get => double.Round(OrderItemPallets.Sum(x => x.NetWeight), 1)", Constraints = "[#SmartTypeConstraints], readonly")]
|
[ToonDescription(BusinessRule = "get => double.Round(OrderItemPallets.Sum(x => x.NetWeight), 1)")]
|
||||||
public double GrossWeight
|
public double GrossWeight
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -94,19 +95,24 @@ public class OrderItemDto : MgOrderItemDto<ProductDto>, IOrderItemDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => IsMeasurable && OrderItemPallets.Count > 0 ? double.Round(OrderItemPallets.Sum(oip => oip.AverageWeight) / OrderItemPallets.Count, 1) : 0d")]
|
||||||
public double AverageWeight => IsMeasurable && OrderItemPallets.Count > 0 ? double.Round(OrderItemPallets.Sum(oip => oip.AverageWeight) / OrderItemPallets.Count, 1) : 0d;
|
public double AverageWeight => IsMeasurable && OrderItemPallets.Count > 0 ? double.Round(OrderItemPallets.Sum(oip => oip.AverageWeight) / OrderItemPallets.Count, 1) : 0d;
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => IsMeasurable ? double.Round(ProductDto!.AverageWeight - AverageWeight, 1) : 0")]
|
||||||
public double AverageWeightDifference => IsMeasurable ? double.Round(ProductDto!.AverageWeight - AverageWeight, 1) : 0;
|
public double AverageWeightDifference => IsMeasurable ? double.Round(ProductDto!.AverageWeight - AverageWeight, 1) : 0;
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
public bool AverageWeightIsValid => !IsMeasurable ||
|
[ToonDescription(BusinessRule = "get => !IsMeasurable || (ProductDto!.AverageWeight > 0 && ((AverageWeightDifference / ProductDto!.AverageWeight) * 100) < ProductDto!.AverageWeightTreshold)")]
|
||||||
|
public bool AverageWeightIsValid => !IsMeasurable ||
|
||||||
(ProductDto!.AverageWeight > 0 && ((AverageWeightDifference / ProductDto!.AverageWeight) * 100) < ProductDto!.AverageWeightTreshold);
|
(ProductDto!.AverageWeight > 0 && ((AverageWeightDifference / ProductDto!.AverageWeight) * 100) < ProductDto!.AverageWeightTreshold);
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Status flag", BusinessRule = "get => OrderItemPallets.Count > 0 && OrderItemPallets.All(oip => oip.IsAudited)")]
|
||||||
public bool IsAudited => OrderItemPallets.Count > 0 && OrderItemPallets.All(oip => oip.IsAudited);
|
public bool IsAudited => OrderItemPallets.Count > 0 && OrderItemPallets.All(oip => oip.IsAudited);
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => complex conditional logic based on IsAudited, IsMeasured, and OrderItemPallets status")]
|
||||||
public MeasuringStatus MeasuringStatus
|
public MeasuringStatus MeasuringStatus
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Mango.Nop.Core.Interfaces.ForeignKeys;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
//using Nop.Core.Domain.Catalog;
|
//using Nop.Core.Domain.Catalog;
|
||||||
using Nop.Core.Domain.Common;
|
using Nop.Core.Domain.Common;
|
||||||
|
using Nop.Core.Domain.Orders;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
|
@ -14,7 +15,7 @@ namespace FruitBank.Common.Dtos;
|
||||||
|
|
||||||
[LinqToDB.Mapping.Table(Name = "Product")]
|
[LinqToDB.Mapping.Table(Name = "Product")]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table("Product")]
|
[System.ComponentModel.DataAnnotations.Schema.Table("Product")]
|
||||||
[ToonDescription($"Data transfer object for Product")]
|
[ToonDescription("Product data with measurements and generic attributes", TypeRelation = ToonTypeRelation.DtoOf)]
|
||||||
public class ProductDto : MgProductDto, IProductDto
|
public class ProductDto : MgProductDto, IProductDto
|
||||||
{
|
{
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
|
@ -33,6 +34,7 @@ public class ProductDto : MgProductDto, IProductDto
|
||||||
//{ }
|
//{ }
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Status flag", BusinessRule = "get => GenericAttributes.GetValueOrDefault<bool>('IsMeasurable')")]
|
||||||
public bool IsMeasurable
|
public bool IsMeasurable
|
||||||
{
|
{
|
||||||
get => GenericAttributes.GetValueOrDefault<bool>(nameof(IMeasurable.IsMeasurable));
|
get => GenericAttributes.GetValueOrDefault<bool>(nameof(IMeasurable.IsMeasurable));
|
||||||
|
|
@ -47,6 +49,7 @@ public class ProductDto : MgProductDto, IProductDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault<double>('Tare')")]
|
||||||
public double Tare
|
public double Tare
|
||||||
{
|
{
|
||||||
get => GenericAttributes.GetValueOrDefault<double>(nameof(ITare.Tare));
|
get => GenericAttributes.GetValueOrDefault<double>(nameof(ITare.Tare));
|
||||||
|
|
@ -55,6 +58,7 @@ public class ProductDto : MgProductDto, IProductDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault<double>('NetWeight')")]
|
||||||
public double NetWeight
|
public double NetWeight
|
||||||
{
|
{
|
||||||
get => GenericAttributes.GetValueOrDefault<double>(nameof(IMeasuringNetWeight.NetWeight));
|
get => GenericAttributes.GetValueOrDefault<double>(nameof(IMeasuringNetWeight.NetWeight));
|
||||||
|
|
@ -62,13 +66,14 @@ public class ProductDto : MgProductDto, IProductDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault<int>('IncomingQuantity')")]
|
||||||
public int IncomingQuantity
|
public int IncomingQuantity
|
||||||
{
|
{
|
||||||
get => GenericAttributes.GetValueOrDefault<int>(nameof(IIncomingQuantity.IncomingQuantity));
|
get => GenericAttributes.GetValueOrDefault<int>(nameof(IIncomingQuantity.IncomingQuantity));
|
||||||
set => throw new Exception($"ProductDto.IncomingQuantity not set");
|
set => throw new Exception($"ProductDto.IncomingQuantity not set");
|
||||||
//set
|
//set
|
||||||
//{
|
//{
|
||||||
// var ga = GenericAttributes.FirstOrDefault(ga => ga.Key == nameof(IIncomingQuantity.IncomingQuantity)) ??
|
// var ga = GenericAttributes.FirstOrDefault(ga => ga.Key == nameof(IIncomingQuantity.IncomingQuantity)) ??
|
||||||
// GenericAttributes.AddNewGenericAttribute("Product", nameof(IIncomingQuantity.IncomingQuantity), value.ToString(), Id);
|
// GenericAttributes.AddNewGenericAttribute("Product", nameof(IIncomingQuantity.IncomingQuantity), value.ToString(), Id);
|
||||||
|
|
||||||
// ga.Value = value.ToString();
|
// ga.Value = value.ToString();
|
||||||
|
|
@ -76,12 +81,15 @@ public class ProductDto : MgProductDto, IProductDto
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => StockQuantity + IncomingQuantity")]
|
||||||
public int AvailableQuantity => StockQuantity + IncomingQuantity;
|
public int AvailableQuantity => StockQuantity + IncomingQuantity;
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault<double>('AverageWeight')")]
|
||||||
public double AverageWeight => GenericAttributes.GetValueOrDefault<double>(nameof(IProductDto.AverageWeight));
|
public double AverageWeight => GenericAttributes.GetValueOrDefault<double>(nameof(IProductDto.AverageWeight));
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => GenericAttributes.GetValueOrDefault<double>('AverageWeightTreshold')")]
|
||||||
public double AverageWeightTreshold => GenericAttributes.GetValueOrDefault<double>(nameof(IProductDto.AverageWeightTreshold));
|
public double AverageWeightTreshold => GenericAttributes.GetValueOrDefault<double>(nameof(IProductDto.AverageWeightTreshold));
|
||||||
|
|
||||||
public bool HasMeasuringValues() => Id > 0 && NetWeight != 0 && IsMeasurable;
|
public bool HasMeasuringValues() => Id > 0 && NetWeight != 0 && IsMeasurable;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using AyCode.Core.Serializers.Toons;
|
using AyCode.Core.Serializers.Toons;
|
||||||
using FruitBank.Common.Interfaces;
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Dtos;
|
using Mango.Nop.Core.Dtos;
|
||||||
|
|
@ -18,10 +18,11 @@ namespace FruitBank.Common.Dtos
|
||||||
{
|
{
|
||||||
[LinqToDB.Mapping.Table(Name = nameof(StockQuantityHistory))]
|
[LinqToDB.Mapping.Table(Name = nameof(StockQuantityHistory))]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(nameof(StockQuantityHistory))]
|
[System.ComponentModel.DataAnnotations.Schema.Table(nameof(StockQuantityHistory))]
|
||||||
[ToonDescription($"Data transfer object for {nameof(StockQuantityHistory)}", TypeRelation = ToonTypeRelation.DtoOf, RelatedTypes = [typeof(StockQuantityHistory)])]
|
[ToonDescription("Stock quantity history with net weight adjustments", TypeRelation = ToonTypeRelation.DtoOf, RelatedTypes = [typeof(StockQuantityHistory)])]
|
||||||
public class StockQuantityHistoryDto : MgStockQuantityHistoryDto<ProductDto>, IStockQuantityHistoryDto
|
public class StockQuantityHistoryDto : MgStockQuantityHistoryDto<ProductDto>, IStockQuantityHistoryDto
|
||||||
{
|
{
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => StockQuantityHistoryExt?.StockQuantityHistoryId")]
|
||||||
public int? StockQuantityHistoryId
|
public int? StockQuantityHistoryId
|
||||||
{
|
{
|
||||||
get => StockQuantityHistoryExt?.StockQuantityHistoryId;
|
get => StockQuantityHistoryExt?.StockQuantityHistoryId;
|
||||||
|
|
@ -29,6 +30,7 @@ namespace FruitBank.Common.Dtos
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => StockQuantityHistoryExt?.NetWeightAdjustment")]
|
||||||
public double? NetWeightAdjustment
|
public double? NetWeightAdjustment
|
||||||
{
|
{
|
||||||
get => StockQuantityHistoryExt?.NetWeightAdjustment;
|
get => StockQuantityHistoryExt?.NetWeightAdjustment;
|
||||||
|
|
@ -36,20 +38,22 @@ namespace FruitBank.Common.Dtos
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => StockQuantityHistoryExt?.NetWeight")]
|
||||||
public double? NetWeight
|
public double? NetWeight
|
||||||
{
|
{
|
||||||
get => StockQuantityHistoryExt?.NetWeight;
|
get => StockQuantityHistoryExt?.NetWeight;
|
||||||
set => StockQuantityHistoryExt!.NetWeight = value;
|
set => StockQuantityHistoryExt!.NetWeight = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Status flag", BusinessRule = "get => StockQuantityHistoryExt?.IsInconsistent ?? false")]
|
||||||
public bool IsInconsistent
|
public bool IsInconsistent
|
||||||
{
|
{
|
||||||
get => StockQuantityHistoryExt?.IsInconsistent ?? false;
|
get => StockQuantityHistoryExt?.IsInconsistent ?? false;
|
||||||
set => StockQuantityHistoryExt!.IsInconsistent = value;
|
set => StockQuantityHistoryExt!.IsInconsistent = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Association(ThisKey = nameof(Id), OtherKey = nameof(StockQuantityHistoryExt.StockQuantityHistoryId), CanBeNull = true)]
|
[Association(ThisKey = nameof(Id), OtherKey = nameof(StockQuantityHistoryExt.StockQuantityHistoryId), CanBeNull = true)]
|
||||||
public StockQuantityHistoryExt? StockQuantityHistoryExt { get; set; }
|
public StockQuantityHistoryExt? StockQuantityHistoryExt { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
using FruitBank.Common.Interfaces;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Uploaded file with extracted text content", Purpose = "A centralized repository for all uploaded binary content and metadata, featuring a 'RawText' field that stores OCR-extracted information for full-text search and automated data validation across the system")]
|
||||||
[Table(Name = FruitBankConstClient.FilesDbTableName)]
|
[Table(Name = FruitBankConstClient.FilesDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.FilesDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.FilesDbTableName)]
|
||||||
public class Files : MgEntityBase, IFiles
|
public class Files : MgEntityBase, IFiles
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using AyCode.Core.Serializers.Toons;
|
||||||
using FruitBank.Common.Dtos;
|
using FruitBank.Common.Dtos;
|
||||||
using FruitBank.Common.Enums;
|
using FruitBank.Common.Enums;
|
||||||
using FruitBank.Common.Interfaces;
|
using FruitBank.Common.Interfaces;
|
||||||
|
|
@ -8,6 +9,7 @@ using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Base class for pallet measurements with net weight calculation")]
|
||||||
public abstract class MeasuringItemPalletBase : MgEntityBase, IMeasuringItemPalletBase
|
public abstract class MeasuringItemPalletBase : MgEntityBase, IMeasuringItemPalletBase
|
||||||
{
|
{
|
||||||
private double _palletWeight;
|
private double _palletWeight;
|
||||||
|
|
@ -16,7 +18,9 @@ public abstract class MeasuringItemPalletBase : MgEntityBase, IMeasuringItemPall
|
||||||
|
|
||||||
[NotColumn]
|
[NotColumn]
|
||||||
protected int ForeignItemId;
|
protected int ForeignItemId;
|
||||||
|
|
||||||
[NotColumn]
|
[NotColumn]
|
||||||
|
[ToonDescription(BusinessRule = "get => ForeignItemId")]
|
||||||
public int ForeignKey => ForeignItemId;
|
public int ForeignKey => ForeignItemId;
|
||||||
|
|
||||||
public int TrayQuantity { get; set; }
|
public int TrayQuantity { get; set; }
|
||||||
|
|
@ -36,6 +40,7 @@ public abstract class MeasuringItemPalletBase : MgEntityBase, IMeasuringItemPall
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, System.ComponentModel.DataAnnotations.Schema.NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, System.ComponentModel.DataAnnotations.Schema.NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => CalculateNetWeight()", Constraints = "[#SmartTypeConstraints], readonly")]
|
||||||
public double NetWeight
|
public double NetWeight
|
||||||
{
|
{
|
||||||
get => CalculateNetWeight();
|
get => CalculateNetWeight();
|
||||||
|
|
@ -60,6 +65,7 @@ public abstract class MeasuringItemPalletBase : MgEntityBase, IMeasuringItemPall
|
||||||
public DateTime Modified { get; set; }
|
public DateTime Modified { get; set; }
|
||||||
|
|
||||||
[NotColumn, System.ComponentModel.DataAnnotations.Schema.NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, System.ComponentModel.DataAnnotations.Schema.NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => IsMeasured ? MeasuringStatus.Finnished : Id > 0 ? MeasuringStatus.Started : MeasuringStatus.NotStarted")]
|
||||||
public virtual MeasuringStatus MeasuringStatus => IsMeasured ? MeasuringStatus.Finnished : Id > 0 ? MeasuringStatus.Started : MeasuringStatus.NotStarted;
|
public virtual MeasuringStatus MeasuringStatus => IsMeasured ? MeasuringStatus.Finnished : Id > 0 ? MeasuringStatus.Started : MeasuringStatus.NotStarted;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using AyCode.Core.Serializers.Toons;
|
||||||
using FruitBank.Common.Dtos;
|
using FruitBank.Common.Dtos;
|
||||||
using FruitBank.Common.Enums;
|
using FruitBank.Common.Enums;
|
||||||
using FruitBank.Common.Interfaces;
|
using FruitBank.Common.Interfaces;
|
||||||
|
|
@ -10,6 +11,7 @@ using Table = LinqToDB.Mapping.TableAttribute;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Pallet measurements for order items with audit tracking", Purpose = "A measurement record for outgoing goods, used to verify that the net weight being sent to the customer is accurate and audited")]
|
||||||
[Table(Name = FruitBankConstClient.OrderItemPalletDbTableName)]
|
[Table(Name = FruitBankConstClient.OrderItemPalletDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.OrderItemPalletDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.OrderItemPalletDbTableName)]
|
||||||
public class OrderItemPallet : MeasuringItemPalletBase, IOrderItemPallet
|
public class OrderItemPallet : MeasuringItemPalletBase, IOrderItemPallet
|
||||||
|
|
@ -21,6 +23,9 @@ public class OrderItemPallet : MeasuringItemPalletBase, IOrderItemPallet
|
||||||
}
|
}
|
||||||
|
|
||||||
public int RevisorId { get; set; }
|
public int RevisorId { get; set; }
|
||||||
|
|
||||||
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Status flag", BusinessRule = "get => RevisorId > 0")]
|
||||||
public bool IsAudited => RevisorId > 0;
|
public bool IsAudited => RevisorId > 0;
|
||||||
|
|
||||||
//[JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
//[JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
|
@ -28,6 +33,7 @@ public class OrderItemPallet : MeasuringItemPalletBase, IOrderItemPallet
|
||||||
public OrderItemDto? OrderItemDto { get; set; }
|
public OrderItemDto? OrderItemDto { get; set; }
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => IsAudited ? MeasuringStatus.Audited : base.MeasuringStatus")]
|
||||||
public override MeasuringStatus MeasuringStatus => IsAudited ? MeasuringStatus.Audited : base.MeasuringStatus;
|
public override MeasuringStatus MeasuringStatus => IsAudited ? MeasuringStatus.Audited : base.MeasuringStatus;
|
||||||
public override double CalculateNetWeight() => base.CalculateNetWeight();
|
public override double CalculateNetWeight() => base.CalculateNetWeight();
|
||||||
|
|
||||||
|
|
@ -37,6 +43,7 @@ public class OrderItemPallet : MeasuringItemPalletBase, IOrderItemPallet
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => double.Round(NetWeight / TrayQuantity, 1)")]
|
||||||
public double AverageWeight => double.Round(NetWeight / TrayQuantity, 1);
|
public double AverageWeight => double.Round(NetWeight / TrayQuantity, 1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
using FruitBank.Common.Interfaces;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Pallet type definition with size and weight")]
|
||||||
[Table(Name = FruitBankConstClient.PalletDbTableName)]
|
[Table(Name = FruitBankConstClient.PalletDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.PalletDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.PalletDbTableName)]
|
||||||
public class Pallet : MgEntityBase, IPallet
|
public class Pallet : MgEntityBase, IPallet
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
using FruitBank.Common.Interfaces;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Business partner with address and tax information", Purpose = "Represents an external legal entity, specifically a Supplier who provides goods or a business partner involved in the procurement chain")]
|
||||||
[Table(Name = FruitBankConstClient.PartnerDbTableName)]
|
[Table(Name = FruitBankConstClient.PartnerDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.PartnerDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.PartnerDbTableName)]
|
||||||
public class Partner : MgEntityBase, IPartner
|
public class Partner : MgEntityBase, IPartner
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
using FruitBank.Common.Interfaces;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Shipping record with documents and measurement tracking", Purpose = "Represents a physical inbound delivery event (truck arrival) at the warehouse, tracking the vehicle and the overall measurement status of the shipment")]
|
||||||
[Table(Name = FruitBankConstClient.ShippingDbTableName)]
|
[Table(Name = FruitBankConstClient.ShippingDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDbTableName)]
|
||||||
public class Shipping : MgEntityBase, IShipping
|
public class Shipping : MgEntityBase, IShipping
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using AyCode.Core.Serializers.Toons;
|
||||||
using FruitBank.Common.Interfaces;
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Shipping document with partner, items and files", Purpose = "A digital representation of a supplier's delivery note or invoice associated with the shipment, used for reconciling paper-based data with measured reality")]
|
||||||
[Table(Name = FruitBankConstClient.ShippingDocumentDbTableName)]
|
[Table(Name = FruitBankConstClient.ShippingDocumentDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDocumentDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDocumentDbTableName)]
|
||||||
public class ShippingDocument : MgEntityBase, IShippingDocument
|
public class ShippingDocument : MgEntityBase, IShippingDocument
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using AyCode.Core.Serializers.Toons;
|
||||||
using FruitBank.Common.Interfaces;
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
@ -6,6 +7,7 @@ using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Links shipping documents to files with document type", Purpose = "A many-to-many link table that associates general uploaded files with specific shipping documents, assigning a functional context (DocumentType) to each file, such as identifying which PDF is the supplier's invoice versus the packing list")]
|
||||||
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.ShippingDocumentToFilesDbTableName)]
|
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.ShippingDocumentToFilesDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDocumentToFilesDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDocumentToFilesDbTableName)]
|
||||||
public class ShippingDocumentToFiles : MgEntityBase, IShippingDocumentToFiles
|
public class ShippingDocumentToFiles : MgEntityBase, IShippingDocumentToFiles
|
||||||
|
|
@ -16,6 +18,7 @@ public class ShippingDocumentToFiles : MgEntityBase, IShippingDocumentToFiles
|
||||||
public int DocumentTypeId { get; set; }
|
public int DocumentTypeId { get; set; }
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Enum wrapper", BusinessRule = "get, set => DocumentTypeId")]
|
||||||
public DocumentType DocumentType
|
public DocumentType DocumentType
|
||||||
{
|
{
|
||||||
get => (DocumentType)DocumentTypeId;
|
get => (DocumentType)DocumentTypeId;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using AyCode.Core.Interfaces;
|
using AyCode.Core.Interfaces;
|
||||||
|
using AyCode.Core.Serializers.Toons;
|
||||||
using FruitBank.Common.Dtos;
|
using FruitBank.Common.Dtos;
|
||||||
using FruitBank.Common.Enums;
|
using FruitBank.Common.Enums;
|
||||||
using FruitBank.Common.Interfaces;
|
using FruitBank.Common.Interfaces;
|
||||||
|
|
@ -17,6 +18,7 @@ using Table = LinqToDB.Mapping.TableAttribute;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Shipping document item with measurements and pallets", Purpose = "Represents a specific product line item within a shipping document, storing the discrepancy between the supplier's declared weight/quantity and the warehouse's measured values")]
|
||||||
[Table(Name = FruitBankConstClient.ShippingItemDbTableName)]
|
[Table(Name = FruitBankConstClient.ShippingItemDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingItemDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingItemDbTableName)]
|
||||||
public class ShippingItem : MgEntityBase, IShippingItem
|
public class ShippingItem : MgEntityBase, IShippingItem
|
||||||
|
|
@ -29,10 +31,8 @@ public class ShippingItem : MgEntityBase, IShippingItem
|
||||||
public string NameOnDocument { get; set; }
|
public string NameOnDocument { get; set; }
|
||||||
public string HungarianName { get; set; }
|
public string HungarianName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// get => ProductDto?.Name ?? Name
|
|
||||||
/// </summary>
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => ProductDto?.Name ?? Name")]
|
||||||
public string ProductName => ProductDto?.Name ?? Name;
|
public string ProductName => ProductDto?.Name ?? Name;
|
||||||
|
|
||||||
public int PalletsOnDocument { get; set; }
|
public int PalletsOnDocument { get; set; }
|
||||||
|
|
@ -84,6 +84,7 @@ public class ShippingItem : MgEntityBase, IShippingItem
|
||||||
public DateTime Modified { get; set; }
|
public DateTime Modified { get; set; }
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => complex conditional logic based on IsMeasured and ShippingItemPallets status")]
|
||||||
public MeasuringStatus MeasuringStatus
|
public MeasuringStatus MeasuringStatus
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using FruitBank.Common.Interfaces;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
@ -6,6 +7,7 @@ using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Pallet measurements for shipping items", Purpose = "The smallest unit of measurement tracking, representing a single physical pallet of a shipping item, used for precise gross-to-net weight calculation and quality audit")]
|
||||||
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.ShippingItemPalletDbTableName)]
|
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.ShippingItemPalletDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingItemPalletDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingItemPalletDbTableName)]
|
||||||
public class ShippingItemPallet : MeasuringItemPalletBase, IShippingItemPallet
|
public class ShippingItemPallet : MeasuringItemPalletBase, IShippingItemPallet
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
|
||||||
namespace Mango.Nop.Core.Entities
|
namespace Mango.Nop.Core.Entities
|
||||||
{
|
{
|
||||||
|
|
@ -23,6 +24,7 @@ namespace Mango.Nop.Core.Entities
|
||||||
|
|
||||||
[Table(Name = FruitBankConstClient.StockQuantityHistoryExtDbTableName)]
|
[Table(Name = FruitBankConstClient.StockQuantityHistoryExtDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockQuantityHistoryExtDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockQuantityHistoryExtDbTableName)]
|
||||||
|
[ToonDescription("Extended weight-metadata for StockQuantityHistory", Purpose = "Validates quantity deltas against measured weight to detect inconsistencies")]
|
||||||
public class StockQuantityHistoryExt : MgEntityBase, IStockQuantityHistoryExt
|
public class StockQuantityHistoryExt : MgEntityBase, IStockQuantityHistoryExt
|
||||||
{
|
{
|
||||||
public int StockQuantityHistoryId { get; set; }
|
public int StockQuantityHistoryId { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
using LinqToDB.Mapping;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Inventory session record", Purpose = "Orchestrates inventory sessions by freezing logical stock states")]
|
||||||
[Table(Name = FruitBankConstClient.StockTakingDbTableName)]
|
[Table(Name = FruitBankConstClient.StockTakingDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingDbTableName)]
|
||||||
public class StockTaking : MgStockTaking<StockTakingItem>
|
public class StockTaking : MgStockTaking<StockTakingItem>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using FruitBank.Common.Dtos;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Dtos;
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
@ -9,6 +10,7 @@ using Table = LinqToDB.Mapping.TableAttribute;
|
||||||
|
|
||||||
namespace FruitBank.Common.Entities;
|
namespace FruitBank.Common.Entities;
|
||||||
|
|
||||||
|
[ToonDescription("Line item for product reconciliation", Purpose = "Reconciles snapshot quantity with physical count to calculate final stock delta")]
|
||||||
[Table(Name = FruitBankConstClient.StockTakingItemDbTableName)]
|
[Table(Name = FruitBankConstClient.StockTakingItemDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingItemDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingItemDbTableName)]
|
||||||
public class StockTakingItem : MgStockTakingItem<StockTaking, ProductDto>
|
public class StockTakingItem : MgStockTakingItem<StockTaking, ProductDto>
|
||||||
|
|
@ -21,27 +23,34 @@ public class StockTakingItem : MgStockTakingItem<StockTaking, ProductDto>
|
||||||
[Column(DataType = DataType.DecFloat, CanBeNull = false)]
|
[Column(DataType = DataType.DecFloat, CanBeNull = false)]
|
||||||
public double MeasuredNetWeight { get; set; }
|
public double MeasuredNetWeight { get; set; }
|
||||||
|
|
||||||
|
[ToonDescription(Purpose = "Reserved stock buffer to prevent double-deduction during closing")]
|
||||||
public int InProcessOrdersQuantity { get; set; }
|
public int InProcessOrdersQuantity { get; set; }
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => OriginalStockQuantity + InProcessOrdersQuantity")]
|
||||||
public int TotalOriginalQuantity => OriginalStockQuantity + InProcessOrdersQuantity;
|
public int TotalOriginalQuantity => OriginalStockQuantity + InProcessOrdersQuantity;
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Final adjustment value for Product.StockQuantity", BusinessRule = "get => IsMeasured ? MeasuredStockQuantity - TotalOriginalQuantity : 0")]
|
||||||
public int QuantityDiff => IsMeasured ? MeasuredStockQuantity - TotalOriginalQuantity : 0;
|
public int QuantityDiff => IsMeasured ? MeasuredStockQuantity - TotalOriginalQuantity : 0;
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => IsMeasurable && IsMeasured ? double.Round(MeasuredNetWeight - OriginalNetWeight, 1) : 0d")]
|
||||||
public double NetWeightDiff => IsMeasurable && IsMeasured ? double.Round(MeasuredNetWeight - OriginalNetWeight, 1) : 0d;
|
public double NetWeightDiff => IsMeasurable && IsMeasured ? double.Round(MeasuredNetWeight - OriginalNetWeight, 1) : 0d;
|
||||||
|
|
||||||
[Association(ThisKey = nameof(Id), OtherKey = nameof(StockTakingItemPallet.StockTakingItemId), CanBeNull = true)]
|
[Association(ThisKey = nameof(Id), OtherKey = nameof(StockTakingItemPallet.StockTakingItemId), CanBeNull = true)]
|
||||||
public List<StockTakingItemPallet>? StockTakingItemPallets { get; set; }
|
public List<StockTakingItemPallet>? StockTakingItemPallets { get; set; }
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Status flag", BusinessRule = "get => !IsInvalid && (TotalOriginalQuantity != 0 || OriginalNetWeight != 0)")]
|
||||||
public bool IsRequiredForMeasuring => !IsInvalid && (TotalOriginalQuantity != 0 || OriginalNetWeight != 0);
|
public bool IsRequiredForMeasuring => !IsInvalid && (TotalOriginalQuantity != 0 || OriginalNetWeight != 0);
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(Purpose = "Status flag", BusinessRule = "get => TotalOriginalQuantity < 0")]
|
||||||
public bool IsInvalid => TotalOriginalQuantity < 0;
|
public bool IsInvalid => TotalOriginalQuantity < 0;
|
||||||
|
|
||||||
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
[NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
[ToonDescription(BusinessRule = "get => conditional string based on IsInvalid, IsMeasured, IsRequiredForMeasuring")]
|
||||||
public string DisplayText
|
public string DisplayText
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using FruitBank.Common.Dtos;
|
using AyCode.Core.Serializers.Toons;
|
||||||
|
using FruitBank.Common.Dtos;
|
||||||
using FruitBank.Common.Interfaces;
|
using FruitBank.Common.Interfaces;
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
using Mango.Nop.Core.Entities;
|
using Mango.Nop.Core.Entities;
|
||||||
|
|
@ -12,6 +13,7 @@ public interface IStockTakingItemPallet : IMeasuringItemPalletBase
|
||||||
public StockTakingItem? StockTakingItem{ get; set; }
|
public StockTakingItem? StockTakingItem{ get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ToonDescription("Weight record for inventory item", Purpose = "Granular weight-based evidence for a stock taking line item")]
|
||||||
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.StockTakingItemPalletDbTableName)]
|
[LinqToDB.Mapping.Table(Name = FruitBankConstClient.StockTakingItemPalletDbTableName)]
|
||||||
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingItemPalletDbTableName)]
|
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.StockTakingItemPalletDbTableName)]
|
||||||
public class StockTakingItemPallet : MeasuringItemPalletBase, IStockTakingItemPallet
|
public class StockTakingItemPallet : MeasuringItemPalletBase, IStockTakingItemPallet
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
using AyCode.Core.Enums;
|
using AyCode.Core.Enums;
|
||||||
using AyCode.Core.Extensions;
|
using AyCode.Core.Extensions;
|
||||||
using AyCode.Core.Loggers;
|
using AyCode.Core.Loggers;
|
||||||
|
using AyCode.Core.Serializers.Toons;
|
||||||
using FruitBank.Common;
|
using FruitBank.Common;
|
||||||
using FruitBank.Common.Dtos;
|
using FruitBank.Common.Dtos;
|
||||||
using FruitBank.Common.Entities;
|
using FruitBank.Common.Entities;
|
||||||
using FruitBank.Common.Loggers;
|
using FruitBank.Common.Loggers;
|
||||||
using FruitBankHybrid.Shared.Services.SignalRs;
|
using FruitBankHybrid.Shared.Services.SignalRs;
|
||||||
|
using Mango.Nop.Core.Entities;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Nop.Core.Domain.Catalog;
|
||||||
using Nop.Core.Domain.Common;
|
using Nop.Core.Domain.Common;
|
||||||
using Nop.Core.Domain.Orders;
|
using Nop.Core.Domain.Orders;
|
||||||
using Nop.Core.Domain.Payments;
|
using Nop.Core.Domain.Payments;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using AyCode.Core.Serializers.Toons;
|
|
||||||
|
|
||||||
namespace FruitBankHybrid.Shared.Tests;
|
namespace FruitBankHybrid.Shared.Tests;
|
||||||
|
|
||||||
|
|
@ -37,9 +39,9 @@ public sealed class ToonTests
|
||||||
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void OrderDtoToToon()
|
public async Task OrderDtoToToon()
|
||||||
{
|
{
|
||||||
var orderDtos = _signalRClient.GetAllOrderDtos();
|
var orderDtos = await _signalRClient.GetAllOrderDtos();
|
||||||
var toon = AcToonSerializer.Serialize(orderDtos, AcToonSerializerOptions.Default);
|
var toon = AcToonSerializer.Serialize(orderDtos, AcToonSerializerOptions.Default);
|
||||||
|
|
||||||
Console.WriteLine(toon);
|
Console.WriteLine(toon);
|
||||||
|
|
@ -106,7 +108,7 @@ public sealed class ToonTests
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void ToonTypes_NavigationMetadata_ShouldBeComplete()
|
public void ToonTypes_NavigationMetadata_ShouldBeComplete()
|
||||||
{
|
{
|
||||||
var toon = AcToonSerializer.SerializeMetadata([typeof(Shipping), typeof(OrderDto)]);
|
var toon = AcToonSerializer.SerializeMetadata([typeof(Shipping), typeof(OrderDto), typeof(StockTaking), typeof(StockQuantityHistory), typeof(StockQuantityHistoryExt)]);
|
||||||
Console.WriteLine(toon);
|
Console.WriteLine(toon);
|
||||||
Console.WriteLine("\n=== NAVIGATION METADATA ELLENŐRZÉS ===\n");
|
Console.WriteLine("\n=== NAVIGATION METADATA ELLENŐRZÉS ===\n");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
# Test debugger script for JsonExtensionTests
|
|
||||||
$projectPath = "H:\Applications\Mango\Source\FruitBankHybridApp"
|
|
||||||
Set-Location $projectPath
|
|
||||||
|
|
||||||
Write-Host "Building test project..."
|
|
||||||
dotnet build FruitBankHybrid.Shared.Tests/FruitBankHybrid.Shared.Tests.csproj -c Debug
|
|
||||||
|
|
||||||
Write-Host "`nRunning JsonExtensionTests..."
|
|
||||||
# Use --no-build to avoid the MSBuild conflict
|
|
||||||
dotnet test FruitBankHybrid.Shared.Tests/FruitBankHybrid.Shared.Tests.csproj `
|
|
||||||
--no-build `
|
|
||||||
-c Debug `
|
|
||||||
--filter "ClassName=FruitBankHybrid.Shared.Tests.JsonExtensionTests" `
|
|
||||||
2>&1 | Tee-Object -FilePath "test_results.txt"
|
|
||||||
|
|
||||||
Write-Host "`n=== Test Results ==="
|
|
||||||
Get-Content "test_results.txt" | Select-String -Pattern "FAILED|PASSED|Error|Assert" | tail -50
|
|
||||||
Loading…
Reference in New Issue