Add item tracking and warranty settings
This commit is contained in:
@@ -12,7 +12,13 @@ public record CreateItemRequest(
|
||||
Guid BaseUomId,
|
||||
decimal? SalePrice,
|
||||
List<UomConversionRequest>? Conversions,
|
||||
decimal? ReorderLevel = null);
|
||||
decimal? ReorderLevel = null,
|
||||
bool TracksSerialNumbers = false,
|
||||
bool TracksBatches = false,
|
||||
bool TracksExpiryDate = false,
|
||||
bool HasWarranty = false,
|
||||
int? WarrantyPeriodDays = null,
|
||||
bool AllowCustomWarrantyPeriod = false);
|
||||
|
||||
public record UpdateItemRequest(
|
||||
string Name,
|
||||
@@ -23,7 +29,13 @@ public record UpdateItemRequest(
|
||||
Guid BaseUomId,
|
||||
decimal? SalePrice,
|
||||
bool IsActive = true,
|
||||
decimal? ReorderLevel = null);
|
||||
decimal? ReorderLevel = null,
|
||||
bool TracksSerialNumbers = false,
|
||||
bool TracksBatches = false,
|
||||
bool TracksExpiryDate = false,
|
||||
bool HasWarranty = false,
|
||||
int? WarrantyPeriodDays = null,
|
||||
bool AllowCustomWarrantyPeriod = false);
|
||||
|
||||
public record ReplaceConversionsRequest(List<UomConversionRequest> Conversions);
|
||||
|
||||
@@ -43,6 +55,12 @@ public record ItemSummaryResponse(
|
||||
string BaseUomName,
|
||||
decimal? SalePrice,
|
||||
decimal? ReorderLevel,
|
||||
bool TracksSerialNumbers,
|
||||
bool TracksBatches,
|
||||
bool TracksExpiryDate,
|
||||
bool HasWarranty,
|
||||
int? WarrantyPeriodDays,
|
||||
bool AllowCustomWarrantyPeriod,
|
||||
Models.SyncSource SyncSource,
|
||||
bool IsActive,
|
||||
DateTime CreatedAt);
|
||||
@@ -62,6 +80,12 @@ public record ItemDetailResponse(
|
||||
string BaseUomName,
|
||||
decimal? SalePrice,
|
||||
decimal? ReorderLevel,
|
||||
bool TracksSerialNumbers,
|
||||
bool TracksBatches,
|
||||
bool TracksExpiryDate,
|
||||
bool HasWarranty,
|
||||
int? WarrantyPeriodDays,
|
||||
bool AllowCustomWarrantyPeriod,
|
||||
Models.SyncSource SyncSource,
|
||||
bool IsActive,
|
||||
DateTime CreatedAt,
|
||||
|
||||
@@ -2,7 +2,7 @@ using Distribution.Infra.UoW;
|
||||
|
||||
namespace Distribution.Features.Item;
|
||||
|
||||
public class ItemService(IItemRepository repo, IUnitOfWork uow)
|
||||
public class ItemService(IItemRepository repo, IUnitOfWork uow, SysConfig.SysConfigService sysConfig)
|
||||
{
|
||||
private static UomConversionResponse MapConversion(Models.UomConversion c) =>
|
||||
new(c.Id, c.FK_FromUomId, c.FromUom.Name, c.FK_ToUomId, c.ToUom.Name, c.Factor);
|
||||
@@ -13,7 +13,10 @@ public class ItemService(IItemRepository repo, IUnitOfWork uow)
|
||||
i.FK_SubCategoryId, i.SubCategory?.Name,
|
||||
i.FK_BrandId, i.Brand?.Name,
|
||||
i.FK_BaseUomId, i.BaseUom.Name,
|
||||
i.SalePrice, i.ReorderLevel, i.SyncSource, i.IsActive, i.CreatedAt);
|
||||
i.SalePrice, i.ReorderLevel,
|
||||
i.TracksSerialNumbers, i.TracksBatches, i.TracksExpiryDate,
|
||||
i.HasWarranty, i.WarrantyPeriodDays, i.AllowCustomWarrantyPeriod,
|
||||
i.SyncSource, i.IsActive, i.CreatedAt);
|
||||
|
||||
private static ItemDetailResponse MapDetail(Models.Item i) =>
|
||||
new(i.Id, i.Sku, i.Name, i.Description,
|
||||
@@ -21,9 +24,44 @@ public class ItemService(IItemRepository repo, IUnitOfWork uow)
|
||||
i.FK_SubCategoryId, i.SubCategory?.Name,
|
||||
i.FK_BrandId, i.Brand?.Name,
|
||||
i.FK_BaseUomId, i.BaseUom.Name,
|
||||
i.SalePrice, i.ReorderLevel, i.SyncSource, i.IsActive, i.CreatedAt,
|
||||
i.SalePrice, i.ReorderLevel,
|
||||
i.TracksSerialNumbers, i.TracksBatches, i.TracksExpiryDate,
|
||||
i.HasWarranty, i.WarrantyPeriodDays, i.AllowCustomWarrantyPeriod,
|
||||
i.SyncSource, i.IsActive, i.CreatedAt,
|
||||
i.Conversions.Select(MapConversion).ToList());
|
||||
|
||||
/// <summary>
|
||||
/// Rejects per-item tracking flags that are off system-wide, and warranty-period values that
|
||||
/// don't make sense given HasWarranty/AllowCustomWarrantyPeriod.
|
||||
/// </summary>
|
||||
private async Task ValidateTrackingFlagsAsync(bool tracksSerialNumbers, bool tracksBatches,
|
||||
bool tracksExpiryDate, bool hasWarranty, int? warrantyPeriodDays, bool allowCustomWarrantyPeriod)
|
||||
{
|
||||
if (tracksSerialNumbers && !await sysConfig.GetSerialNumberTrackingEnabledAsync())
|
||||
throw new InvalidOperationException("Serial number tracking is disabled system-wide.");
|
||||
|
||||
if (tracksBatches && !await sysConfig.GetBatchTrackingEnabledAsync())
|
||||
throw new InvalidOperationException("Batch tracking is disabled system-wide.");
|
||||
|
||||
if (tracksExpiryDate && !await sysConfig.GetExpiryDateTrackingEnabledAsync())
|
||||
throw new InvalidOperationException("Expiry date tracking is disabled system-wide.");
|
||||
|
||||
if (hasWarranty && !await sysConfig.GetWarrantyTrackingEnabledAsync())
|
||||
throw new InvalidOperationException("Warranty tracking is disabled system-wide.");
|
||||
|
||||
if (allowCustomWarrantyPeriod && !await sysConfig.GetCustomWarrantyOverrideEnabledAsync())
|
||||
throw new InvalidOperationException("Custom warranty period override is disabled system-wide.");
|
||||
|
||||
if (!hasWarranty && (warrantyPeriodDays is not null || allowCustomWarrantyPeriod))
|
||||
throw new InvalidOperationException("Warranty period/override can only be set when HasWarranty is true.");
|
||||
|
||||
if (warrantyPeriodDays is not null && !allowCustomWarrantyPeriod)
|
||||
throw new InvalidOperationException("WarrantyPeriodDays can only be set when AllowCustomWarrantyPeriod is true.");
|
||||
|
||||
if (warrantyPeriodDays is < 0)
|
||||
throw new InvalidOperationException("WarrantyPeriodDays cannot be negative.");
|
||||
}
|
||||
|
||||
public async Task<List<ItemSummaryResponse>> GetAllAsync(Guid? categoryId = null, Guid? subCategoryId = null, Guid? brandId = null) =>
|
||||
(await repo.GetAllAsync(categoryId, subCategoryId, brandId))
|
||||
.Select(MapSummary)
|
||||
@@ -41,6 +79,9 @@ public class ItemService(IItemRepository repo, IUnitOfWork uow)
|
||||
if (await repo.SkuExistsAsync(request.Sku))
|
||||
throw new InvalidOperationException($"SKU '{request.Sku}' already exists.");
|
||||
|
||||
await ValidateTrackingFlagsAsync(request.TracksSerialNumbers, request.TracksBatches,
|
||||
request.TracksExpiryDate, request.HasWarranty, request.WarrantyPeriodDays, request.AllowCustomWarrantyPeriod);
|
||||
|
||||
var item = new Models.Item
|
||||
{
|
||||
Sku = request.Sku,
|
||||
@@ -52,6 +93,12 @@ public class ItemService(IItemRepository repo, IUnitOfWork uow)
|
||||
FK_BaseUomId = request.BaseUomId,
|
||||
SalePrice = request.SalePrice,
|
||||
ReorderLevel = request.ReorderLevel,
|
||||
TracksSerialNumbers = request.TracksSerialNumbers,
|
||||
TracksBatches = request.TracksBatches,
|
||||
TracksExpiryDate = request.TracksExpiryDate,
|
||||
HasWarranty = request.HasWarranty,
|
||||
WarrantyPeriodDays = request.WarrantyPeriodDays,
|
||||
AllowCustomWarrantyPeriod = request.AllowCustomWarrantyPeriod,
|
||||
SyncSource = Models.SyncSource.Manual
|
||||
};
|
||||
|
||||
@@ -78,6 +125,9 @@ public class ItemService(IItemRepository repo, IUnitOfWork uow)
|
||||
if (item is null) return null;
|
||||
if (item.SyncSource == Models.SyncSource.Erp) return null;
|
||||
|
||||
await ValidateTrackingFlagsAsync(request.TracksSerialNumbers, request.TracksBatches,
|
||||
request.TracksExpiryDate, request.HasWarranty, request.WarrantyPeriodDays, request.AllowCustomWarrantyPeriod);
|
||||
|
||||
item.Name = request.Name;
|
||||
item.Description = request.Description;
|
||||
item.FK_CategoryId = request.CategoryId;
|
||||
@@ -86,6 +136,12 @@ public class ItemService(IItemRepository repo, IUnitOfWork uow)
|
||||
item.FK_BaseUomId = request.BaseUomId;
|
||||
item.SalePrice = request.SalePrice;
|
||||
item.ReorderLevel = request.ReorderLevel;
|
||||
item.TracksSerialNumbers = request.TracksSerialNumbers;
|
||||
item.TracksBatches = request.TracksBatches;
|
||||
item.TracksExpiryDate = request.TracksExpiryDate;
|
||||
item.HasWarranty = request.HasWarranty;
|
||||
item.WarrantyPeriodDays = request.WarrantyPeriodDays;
|
||||
item.AllowCustomWarrantyPeriod = request.AllowCustomWarrantyPeriod;
|
||||
item.IsActive = request.IsActive;
|
||||
|
||||
await uow.BeginAsync(ct);
|
||||
|
||||
Reference in New Issue
Block a user