Refactor code structure for int in alll ids instesd defult using long

This commit is contained in:
2026-07-15 15:35:54 +05:30
parent 6c7f53350f
commit ed2ee87c68
120 changed files with 2775 additions and 12494 deletions
@@ -20,7 +20,7 @@ public sealed class AuditLogsController : ApiControllerBase
[HttpGet] [HttpGet]
[ProducesResponseType(typeof(PagedResponse<AuditLogDto>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PagedResponse<AuditLogDto>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedResponse<AuditLogDto>>> List( public async Task<ActionResult<PagedResponse<AuditLogDto>>> List(
[FromQuery] string? entityType, [FromQuery] long? entityId, [FromQuery] long? userId, [FromQuery] string? entityType, [FromQuery] int? entityId, [FromQuery] int? userId,
[FromQuery] DateOnly? from, [FromQuery] DateOnly? to, [FromQuery] PageQuery query, CancellationToken ct) [FromQuery] DateOnly? from, [FromQuery] DateOnly? to, [FromQuery] PageQuery query, CancellationToken ct)
=> Ok(await _audit.ListLogsAsync(entityType, entityId, userId, from, to, query, ct)); => Ok(await _audit.ListLogsAsync(entityType, entityId, userId, from, to, query, ct));
} }
@@ -12,10 +12,10 @@ public sealed class GrnsController : ApiControllerBase
public GrnsController(IGrnService grns) => _grns = grns; public GrnsController(IGrnService grns) => _grns = grns;
[HttpGet("{grnId:long}")] [HttpGet("{grnId:int}")]
[ProducesResponseType(typeof(GrnDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(GrnDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<GrnDto>> GetById(long grnId, CancellationToken ct) public async Task<ActionResult<GrnDto>> GetById(int grnId, CancellationToken ct)
{ {
var dto = await _grns.GetAsync(grnId, ct); var dto = await _grns.GetAsync(grnId, ct);
return dto is null ? NotFound() : Ok(dto); return dto is null ? NotFound() : Ok(dto);
@@ -33,20 +33,20 @@ public sealed class GrnsController : ApiControllerBase
} }
/// <summary>Confirm: create FIFO layers + inbound ledger + update PO receipts (single UoW txn).</summary> /// <summary>Confirm: create FIFO layers + inbound ledger + update PO receipts (single UoW txn).</summary>
[HttpPost("{grnId:long}/confirm")] [HttpPost("{grnId:int}/confirm")]
[ProducesResponseType(typeof(GrnConfirmResultDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(GrnConfirmResultDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<GrnConfirmResultDto>> Confirm( public async Task<ActionResult<GrnConfirmResultDto>> Confirm(
long grnId, [FromHeader(Name = "Idempotency-Key")] string? idempotencyKey, CancellationToken ct) int grnId, [FromHeader(Name = "Idempotency-Key")] string? idempotencyKey, CancellationToken ct)
=> Ok(await _grns.ConfirmAsync(grnId, idempotencyKey, ct)); => Ok(await _grns.ConfirmAsync(grnId, idempotencyKey, ct));
/// <summary>Release or reject an inspection-hold line (FR-GRN-05).</summary> /// <summary>Release or reject an inspection-hold line (FR-GRN-05).</summary>
[HttpPost("{grnId:long}/lines/{grnLineId:long}/release")] [HttpPost("{grnId:int}/lines/{grnLineId:int}/release")]
[ProducesResponseType(typeof(ReleaseLineResultDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ReleaseLineResultDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<ReleaseLineResultDto>> Release( public async Task<ActionResult<ReleaseLineResultDto>> Release(
long grnId, long grnLineId, [FromBody] ReleaseLineRequest request, CancellationToken ct) int grnId, int grnLineId, [FromBody] ReleaseLineRequest request, CancellationToken ct)
=> Ok(await _grns.ReleaseLineAsync(grnId, grnLineId, request.Action, ct)); => Ok(await _grns.ReleaseLineAsync(grnId, grnLineId, request.Action, ct));
} }
+11 -11
View File
@@ -20,16 +20,16 @@ public sealed class ItemsController : ApiControllerBase
public async Task<ActionResult<PagedResponse<ItemListItemDto>>> List( public async Task<ActionResult<PagedResponse<ItemListItemDto>>> List(
[FromQuery] PageQuery query, [FromQuery] PageQuery query,
[FromQuery] EntityStatus? status, [FromQuery] EntityStatus? status,
[FromQuery] long? categoryId, [FromQuery] int? categoryId,
[FromQuery] TrackingMode? trackingMode, [FromQuery] TrackingMode? trackingMode,
CancellationToken ct) CancellationToken ct)
=> Ok(await _items.ListAsync(query, status, categoryId, trackingMode, ct)); => Ok(await _items.ListAsync(query, status, categoryId, trackingMode, ct));
/// <summary>Get a single item; returns an <c>ETag</c> for optimistic concurrency.</summary> /// <summary>Get a single item; returns an <c>ETag</c> for optimistic concurrency.</summary>
[HttpGet("{itemId:long}")] [HttpGet("{itemId:int}")]
[ProducesResponseType(typeof(ItemDetailDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ItemDetailDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<ItemDetailDto>> GetById(long itemId, CancellationToken ct) public async Task<ActionResult<ItemDetailDto>> GetById(int itemId, CancellationToken ct)
{ {
var result = await _items.GetAsync(itemId, ct); var result = await _items.GetAsync(itemId, ct);
if (result is null) return NotFound(); if (result is null) return NotFound();
@@ -51,11 +51,11 @@ public sealed class ItemsController : ApiControllerBase
} }
/// <summary>Full update; requires <c>If-Match</c> (412 on stale ETag).</summary> /// <summary>Full update; requires <c>If-Match</c> (412 on stale ETag).</summary>
[HttpPut("{itemId:long}")] [HttpPut("{itemId:int}")]
[ProducesResponseType(typeof(ItemDetailDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ItemDetailDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status412PreconditionFailed)] [ProducesResponseType(StatusCodes.Status412PreconditionFailed)]
public async Task<ActionResult<ItemDetailDto>> Update(long itemId, [FromBody] UpdateItemRequest request, CancellationToken ct) public async Task<ActionResult<ItemDetailDto>> Update(int itemId, [FromBody] UpdateItemRequest request, CancellationToken ct)
{ {
var expected = RequireIfMatch(); var expected = RequireIfMatch();
var result = await _items.UpdateAsync(itemId, request, expected, ct); var result = await _items.UpdateAsync(itemId, request, expected, ct);
@@ -64,26 +64,26 @@ public sealed class ItemsController : ApiControllerBase
} }
/// <summary>Activate / deactivate the item (FR-MD-08 — deactivate, not delete).</summary> /// <summary>Activate / deactivate the item (FR-MD-08 — deactivate, not delete).</summary>
[HttpPatch("{itemId:long}/status")] [HttpPatch("{itemId:int}/status")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> SetStatus(long itemId, [FromBody] UpdateItemStatusRequest request, CancellationToken ct) public async Task<IActionResult> SetStatus(int itemId, [FromBody] UpdateItemStatusRequest request, CancellationToken ct)
{ {
await _items.SetStatusAsync(itemId, request.Status, ct); await _items.SetStatusAsync(itemId, request.Status, ct);
return NoContent(); return NoContent();
} }
/// <summary>Replace the item's per-warehouse reorder settings (FR-MD-05).</summary> /// <summary>Replace the item's per-warehouse reorder settings (FR-MD-05).</summary>
[HttpPut("{itemId:long}/reorder")] [HttpPut("{itemId:int}/reorder")]
[ProducesResponseType(typeof(ItemReorderSettingsDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ItemReorderSettingsDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<ItemReorderSettingsDto>> UpdateReorder(long itemId, [FromBody] UpdateReorderRequest request, CancellationToken ct) public async Task<ActionResult<ItemReorderSettingsDto>> UpdateReorder(int itemId, [FromBody] UpdateReorderRequest request, CancellationToken ct)
=> Ok(await _items.UpdateReorderAsync(itemId, request, ct)); => Ok(await _items.UpdateReorderAsync(itemId, request, ct));
/// <summary>Replace the item's UOM conversions (FR-MD-02).</summary> /// <summary>Replace the item's UOM conversions (FR-MD-02).</summary>
[HttpPut("{itemId:long}/uom-conversions")] [HttpPut("{itemId:int}/uom-conversions")]
[ProducesResponseType(typeof(ItemUomConversionsDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ItemUomConversionsDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<ItemUomConversionsDto>> UpdateUomConversions(long itemId, [FromBody] UpdateUomConversionsRequest request, CancellationToken ct) public async Task<ActionResult<ItemUomConversionsDto>> UpdateUomConversions(int itemId, [FromBody] UpdateUomConversionsRequest request, CancellationToken ct)
=> Ok(await _items.UpdateUomConversionsAsync(itemId, request, ct)); => Ok(await _items.UpdateUomConversionsAsync(itemId, request, ct));
} }
@@ -19,6 +19,6 @@ public sealed class JournalEntriesController : ApiControllerBase
[HttpGet] [HttpGet]
[ProducesResponseType(typeof(PagedResponse<JournalEntryStubDto>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PagedResponse<JournalEntryStubDto>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedResponse<JournalEntryStubDto>>> List( public async Task<ActionResult<PagedResponse<JournalEntryStubDto>>> List(
[FromQuery] string? sourceDocType, [FromQuery] long? sourceDocId, [FromQuery] PageQuery query, CancellationToken ct) [FromQuery] string? sourceDocType, [FromQuery] int? sourceDocId, [FromQuery] PageQuery query, CancellationToken ct)
=> Ok(await _audit.ListJournalAsync(sourceDocType, sourceDocId, query, ct)); => Ok(await _audit.ListJournalAsync(sourceDocType, sourceDocId, query, ct));
} }
@@ -17,13 +17,13 @@ public sealed class PurchaseOrdersController : ApiControllerBase
[HttpGet] [HttpGet]
[ProducesResponseType(typeof(PagedResponse<PurchaseOrderSummaryDto>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PagedResponse<PurchaseOrderSummaryDto>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedResponse<PurchaseOrderSummaryDto>>> List( public async Task<ActionResult<PagedResponse<PurchaseOrderSummaryDto>>> List(
[FromQuery] PageQuery query, [FromQuery] PurchaseOrderStatus? status, [FromQuery] long? vendorId, CancellationToken ct) [FromQuery] PageQuery query, [FromQuery] PurchaseOrderStatus? status, [FromQuery] int? vendorId, CancellationToken ct)
=> Ok(await _pos.ListAsync(query, status, vendorId, ct)); => Ok(await _pos.ListAsync(query, status, vendorId, ct));
[HttpGet("{poId:long}")] [HttpGet("{poId:int}")]
[ProducesResponseType(typeof(PurchaseOrderDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PurchaseOrderDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<PurchaseOrderDto>> GetById(long poId, CancellationToken ct) public async Task<ActionResult<PurchaseOrderDto>> GetById(int poId, CancellationToken ct)
{ {
var result = await _pos.GetAsync(poId, ct); var result = await _pos.GetAsync(poId, ct);
if (result is null) return NotFound(); if (result is null) return NotFound();
@@ -44,12 +44,12 @@ public sealed class PurchaseOrdersController : ApiControllerBase
} }
/// <summary>Edit while open (FR-PROC-05); requires <c>If-Match</c>. 409 PO_NOT_EDITABLE if closed.</summary> /// <summary>Edit while open (FR-PROC-05); requires <c>If-Match</c>. 409 PO_NOT_EDITABLE if closed.</summary>
[HttpPut("{poId:long}")] [HttpPut("{poId:int}")]
[ProducesResponseType(typeof(PurchaseOrderDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PurchaseOrderDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
[ProducesResponseType(StatusCodes.Status412PreconditionFailed)] [ProducesResponseType(StatusCodes.Status412PreconditionFailed)]
public async Task<ActionResult<PurchaseOrderDto>> Update(long poId, [FromBody] UpdatePurchaseOrderRequest request, CancellationToken ct) public async Task<ActionResult<PurchaseOrderDto>> Update(int poId, [FromBody] UpdatePurchaseOrderRequest request, CancellationToken ct)
{ {
var expected = RequireIfMatch(); var expected = RequireIfMatch();
var result = await _pos.UpdateAsync(poId, request, expected, ct); var result = await _pos.UpdateAsync(poId, request, expected, ct);
@@ -58,17 +58,17 @@ public sealed class PurchaseOrdersController : ApiControllerBase
} }
/// <summary>Approve — no-op in Phase 1 (POs auto-approve); transitions PendingApproval→Approved when enabled.</summary> /// <summary>Approve — no-op in Phase 1 (POs auto-approve); transitions PendingApproval→Approved when enabled.</summary>
[HttpPost("{poId:long}/approve")] [HttpPost("{poId:int}/approve")]
[ProducesResponseType(typeof(PurchaseOrderDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PurchaseOrderDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<PurchaseOrderDto>> Approve(long poId, CancellationToken ct) public async Task<ActionResult<PurchaseOrderDto>> Approve(int poId, CancellationToken ct)
=> Ok(await _pos.ApproveAsync(poId, ct)); => Ok(await _pos.ApproveAsync(poId, ct));
/// <summary>Cancel — 409 if any goods have been received against the PO.</summary> /// <summary>Cancel — 409 if any goods have been received against the PO.</summary>
[HttpPost("{poId:long}/cancel")] [HttpPost("{poId:int}/cancel")]
[ProducesResponseType(typeof(PurchaseOrderDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PurchaseOrderDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<PurchaseOrderDto>> Cancel(long poId, [FromBody] CancelPurchaseOrderRequest request, CancellationToken ct) public async Task<ActionResult<PurchaseOrderDto>> Cancel(int poId, [FromBody] CancelPurchaseOrderRequest request, CancellationToken ct)
=> Ok(await _pos.CancelAsync(poId, request.Reason, ct)); => Ok(await _pos.CancelAsync(poId, request.Reason, ct));
} }
@@ -18,10 +18,10 @@ public sealed class RequisitionsController : ApiControllerBase
public async Task<ActionResult<PagedResponse<RequisitionSummaryDto>>> List([FromQuery] PageQuery query, CancellationToken ct) public async Task<ActionResult<PagedResponse<RequisitionSummaryDto>>> List([FromQuery] PageQuery query, CancellationToken ct)
=> Ok(await _requisitions.ListAsync(query, ct)); => Ok(await _requisitions.ListAsync(query, ct));
[HttpGet("{requisitionId:long}")] [HttpGet("{requisitionId:int}")]
[ProducesResponseType(typeof(RequisitionDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(RequisitionDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<RequisitionDto>> GetById(long requisitionId, CancellationToken ct) public async Task<ActionResult<RequisitionDto>> GetById(int requisitionId, CancellationToken ct)
{ {
var dto = await _requisitions.GetAsync(requisitionId, ct); var dto = await _requisitions.GetAsync(requisitionId, ct);
return dto is null ? NotFound() : Ok(dto); return dto is null ? NotFound() : Ok(dto);
@@ -36,9 +36,9 @@ public sealed class RequisitionsController : ApiControllerBase
return Created($"/api/v1/requisitions/{dto.RequisitionId}", dto); return Created($"/api/v1/requisitions/{dto.RequisitionId}", dto);
} }
[HttpPost("{requisitionId:long}/submit")] [HttpPost("{requisitionId:int}/submit")]
[ProducesResponseType(typeof(RequisitionDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(RequisitionDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<RequisitionDto>> Submit(long requisitionId, CancellationToken ct) public async Task<ActionResult<RequisitionDto>> Submit(int requisitionId, CancellationToken ct)
=> Ok(await _requisitions.SubmitAsync(requisitionId, ct)); => Ok(await _requisitions.SubmitAsync(requisitionId, ct));
} }
@@ -12,10 +12,10 @@ public sealed class RfqsController : ApiControllerBase
public RfqsController(IRfqService rfqs) => _rfqs = rfqs; public RfqsController(IRfqService rfqs) => _rfqs = rfqs;
[HttpGet("{rfqId:long}")] [HttpGet("{rfqId:int}")]
[ProducesResponseType(typeof(RfqDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(RfqDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<RfqDto>> GetById(long rfqId, CancellationToken ct) public async Task<ActionResult<RfqDto>> GetById(int rfqId, CancellationToken ct)
{ {
var dto = await _rfqs.GetAsync(rfqId, ct); var dto = await _rfqs.GetAsync(rfqId, ct);
return dto is null ? NotFound() : Ok(dto); return dto is null ? NotFound() : Ok(dto);
@@ -30,20 +30,20 @@ public sealed class RfqsController : ApiControllerBase
return Created($"/api/v1/rfqs/{dto.RfqId}", dto); return Created($"/api/v1/rfqs/{dto.RfqId}", dto);
} }
[HttpPost("{rfqId:long}/quotations")] [HttpPost("{rfqId:int}/quotations")]
[ProducesResponseType(typeof(VendorQuotationDto), StatusCodes.Status201Created)] [ProducesResponseType(typeof(VendorQuotationDto), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
[ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
public async Task<ActionResult<VendorQuotationDto>> AddQuotation(long rfqId, [FromBody] CreateQuotationRequest request, CancellationToken ct) public async Task<ActionResult<VendorQuotationDto>> AddQuotation(int rfqId, [FromBody] CreateQuotationRequest request, CancellationToken ct)
{ {
var dto = await _rfqs.AddQuotationAsync(rfqId, request, ct); var dto = await _rfqs.AddQuotationAsync(rfqId, request, ct);
return Created($"/api/v1/rfqs/{rfqId}/quotations/{dto.QuotationId}", dto); return Created($"/api/v1/rfqs/{rfqId}/quotations/{dto.QuotationId}", dto);
} }
[HttpGet("{rfqId:long}/comparison")] [HttpGet("{rfqId:int}/comparison")]
[ProducesResponseType(typeof(RfqComparisonDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(RfqComparisonDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<RfqComparisonDto>> Comparison(long rfqId, CancellationToken ct) public async Task<ActionResult<RfqComparisonDto>> Comparison(int rfqId, CancellationToken ct)
=> Ok(await _rfqs.GetComparisonAsync(rfqId, ct)); => Ok(await _rfqs.GetComparisonAsync(rfqId, ct));
} }
@@ -21,34 +21,34 @@ public sealed class StockController : ApiControllerBase
[HttpGet("on-hand")] [HttpGet("on-hand")]
[ProducesResponseType(typeof(StockOnHandDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(StockOnHandDto), StatusCodes.Status200OK)]
public async Task<ActionResult<StockOnHandDto>> OnHand([FromQuery] long itemId, [FromQuery] long warehouseId, CancellationToken ct) public async Task<ActionResult<StockOnHandDto>> OnHand([FromQuery] int itemId, [FromQuery] int warehouseId, CancellationToken ct)
=> Ok(await _stock.GetOnHandAsync(itemId, warehouseId, ct)); => Ok(await _stock.GetOnHandAsync(itemId, warehouseId, ct));
[HttpGet("ledger")] [HttpGet("ledger")]
[ProducesResponseType(typeof(PagedResponse<StockLedgerRowDto>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PagedResponse<StockLedgerRowDto>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedResponse<StockLedgerRowDto>>> Ledger( public async Task<ActionResult<PagedResponse<StockLedgerRowDto>>> Ledger(
[FromQuery] long? itemId, [FromQuery] long? warehouseId, [FromQuery] int? itemId, [FromQuery] int? warehouseId,
[FromQuery] DateOnly? from, [FromQuery] DateOnly? to, [FromQuery] PageQuery query, CancellationToken ct) [FromQuery] DateOnly? from, [FromQuery] DateOnly? to, [FromQuery] PageQuery query, CancellationToken ct)
=> Ok(await _stock.GetLedgerAsync(itemId, warehouseId, from, to, query, ct)); => Ok(await _stock.GetLedgerAsync(itemId, warehouseId, from, to, query, ct));
[HttpGet("valuation")] [HttpGet("valuation")]
[ProducesResponseType(typeof(StockValuationDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(StockValuationDto), StatusCodes.Status200OK)]
public async Task<ActionResult<StockValuationDto>> Valuation([FromQuery] long itemId, [FromQuery] long warehouseId, CancellationToken ct) public async Task<ActionResult<StockValuationDto>> Valuation([FromQuery] int itemId, [FromQuery] int warehouseId, CancellationToken ct)
=> Ok(await _stock.GetValuationAsync(itemId, warehouseId, ct)); => Ok(await _stock.GetValuationAsync(itemId, warehouseId, ct));
/// <summary>Items at/below their reorder point (FR-STK-10), computed on read.</summary> /// <summary>Items at/below their reorder point (FR-STK-10), computed on read.</summary>
[HttpGet("reorder-alerts")] [HttpGet("reorder-alerts")]
[ProducesResponseType(typeof(PagedResponse<ReorderAlertDto>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(PagedResponse<ReorderAlertDto>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedResponse<ReorderAlertDto>>> ReorderAlerts( public async Task<ActionResult<PagedResponse<ReorderAlertDto>>> ReorderAlerts(
[FromQuery] long? warehouseId, [FromQuery] PageQuery query, CancellationToken ct) [FromQuery] int? warehouseId, [FromQuery] PageQuery query, CancellationToken ct)
=> Ok(await _reorder.GetAlertsAsync(warehouseId, query, ct)); => Ok(await _reorder.GetAlertsAsync(warehouseId, query, ct));
/// <summary>Create a draft requisition for an item's suggested reorder quantity.</summary> /// <summary>Create a draft requisition for an item's suggested reorder quantity.</summary>
[HttpPost("reorder-alerts/{itemId:long}/requisition")] [HttpPost("reorder-alerts/{itemId:int}/requisition")]
[ProducesResponseType(typeof(RequisitionDto), StatusCodes.Status201Created)] [ProducesResponseType(typeof(RequisitionDto), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
public async Task<ActionResult<RequisitionDto>> SuggestRequisition( public async Task<ActionResult<RequisitionDto>> SuggestRequisition(
long itemId, [FromQuery] long warehouseId, CancellationToken ct) int itemId, [FromQuery] int warehouseId, CancellationToken ct)
{ {
var dto = await _reorder.CreateSuggestedRequisitionAsync(itemId, warehouseId, ct); var dto = await _reorder.CreateSuggestedRequisitionAsync(itemId, warehouseId, ct);
return Created($"/api/v1/requisitions/{dto.RequisitionId}", dto); return Created($"/api/v1/requisitions/{dto.RequisitionId}", dto);
@@ -12,10 +12,10 @@ public sealed class StockCountsController : ApiControllerBase
public StockCountsController(ICountService counts) => _counts = counts; public StockCountsController(ICountService counts) => _counts = counts;
[HttpGet("{countId:long}")] [HttpGet("{countId:int}")]
[ProducesResponseType(typeof(CountDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(CountDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<CountDto>> GetById(long countId, CancellationToken ct) public async Task<ActionResult<CountDto>> GetById(int countId, CancellationToken ct)
{ {
var dto = await _counts.GetAsync(countId, ct); var dto = await _counts.GetAsync(countId, ct);
return dto is null ? NotFound() : Ok(dto); return dto is null ? NotFound() : Ok(dto);
@@ -32,18 +32,18 @@ public sealed class StockCountsController : ApiControllerBase
} }
/// <summary>Enter counted quantities; variance = counted system.</summary> /// <summary>Enter counted quantities; variance = counted system.</summary>
[HttpPut("{countId:long}/counts")] [HttpPut("{countId:int}/counts")]
[ProducesResponseType(typeof(CountDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(CountDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<CountDto>> EnterCounts(long countId, [FromBody] EnterCountsRequest request, CancellationToken ct) public async Task<ActionResult<CountDto>> EnterCounts(int countId, [FromBody] EnterCountsRequest request, CancellationToken ct)
=> Ok(await _counts.EnterCountsAsync(countId, request, ct)); => Ok(await _counts.EnterCountsAsync(countId, request, ct));
/// <summary>Post: emit a variance adjustment and close the count.</summary> /// <summary>Post: emit a variance adjustment and close the count.</summary>
[HttpPost("{countId:long}/post")] [HttpPost("{countId:int}/post")]
[ProducesResponseType(typeof(CountPostResultDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(CountPostResultDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<CountPostResultDto>> Post(long countId, CancellationToken ct) public async Task<ActionResult<CountPostResultDto>> Post(int countId, CancellationToken ct)
=> Ok(await _counts.PostAsync(countId, ct)); => Ok(await _counts.PostAsync(countId, ct));
} }
@@ -12,10 +12,10 @@ public sealed class StockTransfersController : ApiControllerBase
public StockTransfersController(ITransferService transfers) => _transfers = transfers; public StockTransfersController(ITransferService transfers) => _transfers = transfers;
[HttpGet("{transferId:long}")] [HttpGet("{transferId:int}")]
[ProducesResponseType(typeof(TransferDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(TransferDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<TransferDto>> GetById(long transferId, CancellationToken ct) public async Task<ActionResult<TransferDto>> GetById(int transferId, CancellationToken ct)
{ {
var dto = await _transfers.GetAsync(transferId, ct); var dto = await _transfers.GetAsync(transferId, ct);
return dto is null ? NotFound() : Ok(dto); return dto is null ? NotFound() : Ok(dto);
@@ -31,19 +31,19 @@ public sealed class StockTransfersController : ApiControllerBase
} }
/// <summary>Dispatch: consume source FIFO layers into in-transit. 409 STOCK_NEGATIVE_BLOCKED if short.</summary> /// <summary>Dispatch: consume source FIFO layers into in-transit. 409 STOCK_NEGATIVE_BLOCKED if short.</summary>
[HttpPost("{transferId:long}/dispatch")] [HttpPost("{transferId:int}/dispatch")]
[ProducesResponseType(typeof(DispatchResultDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(DispatchResultDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<DispatchResultDto>> Dispatch(long transferId, CancellationToken ct) public async Task<ActionResult<DispatchResultDto>> Dispatch(int transferId, CancellationToken ct)
=> Ok(await _transfers.DispatchAsync(transferId, ct)); => Ok(await _transfers.DispatchAsync(transferId, ct));
/// <summary>Receive: create the destination layer at the inherited cost (cost-preserving).</summary> /// <summary>Receive: create the destination layer at the inherited cost (cost-preserving).</summary>
[HttpPost("{transferId:long}/receive")] [HttpPost("{transferId:int}/receive")]
[ProducesResponseType(typeof(ReceiveResultDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ReceiveResultDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
[ProducesResponseType(StatusCodes.Status422UnprocessableEntity)] [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
public async Task<ActionResult<ReceiveResultDto>> Receive(long transferId, [FromBody] ReceiveTransferRequest request, CancellationToken ct) public async Task<ActionResult<ReceiveResultDto>> Receive(int transferId, [FromBody] ReceiveTransferRequest request, CancellationToken ct)
=> Ok(await _transfers.ReceiveAsync(transferId, request, ct)); => Ok(await _transfers.ReceiveAsync(transferId, request, ct));
} }
@@ -20,10 +20,10 @@ public sealed class VendorsController : ApiControllerBase
[FromQuery] PageQuery query, [FromQuery] EntityStatus? status, CancellationToken ct) [FromQuery] PageQuery query, [FromQuery] EntityStatus? status, CancellationToken ct)
=> Ok(await _vendors.ListAsync(query, status, ct)); => Ok(await _vendors.ListAsync(query, status, ct));
[HttpGet("{vendorId:long}")] [HttpGet("{vendorId:int}")]
[ProducesResponseType(typeof(VendorDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(VendorDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<VendorDto>> GetById(long vendorId, CancellationToken ct) public async Task<ActionResult<VendorDto>> GetById(int vendorId, CancellationToken ct)
{ {
var result = await _vendors.GetAsync(vendorId, ct); var result = await _vendors.GetAsync(vendorId, ct);
if (result is null) return NotFound(); if (result is null) return NotFound();
@@ -42,11 +42,11 @@ public sealed class VendorsController : ApiControllerBase
return Created($"/api/v1/vendors/{result.Value.VendorId}", result.Value); return Created($"/api/v1/vendors/{result.Value.VendorId}", result.Value);
} }
[HttpPut("{vendorId:long}")] [HttpPut("{vendorId:int}")]
[ProducesResponseType(typeof(VendorDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(VendorDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status412PreconditionFailed)] [ProducesResponseType(StatusCodes.Status412PreconditionFailed)]
public async Task<ActionResult<VendorDto>> Update(long vendorId, [FromBody] UpdateVendorRequest request, CancellationToken ct) public async Task<ActionResult<VendorDto>> Update(int vendorId, [FromBody] UpdateVendorRequest request, CancellationToken ct)
{ {
var expected = RequireIfMatch(); var expected = RequireIfMatch();
var result = await _vendors.UpdateAsync(vendorId, request, expected, ct); var result = await _vendors.UpdateAsync(vendorId, request, expected, ct);
@@ -54,10 +54,10 @@ public sealed class VendorsController : ApiControllerBase
return Ok(result.Value); return Ok(result.Value);
} }
[HttpPatch("{vendorId:long}/status")] [HttpPatch("{vendorId:int}/status")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> SetStatus(long vendorId, [FromBody] UpdateVendorStatusRequest request, CancellationToken ct) public async Task<IActionResult> SetStatus(int vendorId, [FromBody] UpdateVendorStatusRequest request, CancellationToken ct)
{ {
await _vendors.SetStatusAsync(vendorId, request.Status, ct); await _vendors.SetStatusAsync(vendorId, request.Status, ct);
return NoContent(); return NoContent();
@@ -18,10 +18,10 @@ public sealed class WarehousesController : ApiControllerBase
public async Task<ActionResult<PagedResponse<WarehouseDto>>> List([FromQuery] PageQuery query, CancellationToken ct) public async Task<ActionResult<PagedResponse<WarehouseDto>>> List([FromQuery] PageQuery query, CancellationToken ct)
=> Ok(await _warehouses.ListAsync(query, ct)); => Ok(await _warehouses.ListAsync(query, ct));
[HttpGet("{warehouseId:long}")] [HttpGet("{warehouseId:int}")]
[ProducesResponseType(typeof(WarehouseDto), StatusCodes.Status200OK)] [ProducesResponseType(typeof(WarehouseDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<WarehouseDto>> GetById(long warehouseId, CancellationToken ct) public async Task<ActionResult<WarehouseDto>> GetById(int warehouseId, CancellationToken ct)
{ {
var dto = await _warehouses.GetAsync(warehouseId, ct); var dto = await _warehouses.GetAsync(warehouseId, ct);
return dto is null ? NotFound() : Ok(dto); return dto is null ? NotFound() : Ok(dto);
@@ -36,17 +36,17 @@ public sealed class WarehousesController : ApiControllerBase
return Created($"/api/v1/warehouses/{dto.WarehouseId}", dto); return Created($"/api/v1/warehouses/{dto.WarehouseId}", dto);
} }
[HttpGet("{warehouseId:long}/bins")] [HttpGet("{warehouseId:int}/bins")]
[ProducesResponseType(typeof(IReadOnlyList<BinDto>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(IReadOnlyList<BinDto>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<IReadOnlyList<BinDto>>> ListBins(long warehouseId, CancellationToken ct) public async Task<ActionResult<IReadOnlyList<BinDto>>> ListBins(int warehouseId, CancellationToken ct)
=> Ok(await _warehouses.ListBinsAsync(warehouseId, ct)); => Ok(await _warehouses.ListBinsAsync(warehouseId, ct));
[HttpPost("{warehouseId:long}/bins")] [HttpPost("{warehouseId:int}/bins")]
[ProducesResponseType(typeof(BinDto), StatusCodes.Status201Created)] [ProducesResponseType(typeof(BinDto), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<BinDto>> CreateBin(long warehouseId, [FromBody] CreateBinRequest request, CancellationToken ct) public async Task<ActionResult<BinDto>> CreateBin(int warehouseId, [FromBody] CreateBinRequest request, CancellationToken ct)
{ {
var dto = await _warehouses.CreateBinAsync(warehouseId, request, ct); var dto = await _warehouses.CreateBinAsync(warehouseId, request, ct);
return Created($"/api/v1/warehouses/{warehouseId}/bins/{dto.BinId}", dto); return Created($"/api/v1/warehouses/{warehouseId}/bins/{dto.BinId}", dto);
+3 -3
View File
@@ -12,10 +12,10 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class AuditLog public class AuditLog
{ {
public long AuditId { get; set; } public int AuditId { get; set; }
public long UserId { get; set; } public int UserId { get; set; }
public string EntityType { get; set; } = string.Empty; public string EntityType { get; set; } = string.Empty;
public long EntityId { get; set; } public int EntityId { get; set; }
public AuditAction Action { get; set; } public AuditAction Action { get; set; }
/// <summary>JSON change set: field→value (create/delete) or field→{old,new} (update).</summary> /// <summary>JSON change set: field→value (create/delete) or field→{old,new} (update).</summary>
public string ChangeSet { get; set; } = "{}"; public string ChangeSet { get; set; } = "{}";
+2 -2
View File
@@ -6,9 +6,9 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Batch public class Batch
{ {
public long BatchId { get; set; } public int BatchId { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public string BatchNo { get; set; } = string.Empty; public string BatchNo { get; set; } = string.Empty;
+2 -2
View File
@@ -6,9 +6,9 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Bin public class Bin
{ {
public long BinId { get; set; } public int BinId { get; set; }
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public Warehouse? Warehouse { get; set; } public Warehouse? Warehouse { get; set; }
public string Code { get; set; } = string.Empty; public string Code { get; set; } = string.Empty;
+2 -2
View File
@@ -6,10 +6,10 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Category public class Category
{ {
public long CategoryId { get; set; } public int CategoryId { get; set; }
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
public long? ParentId { get; set; } public int? ParentId { get; set; }
public Category? Parent { get; set; } public Category? Parent { get; set; }
public ICollection<Category> Children { get; set; } = new List<Category>(); public ICollection<Category> Children { get; set; } = new List<Category>();
} }
+5 -5
View File
@@ -10,21 +10,21 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Grn public class Grn
{ {
public long GrnId { get; set; } public int GrnId { get; set; }
public string DocNo { get; set; } = string.Empty; public string DocNo { get; set; } = string.Empty;
public long? PoId { get; set; } public int? PoId { get; set; }
public PurchaseOrder? PurchaseOrder { get; set; } public PurchaseOrder? PurchaseOrder { get; set; }
public long VendorId { get; set; } public int VendorId { get; set; }
public Vendor? Vendor { get; set; } public Vendor? Vendor { get; set; }
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public Warehouse? Warehouse { get; set; } public Warehouse? Warehouse { get; set; }
public GrnStatus Status { get; set; } = GrnStatus.Draft; public GrnStatus Status { get; set; } = GrnStatus.Draft;
public long CreatedBy { get; set; } public int CreatedBy { get; set; }
public User? Creator { get; set; } public User? Creator { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
+7 -7
View File
@@ -10,24 +10,24 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class GrnLine public class GrnLine
{ {
public long GrnLineId { get; set; } public int GrnLineId { get; set; }
public long GrnId { get; set; } public int GrnId { get; set; }
public Grn? Grn { get; set; } public Grn? Grn { get; set; }
public long? PoLineId { get; set; } public int? PoLineId { get; set; }
public PoLine? PoLine { get; set; } public PoLine? PoLine { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public long UomId { get; set; } public int UomId { get; set; }
public Uom? Uom { get; set; } public Uom? Uom { get; set; }
public long? BinId { get; set; } public int? BinId { get; set; }
public Bin? Bin { get; set; } public Bin? Bin { get; set; }
public long? BatchId { get; set; } public int? BatchId { get; set; }
public Batch? Batch { get; set; } public Batch? Batch { get; set; }
public decimal Qty { get; set; } public decimal Qty { get; set; }
+4 -4
View File
@@ -9,18 +9,18 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Item public class Item
{ {
public long ItemId { get; set; } public int ItemId { get; set; }
public string Sku { get; set; } = string.Empty; public string Sku { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
public string? Description { get; set; } public string? Description { get; set; }
public long CategoryId { get; set; } public int CategoryId { get; set; }
public Category? Category { get; set; } public Category? Category { get; set; }
public long BaseUomId { get; set; } public int BaseUomId { get; set; }
public Uom? BaseUom { get; set; } public Uom? BaseUom { get; set; }
public long? DefaultVendorId { get; set; } public int? DefaultVendorId { get; set; }
public Vendor? DefaultVendor { get; set; } public Vendor? DefaultVendor { get; set; }
public ItemType ItemType { get; set; } public ItemType ItemType { get; set; }
@@ -7,12 +7,12 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class ItemReorder public class ItemReorder
{ {
public long ReorderId { get; set; } public int ReorderId { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public Warehouse? Warehouse { get; set; } public Warehouse? Warehouse { get; set; }
public decimal ReorderPoint { get; set; } public decimal ReorderPoint { get; set; }
@@ -9,9 +9,9 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class JournalEntryStub public class JournalEntryStub
{ {
public long JournalId { get; set; } public int JournalId { get; set; }
public string SourceDocType { get; set; } = string.Empty; public string SourceDocType { get; set; } = string.Empty;
public long SourceDocId { get; set; } public int SourceDocId { get; set; }
public string DebitAccount { get; set; } = string.Empty; public string DebitAccount { get; set; } = string.Empty;
public string CreditAccount { get; set; } = string.Empty; public string CreditAccount { get; set; } = string.Empty;
public decimal Amount { get; set; } public decimal Amount { get; set; }
@@ -8,8 +8,8 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class NumberSequence public class NumberSequence
{ {
public long SequenceId { get; set; } public int SequenceId { get; set; }
public string DocType { get; set; } = string.Empty; public string DocType { get; set; } = string.Empty;
public int Year { get; set; } public int Year { get; set; }
public long LastNumber { get; set; } public int LastNumber { get; set; }
} }
+5 -5
View File
@@ -7,18 +7,18 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class PoLine public class PoLine
{ {
public long PoLineId { get; set; } public int PoLineId { get; set; }
public long PoId { get; set; } public int PoId { get; set; }
public PurchaseOrder? PurchaseOrder { get; set; } public PurchaseOrder? PurchaseOrder { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public long UomId { get; set; } public int UomId { get; set; }
public Uom? Uom { get; set; } public Uom? Uom { get; set; }
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public Warehouse? Warehouse { get; set; } public Warehouse? Warehouse { get; set; }
public decimal Qty { get; set; } public decimal Qty { get; set; }
@@ -11,19 +11,19 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class PurchaseOrder public class PurchaseOrder
{ {
public long PoId { get; set; } public int PoId { get; set; }
public string DocNo { get; set; } = string.Empty; public string DocNo { get; set; } = string.Empty;
public long VendorId { get; set; } public int VendorId { get; set; }
public Vendor? Vendor { get; set; } public Vendor? Vendor { get; set; }
public long? RequisitionId { get; set; } public int? RequisitionId { get; set; }
public Requisition? Requisition { get; set; } public Requisition? Requisition { get; set; }
public PurchaseOrderStatus Status { get; set; } = PurchaseOrderStatus.Draft; public PurchaseOrderStatus Status { get; set; } = PurchaseOrderStatus.Draft;
public bool ApprovalRequired { get; set; } public bool ApprovalRequired { get; set; }
public long CreatedBy { get; set; } public int CreatedBy { get; set; }
public User? Creator { get; set; } public User? Creator { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
@@ -9,21 +9,21 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class PurchaseReturn public class PurchaseReturn
{ {
public long ReturnId { get; set; } public int ReturnId { get; set; }
public string DocNo { get; set; } = string.Empty; public string DocNo { get; set; } = string.Empty;
public long VendorId { get; set; } public int VendorId { get; set; }
public Vendor? Vendor { get; set; } public Vendor? Vendor { get; set; }
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public Warehouse? Warehouse { get; set; } public Warehouse? Warehouse { get; set; }
public long ReasonCodeId { get; set; } public int ReasonCodeId { get; set; }
public ReasonCode? ReasonCode { get; set; } public ReasonCode? ReasonCode { get; set; }
public ReturnStatus Status { get; set; } = ReturnStatus.Posted; public ReturnStatus Status { get; set; } = ReturnStatus.Posted;
public long CreatedBy { get; set; } public int CreatedBy { get; set; }
public User? Creator { get; set; } public User? Creator { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
@@ -6,15 +6,15 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class PurchaseReturnLine public class PurchaseReturnLine
{ {
public long ReturnLineId { get; set; } public int ReturnLineId { get; set; }
public long ReturnId { get; set; } public int ReturnId { get; set; }
public PurchaseReturn? Return { get; set; } public PurchaseReturn? Return { get; set; }
public long? GrnLineId { get; set; } public int? GrnLineId { get; set; }
public GrnLine? GrnLine { get; set; } public GrnLine? GrnLine { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public decimal Qty { get; set; } public decimal Qty { get; set; }
@@ -8,7 +8,7 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class ReasonCode public class ReasonCode
{ {
public long ReasonCodeId { get; set; } public int ReasonCodeId { get; set; }
public string Code { get; set; } = string.Empty; public string Code { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty; public string Description { get; set; } = string.Empty;
public ReasonContext Context { get; set; } public ReasonContext Context { get; set; }
@@ -8,10 +8,10 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Requisition public class Requisition
{ {
public long RequisitionId { get; set; } public int RequisitionId { get; set; }
public string DocNo { get; set; } = string.Empty; public string DocNo { get; set; } = string.Empty;
public long RequestedBy { get; set; } public int RequestedBy { get; set; }
public User? Requester { get; set; } public User? Requester { get; set; }
public RequisitionStatus Status { get; set; } = RequisitionStatus.Draft; public RequisitionStatus Status { get; set; } = RequisitionStatus.Draft;
@@ -3,12 +3,12 @@ namespace ERPCore.Domain.Entities;
/// <summary>Requisition line (FR-PROC-01). Model: docs/10 Part C.2.</summary> /// <summary>Requisition line (FR-PROC-01). Model: docs/10 Part C.2.</summary>
public class RequisitionLine public class RequisitionLine
{ {
public long ReqLineId { get; set; } public int ReqLineId { get; set; }
public long RequisitionId { get; set; } public int RequisitionId { get; set; }
public Requisition? Requisition { get; set; } public Requisition? Requisition { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public decimal Qty { get; set; } public decimal Qty { get; set; }
+2 -2
View File
@@ -8,10 +8,10 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Rfq public class Rfq
{ {
public long RfqId { get; set; } public int RfqId { get; set; }
public string DocNo { get; set; } = string.Empty; public string DocNo { get; set; } = string.Empty;
public long RequisitionId { get; set; } public int RequisitionId { get; set; }
public Requisition? Requisition { get; set; } public Requisition? Requisition { get; set; }
public RfqStatus Status { get; set; } = RfqStatus.Open; public RfqStatus Status { get; set; } = RfqStatus.Open;
+3 -3
View File
@@ -3,12 +3,12 @@ namespace ERPCore.Domain.Entities;
/// <summary>RFQ line — an item + quantity being quoted (FR-PROC-02). Model: docs/10 Part C.2.</summary> /// <summary>RFQ line — an item + quantity being quoted (FR-PROC-02). Model: docs/10 Part C.2.</summary>
public class RfqLine public class RfqLine
{ {
public long RfqLineId { get; set; } public int RfqLineId { get; set; }
public long RfqId { get; set; } public int RfqId { get; set; }
public Rfq? Rfq { get; set; } public Rfq? Rfq { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public decimal Qty { get; set; } public decimal Qty { get; set; }
+2 -2
View File
@@ -6,9 +6,9 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Serial public class Serial
{ {
public long SerialId { get; set; } public int SerialId { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public string SerialNo { get; set; } = string.Empty; public string SerialNo { get; set; } = string.Empty;
@@ -10,18 +10,18 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class StockAdjustment public class StockAdjustment
{ {
public long AdjustmentId { get; set; } public int AdjustmentId { get; set; }
public string DocNo { get; set; } = string.Empty; public string DocNo { get; set; } = string.Empty;
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public Warehouse? Warehouse { get; set; } public Warehouse? Warehouse { get; set; }
public long ReasonCodeId { get; set; } public int ReasonCodeId { get; set; }
public ReasonCode? ReasonCode { get; set; } public ReasonCode? ReasonCode { get; set; }
public AdjustmentStatus Status { get; set; } = AdjustmentStatus.Posted; public AdjustmentStatus Status { get; set; } = AdjustmentStatus.Posted;
public long CreatedBy { get; set; } public int CreatedBy { get; set; }
public User? Creator { get; set; } public User? Creator { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
@@ -7,17 +7,17 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class StockAdjustmentLine public class StockAdjustmentLine
{ {
public long AdjLineId { get; set; } public int AdjLineId { get; set; }
public long AdjustmentId { get; set; } public int AdjustmentId { get; set; }
public StockAdjustment? Adjustment { get; set; } public StockAdjustment? Adjustment { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public long? BinId { get; set; } public int? BinId { get; set; }
public long? BatchId { get; set; } public int? BatchId { get; set; }
public long? SerialId { get; set; } public int? SerialId { get; set; }
public decimal QtyDelta { get; set; } public decimal QtyDelta { get; set; }
} }
@@ -10,16 +10,16 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class StockCount public class StockCount
{ {
public long CountId { get; set; } public int CountId { get; set; }
public string DocNo { get; set; } = string.Empty; public string DocNo { get; set; } = string.Empty;
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public Warehouse? Warehouse { get; set; } public Warehouse? Warehouse { get; set; }
public CountType CountType { get; set; } public CountType CountType { get; set; }
public CountStatus Status { get; set; } = CountStatus.Draft; public CountStatus Status { get; set; } = CountStatus.Draft;
public long CreatedBy { get; set; } public int CreatedBy { get; set; }
public User? Creator { get; set; } public User? Creator { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
@@ -6,15 +6,15 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class StockCountLine public class StockCountLine
{ {
public long CountLineId { get; set; } public int CountLineId { get; set; }
public long CountId { get; set; } public int CountId { get; set; }
public StockCount? Count { get; set; } public StockCount? Count { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public long? BinId { get; set; } public int? BinId { get; set; }
public decimal SystemQty { get; set; } public decimal SystemQty { get; set; }
public decimal? CountedQty { get; set; } public decimal? CountedQty { get; set; }
@@ -8,22 +8,22 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class StockLayer public class StockLayer
{ {
public long LayerId { get; set; } public int LayerId { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public Warehouse? Warehouse { get; set; } public Warehouse? Warehouse { get; set; }
public long? BatchId { get; set; } public int? BatchId { get; set; }
public Batch? Batch { get; set; } public Batch? Batch { get; set; }
public long? SerialId { get; set; } public int? SerialId { get; set; }
public Serial? Serial { get; set; } public Serial? Serial { get; set; }
/// <summary>Originating GRN line — carries the inspection hold status for this stock.</summary> /// <summary>Originating GRN line — carries the inspection hold status for this stock.</summary>
public long? GrnLineId { get; set; } public int? GrnLineId { get; set; }
public GrnLine? GrnLine { get; set; } public GrnLine? GrnLine { get; set; }
public decimal QtyReceived { get; set; } public decimal QtyReceived { get; set; }
@@ -11,14 +11,14 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class StockLedger public class StockLedger
{ {
public long LedgerId { get; set; } public int LedgerId { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public long? BinId { get; set; } public int? BinId { get; set; }
public long? BatchId { get; set; } public int? BatchId { get; set; }
public long? SerialId { get; set; } public int? SerialId { get; set; }
public long UserId { get; set; } public int UserId { get; set; }
public Direction Direction { get; set; } public Direction Direction { get; set; }
public decimal QtyBase { get; set; } public decimal QtyBase { get; set; }
@@ -27,6 +27,6 @@ public class StockLedger
public decimal RunningBalance { get; set; } public decimal RunningBalance { get; set; }
public string SourceDocType { get; set; } = string.Empty; public string SourceDocType { get; set; } = string.Empty;
public long SourceDocId { get; set; } public int SourceDocId { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
} }
@@ -10,18 +10,18 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class StockTransfer public class StockTransfer
{ {
public long TransferId { get; set; } public int TransferId { get; set; }
public string DocNo { get; set; } = string.Empty; public string DocNo { get; set; } = string.Empty;
public long SrcWarehouseId { get; set; } public int SrcWarehouseId { get; set; }
public Warehouse? SrcWarehouse { get; set; } public Warehouse? SrcWarehouse { get; set; }
public long DestWarehouseId { get; set; } public int DestWarehouseId { get; set; }
public Warehouse? DestWarehouse { get; set; } public Warehouse? DestWarehouse { get; set; }
public TransferStatus Status { get; set; } = TransferStatus.Draft; public TransferStatus Status { get; set; } = TransferStatus.Draft;
public long CreatedBy { get; set; } public int CreatedBy { get; set; }
public User? Creator { get; set; } public User? Creator { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
@@ -12,18 +12,18 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class StockTransferLine public class StockTransferLine
{ {
public long TransferLineId { get; set; } public int TransferLineId { get; set; }
public long TransferId { get; set; } public int TransferId { get; set; }
public StockTransfer? Transfer { get; set; } public StockTransfer? Transfer { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public long? SrcBinId { get; set; } public int? SrcBinId { get; set; }
public long? DestBinId { get; set; } public int? DestBinId { get; set; }
public long? BatchId { get; set; } public int? BatchId { get; set; }
public long? SerialId { get; set; } public int? SerialId { get; set; }
public decimal Qty { get; set; } public decimal Qty { get; set; }
+1 -1
View File
@@ -6,6 +6,6 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Uom public class Uom
{ {
public long UomId { get; set; } public int UomId { get; set; }
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
} }
@@ -7,15 +7,15 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class UomConversion public class UomConversion
{ {
public long ConversionId { get; set; } public int ConversionId { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public long FromUomId { get; set; } public int FromUomId { get; set; }
public Uom? FromUom { get; set; } public Uom? FromUom { get; set; }
public long ToUomId { get; set; } public int ToUomId { get; set; }
public Uom? ToUom { get; set; } public Uom? ToUom { get; set; }
public decimal Factor { get; set; } public decimal Factor { get; set; }
+3 -3
View File
@@ -4,7 +4,7 @@ namespace ERPCore.Domain.Entities;
/// <summary> /// <summary>
/// Application user (FR-X-01) — a **local shadow/projection** of an AuthHex identity. /// Application user (FR-X-01) — a **local shadow/projection** of an AuthHex identity.
/// The local <see cref="UserId"/> (long) is what every `createdBy`/`requestedBy`/ /// The local <see cref="UserId"/> (int) is what every `createdBy`/`requestedBy`/
/// audit/ledger FK references; <see cref="AuthUserId"/> maps it to the AuthHex /// audit/ledger FK references; <see cref="AuthUserId"/> maps it to the AuthHex
/// <c>UserId</c> (GUID) and is JIT-provisioned on first authenticated request /// <c>UserId</c> (GUID) and is JIT-provisioned on first authenticated request
/// (docs/10 A.4/C.7). A seeded <c>system</c> user (id 1, null AuthUserId) is the /// (docs/10 A.4/C.7). A seeded <c>system</c> user (id 1, null AuthUserId) is the
@@ -13,9 +13,9 @@ namespace ERPCore.Domain.Entities;
public class User public class User
{ {
/// <summary>Seeded fallback actor for unauthenticated/system operations.</summary> /// <summary>Seeded fallback actor for unauthenticated/system operations.</summary>
public const long SystemUserId = 1; public const int SystemUserId = 1;
public long UserId { get; set; } public int UserId { get; set; }
public string Username { get; set; } = string.Empty; public string Username { get; set; } = string.Empty;
public string DisplayName { get; set; } = string.Empty; public string DisplayName { get; set; } = string.Empty;
public EntityStatus Status { get; set; } = EntityStatus.Active; public EntityStatus Status { get; set; } = EntityStatus.Active;
+1 -1
View File
@@ -9,7 +9,7 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Vendor public class Vendor
{ {
public long VendorId { get; set; } public int VendorId { get; set; }
public string Code { get; set; } = string.Empty; public string Code { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
public string? Terms { get; set; } public string? Terms { get; set; }
@@ -12,12 +12,12 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class VendorQuotation public class VendorQuotation
{ {
public long QuotationId { get; set; } public int QuotationId { get; set; }
public long RfqId { get; set; } public int RfqId { get; set; }
public Rfq? Rfq { get; set; } public Rfq? Rfq { get; set; }
public long VendorId { get; set; } public int VendorId { get; set; }
public Vendor? Vendor { get; set; } public Vendor? Vendor { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
@@ -3,12 +3,12 @@ namespace ERPCore.Domain.Entities;
/// <summary>Per-item quoted price and lead time within a <see cref="VendorQuotation"/> (docs/11 §3.2).</summary> /// <summary>Per-item quoted price and lead time within a <see cref="VendorQuotation"/> (docs/11 §3.2).</summary>
public class VendorQuotationLine public class VendorQuotationLine
{ {
public long QuotationLineId { get; set; } public int QuotationLineId { get; set; }
public long QuotationId { get; set; } public int QuotationId { get; set; }
public VendorQuotation? Quotation { get; set; } public VendorQuotation? Quotation { get; set; }
public long ItemId { get; set; } public int ItemId { get; set; }
public Item? Item { get; set; } public Item? Item { get; set; }
public decimal UnitPrice { get; set; } public decimal UnitPrice { get; set; }
+1 -1
View File
@@ -6,7 +6,7 @@ namespace ERPCore.Domain.Entities;
/// </summary> /// </summary>
public class Warehouse public class Warehouse
{ {
public long WarehouseId { get; set; } public int WarehouseId { get; set; }
public string Code { get; set; } = string.Empty; public string Code { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
+2 -2
View File
@@ -5,8 +5,8 @@ namespace ERPCore.Dtos.Audit;
/// <summary>An audit-trail entry (FR-X-02). <c>ChangeSet</c> is the stored JSON, inlined.</summary> /// <summary>An audit-trail entry (FR-X-02). <c>ChangeSet</c> is the stored JSON, inlined.</summary>
public sealed record AuditLogDto( public sealed record AuditLogDto(
long AuditId, long UserId, string EntityType, long EntityId, AuditAction Action, JsonElement ChangeSet, DateTime CreatedAt); int AuditId, int UserId, string EntityType, int EntityId, AuditAction Action, JsonElement ChangeSet, DateTime CreatedAt);
/// <summary>A GL-ready journal stub emitted per stock movement (FR-STK-13).</summary> /// <summary>A GL-ready journal stub emitted per stock movement (FR-STK-13).</summary>
public sealed record JournalEntryStubDto( public sealed record JournalEntryStubDto(
long JournalId, string SourceDocType, long SourceDocId, string DebitAccount, string CreditAccount, decimal Amount); int JournalId, string SourceDocType, int SourceDocId, string DebitAccount, string CreditAccount, decimal Amount);
@@ -3,13 +3,13 @@ using System.ComponentModel.DataAnnotations;
namespace ERPCore.Dtos.Categories; namespace ERPCore.Dtos.Categories;
/// <summary>Flat category resource (docs/11-BACKEND-PHASE1.md §2.3).</summary> /// <summary>Flat category resource (docs/11-BACKEND-PHASE1.md §2.3).</summary>
public sealed record CategoryDto(long CategoryId, string Name, long? ParentId); public sealed record CategoryDto(int CategoryId, string Name, int? ParentId);
/// <summary>Nested category node for <c>GET /categories?tree=true</c>.</summary> /// <summary>Nested category node for <c>GET /categories?tree=true</c>.</summary>
public sealed record CategoryTreeDto(long CategoryId, string Name, long? ParentId, IReadOnlyList<CategoryTreeDto> Children); public sealed record CategoryTreeDto(int CategoryId, string Name, int? ParentId, IReadOnlyList<CategoryTreeDto> Children);
public sealed class CreateCategoryRequest public sealed class CreateCategoryRequest
{ {
[Required, StringLength(200)] public string Name { get; set; } = string.Empty; [Required, StringLength(200)] public string Name { get; set; } = string.Empty;
public long? ParentId { get; set; } public int? ParentId { get; set; }
} }
+15 -15
View File
@@ -6,22 +6,22 @@ namespace ERPCore.Dtos.Grn;
// Responses (docs/11 §4) -------------------------------------------------------- // Responses (docs/11 §4) --------------------------------------------------------
public sealed record GrnLineDto( public sealed record GrnLineDto(
long GrnLineId, long? PoLineId, long ItemId, long UomId, long? BinId, int GrnLineId, int? PoLineId, int ItemId, int UomId, int? BinId,
decimal Qty, decimal UnitCost, decimal ReceivedValue, HoldStatus HoldStatus, long? BatchId); decimal Qty, decimal UnitCost, decimal ReceivedValue, HoldStatus HoldStatus, int? BatchId);
public sealed record GrnDto( public sealed record GrnDto(
long GrnId, string DocNo, long? PoId, long VendorId, long WarehouseId, GrnStatus Status, int GrnId, string DocNo, int? PoId, int VendorId, int WarehouseId, GrnStatus Status,
long CreatedBy, DateTime CreatedAt, DateTime? PostedAt, IReadOnlyList<GrnLineDto> Lines); int CreatedBy, DateTime CreatedAt, DateTime? PostedAt, IReadOnlyList<GrnLineDto> Lines);
public sealed record CreatedLayerDto( public sealed record CreatedLayerDto(
long LayerId, long ItemId, long WarehouseId, long? BatchId, int LayerId, int ItemId, int WarehouseId, int? BatchId,
decimal QtyReceived, decimal QtyRemaining, decimal UnitCost, DateTime ReceiptDate); decimal QtyReceived, decimal QtyRemaining, decimal UnitCost, DateTime ReceiptDate);
public sealed record GrnConfirmResultDto( public sealed record GrnConfirmResultDto(
long GrnId, GrnStatus Status, DateTime PostedAt, int GrnId, GrnStatus Status, DateTime PostedAt,
IReadOnlyList<CreatedLayerDto> CreatedLayers, IReadOnlyList<long> LedgerRefs, PurchaseOrderStatus? PoStatus); IReadOnlyList<CreatedLayerDto> CreatedLayers, IReadOnlyList<int> LedgerRefs, PurchaseOrderStatus? PoStatus);
public sealed record ReleaseLineResultDto(long GrnLineId, HoldStatus HoldStatus); public sealed record ReleaseLineResultDto(int GrnLineId, HoldStatus HoldStatus);
// Requests ---------------------------------------------------------------------- // Requests ----------------------------------------------------------------------
@@ -34,10 +34,10 @@ public sealed class BatchInput
public sealed class CreateGrnLineInput public sealed class CreateGrnLineInput
{ {
/// <summary>Set for a PO-based receipt; cost is then derived from the PO line (02-SECURITY C.3).</summary> /// <summary>Set for a PO-based receipt; cost is then derived from the PO line (02-SECURITY C.3).</summary>
public long? PoLineId { get; set; } public int? PoLineId { get; set; }
[Required] public long ItemId { get; set; } [Required] public int ItemId { get; set; }
[Required] public long UomId { get; set; } [Required] public int UomId { get; set; }
public long? BinId { get; set; } public int? BinId { get; set; }
[Range(0.0001, double.MaxValue)] public decimal Qty { get; set; } [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; }
/// <summary>Used only for direct (no-PO) receipts; ignored when <see cref="PoLineId"/> is set.</summary> /// <summary>Used only for direct (no-PO) receipts; ignored when <see cref="PoLineId"/> is set.</summary>
[Range(0, double.MaxValue)] public decimal UnitCost { get; set; } [Range(0, double.MaxValue)] public decimal UnitCost { get; set; }
@@ -48,10 +48,10 @@ public sealed class CreateGrnLineInput
public sealed class CreateGrnRequest public sealed class CreateGrnRequest
{ {
/// <summary>PO to receive against; null for a direct/emergency receipt (FR-GRN-02).</summary> /// <summary>PO to receive against; null for a direct/emergency receipt (FR-GRN-02).</summary>
public long? PoId { get; set; } public int? PoId { get; set; }
/// <summary>Required for a direct receipt (no PO); ignored otherwise (vendor derives from the PO).</summary> /// <summary>Required for a direct receipt (no PO); ignored otherwise (vendor derives from the PO).</summary>
public long? VendorId { get; set; } public int? VendorId { get; set; }
[Required] public long WarehouseId { get; set; } [Required] public int WarehouseId { get; set; }
[Required, MinLength(1)] public List<CreateGrnLineInput> Lines { get; set; } = new(); [Required, MinLength(1)] public List<CreateGrnLineInput> Lines { get; set; } = new();
} }
+16 -16
View File
@@ -7,25 +7,25 @@ namespace ERPCore.Dtos.Items;
/// <summary>Row shape for <c>GET /items</c>.</summary> /// <summary>Row shape for <c>GET /items</c>.</summary>
public sealed record ItemListItemDto( public sealed record ItemListItemDto(
long ItemId, string Sku, string Name, long CategoryId, long BaseUomId, int ItemId, string Sku, string Name, int CategoryId, int BaseUomId,
long? DefaultVendorId, ItemType ItemType, TrackingMode TrackingMode, int? DefaultVendorId, ItemType ItemType, TrackingMode TrackingMode,
string? TaxClass, EntityStatus Status); string? TaxClass, EntityStatus Status);
/// <summary>A single per-warehouse reorder policy row.</summary> /// <summary>A single per-warehouse reorder policy row.</summary>
public sealed record ItemReorderDto(long WarehouseId, decimal ReorderPoint, decimal ReorderQty); public sealed record ItemReorderDto(int WarehouseId, decimal ReorderPoint, decimal ReorderQty);
/// <summary>Full item resource for <c>GET /items/{id}</c> and create/update responses.</summary> /// <summary>Full item resource for <c>GET /items/{id}</c> and create/update responses.</summary>
public sealed record ItemDetailDto( public sealed record ItemDetailDto(
long ItemId, string Sku, string Name, string? Description, long CategoryId, int ItemId, string Sku, string Name, string? Description, int CategoryId,
long BaseUomId, long? DefaultVendorId, ItemType ItemType, TrackingMode TrackingMode, int BaseUomId, int? DefaultVendorId, ItemType ItemType, TrackingMode TrackingMode,
string? TaxClass, EntityStatus Status, IReadOnlyList<ItemReorderDto> Reorder, string? TaxClass, EntityStatus Status, IReadOnlyList<ItemReorderDto> Reorder,
DateTime CreatedAt, DateTime? UpdatedAt); DateTime CreatedAt, DateTime? UpdatedAt);
/// <summary>UOM conversion row (docs/11 §2.2).</summary> /// <summary>UOM conversion row (docs/11 §2.2).</summary>
public sealed record UomConversionDto(long ConversionId, long FromUom, long ToUom, decimal Factor); public sealed record UomConversionDto(int ConversionId, int FromUom, int ToUom, decimal Factor);
/// <summary>Response body for <c>PUT /items/{id}/uom-conversions</c>.</summary> /// <summary>Response body for <c>PUT /items/{id}/uom-conversions</c>.</summary>
public sealed record ItemUomConversionsDto(long ItemId, long BaseUomId, IReadOnlyList<UomConversionDto> Conversions); public sealed record ItemUomConversionsDto(int ItemId, int BaseUomId, IReadOnlyList<UomConversionDto> Conversions);
/// <summary>Response body for <c>PUT /items/{id}/reorder</c>.</summary> /// <summary>Response body for <c>PUT /items/{id}/reorder</c>.</summary>
public sealed record ItemReorderSettingsDto(IReadOnlyList<ItemReorderDto> Settings); public sealed record ItemReorderSettingsDto(IReadOnlyList<ItemReorderDto> Settings);
@@ -38,9 +38,9 @@ public sealed class CreateItemRequest
[Required, StringLength(50)] public string Sku { get; set; } = string.Empty; [Required, StringLength(50)] public string Sku { get; set; } = string.Empty;
[Required, StringLength(200)] public string Name { get; set; } = string.Empty; [Required, StringLength(200)] public string Name { get; set; } = string.Empty;
[StringLength(1000)] public string? Description { get; set; } [StringLength(1000)] public string? Description { get; set; }
[Required] public long CategoryId { get; set; } [Required] public int CategoryId { get; set; }
[Required] public long BaseUomId { get; set; } [Required] public int BaseUomId { get; set; }
public long? DefaultVendorId { get; set; } public int? DefaultVendorId { get; set; }
[Required, EnumDataType(typeof(ItemType))] public ItemType ItemType { get; set; } [Required, EnumDataType(typeof(ItemType))] public ItemType ItemType { get; set; }
[EnumDataType(typeof(TrackingMode))] public TrackingMode TrackingMode { get; set; } = TrackingMode.None; [EnumDataType(typeof(TrackingMode))] public TrackingMode TrackingMode { get; set; } = TrackingMode.None;
[StringLength(20)] public string? TaxClass { get; set; } [StringLength(20)] public string? TaxClass { get; set; }
@@ -51,9 +51,9 @@ public sealed class UpdateItemRequest
[Required, StringLength(50)] public string Sku { get; set; } = string.Empty; [Required, StringLength(50)] public string Sku { get; set; } = string.Empty;
[Required, StringLength(200)] public string Name { get; set; } = string.Empty; [Required, StringLength(200)] public string Name { get; set; } = string.Empty;
[StringLength(1000)] public string? Description { get; set; } [StringLength(1000)] public string? Description { get; set; }
[Required] public long CategoryId { get; set; } [Required] public int CategoryId { get; set; }
[Required] public long BaseUomId { get; set; } [Required] public int BaseUomId { get; set; }
public long? DefaultVendorId { get; set; } public int? DefaultVendorId { get; set; }
[Required, EnumDataType(typeof(ItemType))] public ItemType ItemType { get; set; } [Required, EnumDataType(typeof(ItemType))] public ItemType ItemType { get; set; }
[EnumDataType(typeof(TrackingMode))] public TrackingMode TrackingMode { get; set; } = TrackingMode.None; [EnumDataType(typeof(TrackingMode))] public TrackingMode TrackingMode { get; set; } = TrackingMode.None;
[StringLength(20)] public string? TaxClass { get; set; } [StringLength(20)] public string? TaxClass { get; set; }
@@ -66,7 +66,7 @@ public sealed class UpdateItemStatusRequest
public sealed class ReorderSettingInput public sealed class ReorderSettingInput
{ {
[Required] public long WarehouseId { get; set; } [Required] public int WarehouseId { get; set; }
[Range(0, double.MaxValue)] public decimal ReorderPoint { get; set; } [Range(0, double.MaxValue)] public decimal ReorderPoint { get; set; }
[Range(0, double.MaxValue)] public decimal ReorderQty { get; set; } [Range(0, double.MaxValue)] public decimal ReorderQty { get; set; }
} }
@@ -78,8 +78,8 @@ public sealed class UpdateReorderRequest
public sealed class UomConversionInput public sealed class UomConversionInput
{ {
[Required] public long FromUom { get; set; } [Required] public int FromUom { get; set; }
[Required] public long ToUom { get; set; } [Required] public int ToUom { get; set; }
[Range(0.000001, double.MaxValue)] public decimal Factor { get; set; } [Range(0.000001, double.MaxValue)] public decimal Factor { get; set; }
} }
@@ -6,27 +6,27 @@ namespace ERPCore.Dtos.Procurement;
// Responses (docs/11 §3.3) ------------------------------------------------------ // Responses (docs/11 §3.3) ------------------------------------------------------
public sealed record PoLineDto( public sealed record PoLineDto(
long PoLineId, long ItemId, long UomId, long WarehouseId, int PoLineId, int ItemId, int UomId, int WarehouseId,
decimal Qty, decimal UnitPrice, decimal Tax, decimal QtyReceived); decimal Qty, decimal UnitPrice, decimal Tax, decimal QtyReceived);
public sealed record PoTotalsDto(decimal SubTotal, decimal Tax, decimal GrandTotal, string Currency); public sealed record PoTotalsDto(decimal SubTotal, decimal Tax, decimal GrandTotal, string Currency);
public sealed record PurchaseOrderDto( public sealed record PurchaseOrderDto(
long PoId, string DocNo, long VendorId, long? RequisitionId, PurchaseOrderStatus Status, int PoId, string DocNo, int VendorId, int? RequisitionId, PurchaseOrderStatus Status,
bool ApprovalRequired, long CreatedBy, DateTime CreatedAt, DateTime? UpdatedAt, bool ApprovalRequired, int CreatedBy, DateTime CreatedAt, DateTime? UpdatedAt,
PoTotalsDto Totals, IReadOnlyList<PoLineDto> Lines); PoTotalsDto Totals, IReadOnlyList<PoLineDto> Lines);
public sealed record PurchaseOrderSummaryDto( public sealed record PurchaseOrderSummaryDto(
long PoId, string DocNo, long VendorId, PurchaseOrderStatus Status, int PoId, string DocNo, int VendorId, PurchaseOrderStatus Status,
bool ApprovalRequired, DateTime CreatedAt, PoTotalsDto Totals); bool ApprovalRequired, DateTime CreatedAt, PoTotalsDto Totals);
// Requests — server sets docNo, status, createdBy, timestamps, qtyReceived, totals // Requests — server sets docNo, status, createdBy, timestamps, qtyReceived, totals
public sealed class CreatePoLineInput public sealed class CreatePoLineInput
{ {
[Required] public long ItemId { get; set; } [Required] public int ItemId { get; set; }
[Required] public long UomId { get; set; } [Required] public int UomId { get; set; }
[Required] public long WarehouseId { get; set; } [Required] public int WarehouseId { get; set; }
[Range(0.0001, double.MaxValue)] public decimal Qty { get; set; } [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; }
[Range(0, double.MaxValue)] public decimal UnitPrice { get; set; } [Range(0, double.MaxValue)] public decimal UnitPrice { get; set; }
[Range(0, 1)] public decimal Tax { get; set; } [Range(0, 1)] public decimal Tax { get; set; }
@@ -34,15 +34,15 @@ public sealed class CreatePoLineInput
public sealed class CreatePurchaseOrderRequest public sealed class CreatePurchaseOrderRequest
{ {
[Required] public long VendorId { get; set; } [Required] public int VendorId { get; set; }
public long? RequisitionId { get; set; } public int? RequisitionId { get; set; }
[Required, MinLength(1)] public List<CreatePoLineInput> Lines { get; set; } = new(); [Required, MinLength(1)] public List<CreatePoLineInput> Lines { get; set; } = new();
} }
public sealed class UpdatePurchaseOrderRequest public sealed class UpdatePurchaseOrderRequest
{ {
[Required] public long VendorId { get; set; } [Required] public int VendorId { get; set; }
public long? RequisitionId { get; set; } public int? RequisitionId { get; set; }
[Required, MinLength(1)] public List<CreatePoLineInput> Lines { get; set; } = new(); [Required, MinLength(1)] public List<CreatePoLineInput> Lines { get; set; } = new();
} }
@@ -5,27 +5,27 @@ namespace ERPCore.Dtos.Procurement;
// Responses (docs/11 §3.4) ------------------------------------------------------ // Responses (docs/11 §3.4) ------------------------------------------------------
public sealed record PurchaseReturnLineDto(long ReturnLineId, long? GrnLineId, long ItemId, decimal Qty); public sealed record PurchaseReturnLineDto(int ReturnLineId, int? GrnLineId, int ItemId, decimal Qty);
public sealed record PurchaseReturnDto( public sealed record PurchaseReturnDto(
long ReturnId, string DocNo, long VendorId, long WarehouseId, long ReasonCodeId, ReturnStatus Status, int ReturnId, string DocNo, int VendorId, int WarehouseId, int ReasonCodeId, ReturnStatus Status,
long CreatedBy, IReadOnlyList<PurchaseReturnLineDto> Lines, IReadOnlyList<long> LedgerRefs); int CreatedBy, IReadOnlyList<PurchaseReturnLineDto> Lines, IReadOnlyList<int> LedgerRefs);
// Requests ---------------------------------------------------------------------- // Requests ----------------------------------------------------------------------
public sealed class CreatePurchaseReturnLineInput public sealed class CreatePurchaseReturnLineInput
{ {
/// <summary>Original GRN line, for traceability against the receipt.</summary> /// <summary>Original GRN line, for traceability against the receipt.</summary>
public long? GrnLineId { get; set; } public int? GrnLineId { get; set; }
[Required] public long ItemId { get; set; } [Required] public int ItemId { get; set; }
[Range(0.0001, double.MaxValue)] public decimal Qty { get; set; } [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; }
} }
public sealed class CreatePurchaseReturnRequest public sealed class CreatePurchaseReturnRequest
{ {
[Required] public long VendorId { get; set; } [Required] public int VendorId { get; set; }
[Required] public long WarehouseId { get; set; } [Required] public int WarehouseId { get; set; }
/// <summary>Nullable so an omitted value is a distinct <c>REASON_CODE_REQUIRED</c> error.</summary> /// <summary>Nullable so an omitted value is a distinct <c>REASON_CODE_REQUIRED</c> error.</summary>
public long? ReasonCodeId { get; set; } public int? ReasonCodeId { get; set; }
[Required, MinLength(1)] public List<CreatePurchaseReturnLineInput> Lines { get; set; } = new(); [Required, MinLength(1)] public List<CreatePurchaseReturnLineInput> Lines { get; set; } = new();
} }
@@ -5,20 +5,20 @@ namespace ERPCore.Dtos.Procurement;
// Responses (docs/11 §3.1) ------------------------------------------------------ // Responses (docs/11 §3.1) ------------------------------------------------------
public sealed record RequisitionLineDto(long ReqLineId, long ItemId, decimal Qty, DateOnly? RequiredBy); public sealed record RequisitionLineDto(int ReqLineId, int ItemId, decimal Qty, DateOnly? RequiredBy);
public sealed record RequisitionDto( public sealed record RequisitionDto(
long RequisitionId, string DocNo, RequisitionStatus Status, long RequestedBy, int RequisitionId, string DocNo, RequisitionStatus Status, int RequestedBy,
DateTime CreatedAt, IReadOnlyList<RequisitionLineDto> Lines); DateTime CreatedAt, IReadOnlyList<RequisitionLineDto> Lines);
public sealed record RequisitionSummaryDto( public sealed record RequisitionSummaryDto(
long RequisitionId, string DocNo, RequisitionStatus Status, long RequestedBy, DateTime CreatedAt); int RequisitionId, string DocNo, RequisitionStatus Status, int RequestedBy, DateTime CreatedAt);
// Requests — server sets docNo, status, requestedBy (audit actor), timestamps ---- // Requests — server sets docNo, status, requestedBy (audit actor), timestamps ----
public sealed class CreateRequisitionLineInput public sealed class CreateRequisitionLineInput
{ {
[Required] public long ItemId { get; set; } [Required] public int ItemId { get; set; }
[Range(0.0001, double.MaxValue)] public decimal Qty { get; set; } [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; }
public DateOnly? RequiredBy { get; set; } public DateOnly? RequiredBy { get; set; }
} }
+12 -12
View File
@@ -5,46 +5,46 @@ namespace ERPCore.Dtos.Procurement;
// Responses (docs/11 §3.2) ------------------------------------------------------ // Responses (docs/11 §3.2) ------------------------------------------------------
public sealed record RfqLineDto(long RfqLineId, long ItemId, decimal Qty); public sealed record RfqLineDto(int RfqLineId, int ItemId, decimal Qty);
public sealed record RfqDto( public sealed record RfqDto(
long RfqId, string DocNo, long RequisitionId, RfqStatus Status, IReadOnlyList<RfqLineDto> Lines); int RfqId, string DocNo, int RequisitionId, RfqStatus Status, IReadOnlyList<RfqLineDto> Lines);
public sealed record QuotationLineDto(long ItemId, decimal UnitPrice, int LeadDays); public sealed record QuotationLineDto(int ItemId, decimal UnitPrice, int LeadDays);
public sealed record VendorQuotationDto( public sealed record VendorQuotationDto(
long QuotationId, long RfqId, long VendorId, IReadOnlyList<QuotationLineDto> Lines); int QuotationId, int RfqId, int VendorId, IReadOnlyList<QuotationLineDto> Lines);
/// <summary>Per-item, per-vendor price matrix for <c>GET /rfqs/{id}/comparison</c>.</summary> /// <summary>Per-item, per-vendor price matrix for <c>GET /rfqs/{id}/comparison</c>.</summary>
public sealed record RfqComparisonCellDto(long VendorId, long QuotationId, decimal UnitPrice, int LeadDays); public sealed record RfqComparisonCellDto(int VendorId, int QuotationId, decimal UnitPrice, int LeadDays);
public sealed record RfqComparisonRowDto(long ItemId, decimal Qty, IReadOnlyList<RfqComparisonCellDto> Quotes); public sealed record RfqComparisonRowDto(int ItemId, decimal Qty, IReadOnlyList<RfqComparisonCellDto> Quotes);
public sealed record RfqComparisonDto(long RfqId, IReadOnlyList<long> VendorIds, IReadOnlyList<RfqComparisonRowDto> Rows); public sealed record RfqComparisonDto(int RfqId, IReadOnlyList<int> VendorIds, IReadOnlyList<RfqComparisonRowDto> Rows);
// Requests ---------------------------------------------------------------------- // Requests ----------------------------------------------------------------------
public sealed class CreateRfqLineInput public sealed class CreateRfqLineInput
{ {
[Required] public long ItemId { get; set; } [Required] public int ItemId { get; set; }
[Range(0.0001, double.MaxValue)] public decimal Qty { get; set; } [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; }
} }
public sealed class CreateRfqRequest public sealed class CreateRfqRequest
{ {
[Required] public long RequisitionId { get; set; } [Required] public int RequisitionId { get; set; }
/// <summary>Vendors the RFQ is issued to (validated for existence; quotations reference them).</summary> /// <summary>Vendors the RFQ is issued to (validated for existence; quotations reference them).</summary>
public List<long> VendorIds { get; set; } = new(); public List<int> VendorIds { get; set; } = new();
[Required, MinLength(1)] public List<CreateRfqLineInput> Lines { get; set; } = new(); [Required, MinLength(1)] public List<CreateRfqLineInput> Lines { get; set; } = new();
} }
public sealed class CreateQuotationLineInput public sealed class CreateQuotationLineInput
{ {
[Required] public long ItemId { get; set; } [Required] public int ItemId { get; set; }
[Range(0, double.MaxValue)] public decimal UnitPrice { get; set; } [Range(0, double.MaxValue)] public decimal UnitPrice { get; set; }
[Range(0, int.MaxValue)] public int LeadDays { get; set; } [Range(0, int.MaxValue)] public int LeadDays { get; set; }
} }
public sealed class CreateQuotationRequest public sealed class CreateQuotationRequest
{ {
[Required] public long VendorId { get; set; } [Required] public int VendorId { get; set; }
[Required, MinLength(1)] public List<CreateQuotationLineInput> Lines { get; set; } = new(); [Required, MinLength(1)] public List<CreateQuotationLineInput> Lines { get; set; } = new();
} }
@@ -4,7 +4,7 @@ using ERPCore.Domain.Enums;
namespace ERPCore.Dtos.Reference; namespace ERPCore.Dtos.Reference;
/// <summary>Reason code (docs/11 §6).</summary> /// <summary>Reason code (docs/11 §6).</summary>
public sealed record ReasonCodeDto(long ReasonCodeId, string Code, string Description, ReasonContext Context); public sealed record ReasonCodeDto(int ReasonCodeId, string Code, string Description, ReasonContext Context);
public sealed class CreateReasonCodeRequest public sealed class CreateReasonCodeRequest
{ {
+8 -8
View File
@@ -5,27 +5,27 @@ namespace ERPCore.Dtos.Stock;
// Responses (docs/11 §5.5) ------------------------------------------------------ // Responses (docs/11 §5.5) ------------------------------------------------------
public sealed record AdjustmentLineDto(long AdjLineId, long ItemId, long? BinId, long? BatchId, decimal QtyDelta); public sealed record AdjustmentLineDto(int AdjLineId, int ItemId, int? BinId, int? BatchId, decimal QtyDelta);
public sealed record AdjustmentDto( public sealed record AdjustmentDto(
long AdjustmentId, string DocNo, long WarehouseId, long ReasonCodeId, AdjustmentStatus Status, int AdjustmentId, string DocNo, int WarehouseId, int ReasonCodeId, AdjustmentStatus Status,
long CreatedBy, DateTime CreatedAt, IReadOnlyList<AdjustmentLineDto> Lines, IReadOnlyList<long> LedgerRefs); int CreatedBy, DateTime CreatedAt, IReadOnlyList<AdjustmentLineDto> Lines, IReadOnlyList<int> LedgerRefs);
// Requests ---------------------------------------------------------------------- // Requests ----------------------------------------------------------------------
public sealed class CreateAdjustmentLineInput public sealed class CreateAdjustmentLineInput
{ {
[Required] public long ItemId { get; set; } [Required] public int ItemId { get; set; }
public long? BinId { get; set; } public int? BinId { get; set; }
public long? BatchId { get; set; } public int? BatchId { get; set; }
/// <summary>Signed base-UOM delta: negative consumes FIFO layers, positive adds stock.</summary> /// <summary>Signed base-UOM delta: negative consumes FIFO layers, positive adds stock.</summary>
public decimal QtyDelta { get; set; } public decimal QtyDelta { get; set; }
} }
public sealed class CreateAdjustmentRequest public sealed class CreateAdjustmentRequest
{ {
[Required] public long WarehouseId { get; set; } [Required] public int WarehouseId { get; set; }
/// <summary>Nullable so an omitted value is a distinct <c>REASON_CODE_REQUIRED</c> error, not 0.</summary> /// <summary>Nullable so an omitted value is a distinct <c>REASON_CODE_REQUIRED</c> error, not 0.</summary>
public long? ReasonCodeId { get; set; } public int? ReasonCodeId { get; set; }
[Required, MinLength(1)] public List<CreateAdjustmentLineInput> Lines { get; set; } = new(); [Required, MinLength(1)] public List<CreateAdjustmentLineInput> Lines { get; set; } = new();
} }
+6 -6
View File
@@ -5,25 +5,25 @@ namespace ERPCore.Dtos.Stock;
// Responses (docs/11 §5.6) ------------------------------------------------------ // Responses (docs/11 §5.6) ------------------------------------------------------
public sealed record CountLineDto(long CountLineId, long ItemId, long? BinId, decimal SystemQty, decimal? CountedQty, decimal? Variance); public sealed record CountLineDto(int CountLineId, int ItemId, int? BinId, decimal SystemQty, decimal? CountedQty, decimal? Variance);
public sealed record CountDto( public sealed record CountDto(
long CountId, string DocNo, long WarehouseId, CountType CountType, CountStatus Status, IReadOnlyList<CountLineDto> Lines); int CountId, string DocNo, int WarehouseId, CountType CountType, CountStatus Status, IReadOnlyList<CountLineDto> Lines);
public sealed record CountPostResultDto(long CountId, CountStatus Status, long? AdjustmentId, IReadOnlyList<long> LedgerRefs); public sealed record CountPostResultDto(int CountId, CountStatus Status, int? AdjustmentId, IReadOnlyList<int> LedgerRefs);
// Requests ---------------------------------------------------------------------- // Requests ----------------------------------------------------------------------
public sealed class CreateCountRequest public sealed class CreateCountRequest
{ {
[Required] public long WarehouseId { get; set; } [Required] public int WarehouseId { get; set; }
[Required, EnumDataType(typeof(CountType))] public CountType CountType { get; set; } [Required, EnumDataType(typeof(CountType))] public CountType CountType { get; set; }
[Required, MinLength(1)] public List<long> ItemIds { get; set; } = new(); [Required, MinLength(1)] public List<int> ItemIds { get; set; } = new();
} }
public sealed class EnterCountLineInput public sealed class EnterCountLineInput
{ {
[Required] public long CountLineId { get; set; } [Required] public int CountLineId { get; set; }
[Range(0, double.MaxValue)] public decimal CountedQty { get; set; } [Range(0, double.MaxValue)] public decimal CountedQty { get; set; }
} }
+1 -1
View File
@@ -2,5 +2,5 @@ namespace ERPCore.Dtos.Stock;
/// <summary>An item at/below its reorder point (docs/11 §5.7; FR-STK-10). Computed on read.</summary> /// <summary>An item at/below its reorder point (docs/11 §5.7; FR-STK-10). Computed on read.</summary>
public sealed record ReorderAlertDto( public sealed record ReorderAlertDto(
long ItemId, long WarehouseId, decimal Available, int ItemId, int WarehouseId, decimal Available,
decimal ReorderPoint, decimal ReorderQty, decimal SuggestedRequisitionQty); decimal ReorderPoint, decimal ReorderQty, decimal SuggestedRequisitionQty);
+5 -5
View File
@@ -4,19 +4,19 @@ namespace ERPCore.Dtos.Stock;
/// <summary>Stock enquiry (docs/11 §5.1). available = onHand onHold reserved inTransit(out).</summary> /// <summary>Stock enquiry (docs/11 §5.1). available = onHand onHold reserved inTransit(out).</summary>
public sealed record StockOnHandDto( public sealed record StockOnHandDto(
long ItemId, long WarehouseId, decimal OnHand, decimal Available, int ItemId, int WarehouseId, decimal OnHand, decimal Available,
decimal OnHold, decimal InTransit, decimal Reserved, DateTime AsOf); decimal OnHold, decimal InTransit, decimal Reserved, DateTime AsOf);
/// <summary>A stock-ledger row (docs/11 §5.2).</summary> /// <summary>A stock-ledger row (docs/11 §5.2).</summary>
public sealed record StockLedgerRowDto( public sealed record StockLedgerRowDto(
long LedgerId, long ItemId, long WarehouseId, long? BinId, long? BatchId, long? SerialId, int LedgerId, int ItemId, int WarehouseId, int? BinId, int? BatchId, int? SerialId,
Direction Direction, decimal QtyBase, decimal UnitCost, decimal Value, decimal RunningBalance, Direction Direction, decimal QtyBase, decimal UnitCost, decimal Value, decimal RunningBalance,
string SourceDocType, long SourceDocId, long UserId, DateTime CreatedAt); string SourceDocType, int SourceDocId, int UserId, DateTime CreatedAt);
/// <summary>An open FIFO layer in a valuation (docs/11 §5.3).</summary> /// <summary>An open FIFO layer in a valuation (docs/11 §5.3).</summary>
public sealed record StockValuationLayerDto(long LayerId, decimal QtyRemaining, decimal UnitCost, decimal Value, DateTime ReceiptDate); public sealed record StockValuationLayerDto(int LayerId, decimal QtyRemaining, decimal UnitCost, decimal Value, DateTime ReceiptDate);
/// <summary>Valuation of on-hand stock from open FIFO layers (docs/11 §5.3).</summary> /// <summary>Valuation of on-hand stock from open FIFO layers (docs/11 §5.3).</summary>
public sealed record StockValuationDto( public sealed record StockValuationDto(
long ItemId, long WarehouseId, IReadOnlyList<StockValuationLayerDto> Layers, int ItemId, int WarehouseId, IReadOnlyList<StockValuationLayerDto> Layers,
decimal TotalQty, decimal TotalValue, string Currency, string CostingMethod); decimal TotalQty, decimal TotalValue, string Currency, string CostingMethod);
+13 -13
View File
@@ -6,43 +6,43 @@ namespace ERPCore.Dtos.Stock;
// Responses (docs/11 §5.4) ------------------------------------------------------ // Responses (docs/11 §5.4) ------------------------------------------------------
public sealed record TransferLineDto( public sealed record TransferLineDto(
long TransferLineId, long ItemId, long? SrcBinId, long? DestBinId, long? BatchId, decimal Qty, decimal QtyReceived); int TransferLineId, int ItemId, int? SrcBinId, int? DestBinId, int? BatchId, decimal Qty, decimal QtyReceived);
public sealed record TransferDto( public sealed record TransferDto(
long TransferId, string DocNo, long SrcWarehouseId, long DestWarehouseId, int TransferId, string DocNo, int SrcWarehouseId, int DestWarehouseId,
TransferStatus Status, IReadOnlyList<TransferLineDto> Lines); TransferStatus Status, IReadOnlyList<TransferLineDto> Lines);
public sealed record ConsumedLayerDto(long LayerId, decimal QtyConsumed, decimal UnitCost); public sealed record ConsumedLayerDto(int LayerId, decimal QtyConsumed, decimal UnitCost);
public sealed record DispatchResultDto( public sealed record DispatchResultDto(
long TransferId, TransferStatus Status, IReadOnlyList<ConsumedLayerDto> ConsumedLayers, IReadOnlyList<long> LedgerRefs); int TransferId, TransferStatus Status, IReadOnlyList<ConsumedLayerDto> ConsumedLayers, IReadOnlyList<int> LedgerRefs);
public sealed record TransferCreatedLayerDto(long LayerId, long WarehouseId, decimal QtyReceived, decimal UnitCost); public sealed record TransferCreatedLayerDto(int LayerId, int WarehouseId, decimal QtyReceived, decimal UnitCost);
public sealed record ReceiveResultDto( public sealed record ReceiveResultDto(
long TransferId, TransferStatus Status, IReadOnlyList<TransferCreatedLayerDto> CreatedLayers, IReadOnlyList<long> LedgerRefs); int TransferId, TransferStatus Status, IReadOnlyList<TransferCreatedLayerDto> CreatedLayers, IReadOnlyList<int> LedgerRefs);
// Requests ---------------------------------------------------------------------- // Requests ----------------------------------------------------------------------
public sealed class CreateTransferLineInput public sealed class CreateTransferLineInput
{ {
[Required] public long ItemId { get; set; } [Required] public int ItemId { get; set; }
public long? SrcBinId { get; set; } public int? SrcBinId { get; set; }
public long? DestBinId { get; set; } public int? DestBinId { get; set; }
public long? BatchId { get; set; } public int? BatchId { get; set; }
[Range(0.0001, double.MaxValue)] public decimal Qty { get; set; } [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; }
} }
public sealed class CreateTransferRequest public sealed class CreateTransferRequest
{ {
[Required] public long SrcWarehouseId { get; set; } [Required] public int SrcWarehouseId { get; set; }
[Required] public long DestWarehouseId { get; set; } [Required] public int DestWarehouseId { get; set; }
[Required, MinLength(1)] public List<CreateTransferLineInput> Lines { get; set; } = new(); [Required, MinLength(1)] public List<CreateTransferLineInput> Lines { get; set; } = new();
} }
public sealed class ReceiveTransferLineInput public sealed class ReceiveTransferLineInput
{ {
[Required] public long TransferLineId { get; set; } [Required] public int TransferLineId { get; set; }
[Range(0.0001, double.MaxValue)] public decimal Qty { get; set; } [Range(0.0001, double.MaxValue)] public decimal Qty { get; set; }
} }
+1 -1
View File
@@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations;
namespace ERPCore.Dtos.Uoms; namespace ERPCore.Dtos.Uoms;
/// <summary>UOM resource (docs/11-BACKEND-PHASE1.md §2.2).</summary> /// <summary>UOM resource (docs/11-BACKEND-PHASE1.md §2.2).</summary>
public sealed record UomDto(long UomId, string Name); public sealed record UomDto(int UomId, string Name);
public sealed class CreateUomRequest public sealed class CreateUomRequest
{ {
+1 -1
View File
@@ -5,7 +5,7 @@ namespace ERPCore.Dtos.Vendors;
/// <summary>Vendor resource (docs/11-BACKEND-PHASE1.md §2.4).</summary> /// <summary>Vendor resource (docs/11-BACKEND-PHASE1.md §2.4).</summary>
public sealed record VendorDto( public sealed record VendorDto(
long VendorId, string Code, string Name, string? Terms, string? TaxReg, int VendorId, string Code, string Name, string? Terms, string? TaxReg,
string Currency, EntityStatus Status, DateTime CreatedAt, DateTime? UpdatedAt); string Currency, EntityStatus Status, DateTime CreatedAt, DateTime? UpdatedAt);
public sealed class CreateVendorRequest public sealed class CreateVendorRequest
@@ -3,10 +3,10 @@ using System.ComponentModel.DataAnnotations;
namespace ERPCore.Dtos.Warehouses; namespace ERPCore.Dtos.Warehouses;
/// <summary>Warehouse resource (docs/11-BACKEND-PHASE1.md §2.5).</summary> /// <summary>Warehouse resource (docs/11-BACKEND-PHASE1.md §2.5).</summary>
public sealed record WarehouseDto(long WarehouseId, string Code, string Name); public sealed record WarehouseDto(int WarehouseId, string Code, string Name);
/// <summary>Bin/location resource (docs/11 §2.5).</summary> /// <summary>Bin/location resource (docs/11 §2.5).</summary>
public sealed record BinDto(long BinId, long WarehouseId, string Code, string? BinType); public sealed record BinDto(int BinId, int WarehouseId, string Code, string? BinType);
public sealed class CreateWarehouseRequest public sealed class CreateWarehouseRequest
{ {
+1 -1
View File
@@ -30,5 +30,5 @@ public sealed class CurrentUser : ICurrentUser
} }
} }
public long AuditUserId => long.TryParse(UserId, out var id) ? id : User.SystemUserId; public int AuditUserId => int.TryParse(UserId, out var id) ? id : User.SystemUserId;
} }
+1 -1
View File
@@ -15,7 +15,7 @@ public interface ICurrentUser
/// Resolves the token <c>sub</c> to a user id; falls back to the seeded system /// Resolves the token <c>sub</c> to a user id; falls back to the seeded system
/// user (<see cref="Entities.User.SystemUserId"/>) while auth is deferred (§6). /// user (<see cref="Entities.User.SystemUserId"/>) while auth is deferred (§6).
/// </summary> /// </summary>
long AuditUserId { get; } int AuditUserId { get; }
/// <summary>True when the request carries an authenticated principal.</summary> /// <summary>True when the request carries an authenticated principal.</summary>
bool IsAuthenticated { get; } bool IsAuthenticated { get; }
@@ -12,7 +12,7 @@ namespace ERPCore.Infra.Auth;
/// AuthHex tokens carry the user as a custom <c>UserId</c> (GUID) claim and no /// AuthHex tokens carry the user as a custom <c>UserId</c> (GUID) claim and no
/// <c>sub</c>/<c>nameid</c>. This transformation JIT-provisions a local shadow /// <c>sub</c>/<c>nameid</c>. This transformation JIT-provisions a local shadow
/// <see cref="User"/> (keyed by <c>auth_user_id</c>) and injects the local /// <see cref="User"/> (keyed by <c>auth_user_id</c>) and injects the local
/// <c>long</c> id as <see cref="ClaimTypes.NameIdentifier"/>, so /// <c>int</c> id as <see cref="ClaimTypes.NameIdentifier"/>, so
/// <see cref="ICurrentUser"/>/<c>AuditUserId</c> resolve the real user unchanged. /// <see cref="ICurrentUser"/>/<c>AuditUserId</c> resolve the real user unchanged.
/// Idempotent — <see cref="IClaimsTransformation"/> may run several times per request. /// Idempotent — <see cref="IClaimsTransformation"/> may run several times per request.
/// </summary> /// </summary>
@@ -40,7 +40,7 @@ public sealed class ShadowUserClaimsTransformation : IClaimsTransformation
return principal; return principal;
} }
private async Task<long> ResolveOrProvisionAsync(Guid authUserId, string? nic) private async Task<int> ResolveOrProvisionAsync(Guid authUserId, string? nic)
{ {
var existing = await _db.Users.AsNoTracking() var existing = await _db.Users.AsNoTracking()
.Where(u => u.AuthUserId == authUserId) .Where(u => u.AuthUserId == authUserId)
@@ -8,7 +8,7 @@ using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace ERPCore.Infra.Persistence.Auditing; namespace ERPCore.Infra.Persistence.Auditing;
/// <summary>A mutation captured before save, awaiting its (possibly generated) key.</summary> /// <summary>A mutation captured before save, awaiting its (possibly generated) key.</summary>
public sealed record PendingAudit(EntityEntry Entry, string EntityType, AuditAction Action, string ChangeSet, long CapturedId, bool IsAdded); public sealed record PendingAudit(EntityEntry Entry, string EntityType, AuditAction Action, string ChangeSet, int CapturedId, bool IsAdded);
/// <summary> /// <summary>
/// Builds audit-trail rows from the EF change tracker (FR-X-02). High-volume / /// Builds audit-trail rows from the EF change tracker (FR-X-02). High-volume /
@@ -54,7 +54,7 @@ public static class AuditScribe
return pending; return pending;
} }
public static AuditLog ToLog(PendingAudit p, long userId, DateTime now) => new() public static AuditLog ToLog(PendingAudit p, int userId, DateTime now) => new()
{ {
UserId = userId, UserId = userId,
EntityType = p.EntityType, EntityType = p.EntityType,
@@ -64,12 +64,12 @@ public static class AuditScribe
CreatedAt = now, CreatedAt = now,
}; };
private static long ReadKey(EntityEntry entry) private static int ReadKey(EntityEntry entry)
{ {
var pk = entry.Metadata.FindPrimaryKey(); var pk = entry.Metadata.FindPrimaryKey();
if (pk is null || pk.Properties.Count != 1) return 0; if (pk is null || pk.Properties.Count != 1) return 0;
var value = entry.Property(pk.Properties[0].Name).CurrentValue; var value = entry.Property(pk.Properties[0].Name).CurrentValue;
return value is null ? 0 : Convert.ToInt64(value); return value is null ? 0 : Convert.ToInt32(value);
} }
private static string BuildChangeSet(EntityEntry entry, AuditAction action) private static string BuildChangeSet(EntityEntry entry, AuditAction action)
@@ -1,445 +0,0 @@
// <auto-generated />
using System;
using ERPCore.Infra.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
[DbContext(typeof(ErpDbContext))]
[Migration("20260709095653_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b =>
{
b.Property<long>("BinId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("BinId"));
b.Property<string>("BinType")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<long>("WarehouseId")
.HasColumnType("bigint");
b.HasKey("BinId");
b.HasIndex("WarehouseId", "Code")
.IsUnique();
b.ToTable("bins", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.Property<long>("CategoryId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("CategoryId"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<long?>("ParentId")
.HasColumnType("bigint");
b.HasKey("CategoryId");
b.HasIndex("ParentId");
b.ToTable("categories", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.Property<long>("ItemId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ItemId"));
b.Property<long>("BaseUomId")
.HasColumnType("bigint");
b.Property<long>("CategoryId")
.HasColumnType("bigint");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<long?>("DefaultVendorId")
.HasColumnType("bigint");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)");
b.Property<string>("ItemType")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Sku")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Active");
b.Property<string>("TaxClass")
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("TrackingMode")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("ItemId");
b.HasIndex("BaseUomId");
b.HasIndex("CategoryId");
b.HasIndex("DefaultVendorId");
b.HasIndex("Sku")
.IsUnique();
b.HasIndex("Status");
b.ToTable("items", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b =>
{
b.Property<long>("ReorderId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ReorderId"));
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<decimal>("ReorderPoint")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("ReorderQty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<long>("WarehouseId")
.HasColumnType("bigint");
b.HasKey("ReorderId");
b.HasIndex("WarehouseId");
b.HasIndex("ItemId", "WarehouseId")
.IsUnique();
b.ToTable("item_reorders", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Uom", b =>
{
b.Property<long>("UomId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("UomId"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("UomId");
b.HasIndex("Name")
.IsUnique();
b.ToTable("uoms", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b =>
{
b.Property<long>("ConversionId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ConversionId"));
b.Property<decimal>("Factor")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<long>("FromUomId")
.HasColumnType("bigint");
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<long>("ToUomId")
.HasColumnType("bigint");
b.HasKey("ConversionId");
b.HasIndex("FromUomId");
b.HasIndex("ToUomId");
b.HasIndex("ItemId", "FromUomId", "ToUomId")
.IsUnique();
b.ToTable("uom_conversions", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Vendor", b =>
{
b.Property<long>("VendorId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("VendorId"));
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<string>("Currency")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(3)
.HasColumnType("character varying(3)")
.HasDefaultValue("LKR");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Active");
b.Property<string>("TaxReg")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Terms")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("VendorId");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("Status");
b.ToTable("vendors", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b =>
{
b.Property<long>("WarehouseId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("WarehouseId"));
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.HasKey("WarehouseId");
b.HasIndex("Code")
.IsUnique();
b.ToTable("warehouses", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b =>
{
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany("Bins")
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.HasOne("ERPCore.Domain.Entities.Category", "Parent")
.WithMany("Children")
.HasForeignKey("ParentId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Parent");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.HasOne("ERPCore.Domain.Entities.Uom", "BaseUom")
.WithMany()
.HasForeignKey("BaseUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Category", "Category")
.WithMany()
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Vendor", "DefaultVendor")
.WithMany()
.HasForeignKey("DefaultVendorId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("BaseUom");
b.Navigation("Category");
b.Navigation("DefaultVendor");
});
modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany("ReorderSettings")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany()
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Item");
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b =>
{
b.HasOne("ERPCore.Domain.Entities.Uom", "FromUom")
.WithMany()
.HasForeignKey("FromUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany("UomConversions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Uom", "ToUom")
.WithMany()
.HasForeignKey("ToUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("FromUom");
b.Navigation("Item");
b.Navigation("ToUom");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.Navigation("Children");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.Navigation("ReorderSettings");
b.Navigation("UomConversions");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b =>
{
b.Navigation("Bins");
});
#pragma warning restore 612, 618
}
}
}
@@ -1,325 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "categories",
columns: table => new
{
CategoryId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
ParentId = table.Column<long>(type: "bigint", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_categories", x => x.CategoryId);
table.ForeignKey(
name: "FK_categories_categories_ParentId",
column: x => x.ParentId,
principalTable: "categories",
principalColumn: "CategoryId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "uoms",
columns: table => new
{
UomId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_uoms", x => x.UomId);
});
migrationBuilder.CreateTable(
name: "vendors",
columns: table => new
{
VendorId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Code = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
Terms = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
TaxReg = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
Currency = table.Column<string>(type: "character varying(3)", maxLength: 3, nullable: false, defaultValue: "LKR"),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Active"),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
xmin = table.Column<uint>(type: "xid", rowVersion: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_vendors", x => x.VendorId);
});
migrationBuilder.CreateTable(
name: "warehouses",
columns: table => new
{
WarehouseId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Code = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_warehouses", x => x.WarehouseId);
});
migrationBuilder.CreateTable(
name: "items",
columns: table => new
{
ItemId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Sku = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
Description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
CategoryId = table.Column<long>(type: "bigint", nullable: false),
BaseUomId = table.Column<long>(type: "bigint", nullable: false),
DefaultVendorId = table.Column<long>(type: "bigint", nullable: true),
ItemType = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
TrackingMode = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
TaxClass = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false, defaultValue: "Active"),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
xmin = table.Column<uint>(type: "xid", rowVersion: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_items", x => x.ItemId);
table.ForeignKey(
name: "FK_items_categories_CategoryId",
column: x => x.CategoryId,
principalTable: "categories",
principalColumn: "CategoryId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_items_uoms_BaseUomId",
column: x => x.BaseUomId,
principalTable: "uoms",
principalColumn: "UomId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_items_vendors_DefaultVendorId",
column: x => x.DefaultVendorId,
principalTable: "vendors",
principalColumn: "VendorId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "bins",
columns: table => new
{
BinId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
Code = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
BinType = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_bins", x => x.BinId);
table.ForeignKey(
name: "FK_bins_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "item_reorders",
columns: table => new
{
ReorderId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ItemId = table.Column<long>(type: "bigint", nullable: false),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
ReorderPoint = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
ReorderQty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_item_reorders", x => x.ReorderId);
table.ForeignKey(
name: "FK_item_reorders_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_item_reorders_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "uom_conversions",
columns: table => new
{
ConversionId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ItemId = table.Column<long>(type: "bigint", nullable: false),
FromUomId = table.Column<long>(type: "bigint", nullable: false),
ToUomId = table.Column<long>(type: "bigint", nullable: false),
Factor = table.Column<decimal>(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_uom_conversions", x => x.ConversionId);
table.ForeignKey(
name: "FK_uom_conversions_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_uom_conversions_uoms_FromUomId",
column: x => x.FromUomId,
principalTable: "uoms",
principalColumn: "UomId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_uom_conversions_uoms_ToUomId",
column: x => x.ToUomId,
principalTable: "uoms",
principalColumn: "UomId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_bins_WarehouseId_Code",
table: "bins",
columns: new[] { "WarehouseId", "Code" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_categories_ParentId",
table: "categories",
column: "ParentId");
migrationBuilder.CreateIndex(
name: "IX_item_reorders_ItemId_WarehouseId",
table: "item_reorders",
columns: new[] { "ItemId", "WarehouseId" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_item_reorders_WarehouseId",
table: "item_reorders",
column: "WarehouseId");
migrationBuilder.CreateIndex(
name: "IX_items_BaseUomId",
table: "items",
column: "BaseUomId");
migrationBuilder.CreateIndex(
name: "IX_items_CategoryId",
table: "items",
column: "CategoryId");
migrationBuilder.CreateIndex(
name: "IX_items_DefaultVendorId",
table: "items",
column: "DefaultVendorId");
migrationBuilder.CreateIndex(
name: "IX_items_Sku",
table: "items",
column: "Sku",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_items_Status",
table: "items",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_uom_conversions_FromUomId",
table: "uom_conversions",
column: "FromUomId");
migrationBuilder.CreateIndex(
name: "IX_uom_conversions_ItemId_FromUomId_ToUomId",
table: "uom_conversions",
columns: new[] { "ItemId", "FromUomId", "ToUomId" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_uom_conversions_ToUomId",
table: "uom_conversions",
column: "ToUomId");
migrationBuilder.CreateIndex(
name: "IX_uoms_Name",
table: "uoms",
column: "Name",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_vendors_Code",
table: "vendors",
column: "Code",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_vendors_Status",
table: "vendors",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_warehouses_Code",
table: "warehouses",
column: "Code",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "bins");
migrationBuilder.DropTable(
name: "item_reorders");
migrationBuilder.DropTable(
name: "uom_conversions");
migrationBuilder.DropTable(
name: "warehouses");
migrationBuilder.DropTable(
name: "items");
migrationBuilder.DropTable(
name: "categories");
migrationBuilder.DropTable(
name: "uoms");
migrationBuilder.DropTable(
name: "vendors");
}
}
}
@@ -1,445 +0,0 @@
// <auto-generated />
using System;
using ERPCore.Infra.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
[DbContext(typeof(ErpDbContext))]
[Migration("20260709124415_initial")]
partial class initial
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b =>
{
b.Property<long>("BinId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("BinId"));
b.Property<string>("BinType")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<long>("WarehouseId")
.HasColumnType("bigint");
b.HasKey("BinId");
b.HasIndex("WarehouseId", "Code")
.IsUnique();
b.ToTable("bins", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.Property<long>("CategoryId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("CategoryId"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<long?>("ParentId")
.HasColumnType("bigint");
b.HasKey("CategoryId");
b.HasIndex("ParentId");
b.ToTable("categories", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.Property<long>("ItemId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ItemId"));
b.Property<long>("BaseUomId")
.HasColumnType("bigint");
b.Property<long>("CategoryId")
.HasColumnType("bigint");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<long?>("DefaultVendorId")
.HasColumnType("bigint");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)");
b.Property<string>("ItemType")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Sku")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Active");
b.Property<string>("TaxClass")
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("TrackingMode")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("ItemId");
b.HasIndex("BaseUomId");
b.HasIndex("CategoryId");
b.HasIndex("DefaultVendorId");
b.HasIndex("Sku")
.IsUnique();
b.HasIndex("Status");
b.ToTable("items", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b =>
{
b.Property<long>("ReorderId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ReorderId"));
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<decimal>("ReorderPoint")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("ReorderQty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<long>("WarehouseId")
.HasColumnType("bigint");
b.HasKey("ReorderId");
b.HasIndex("WarehouseId");
b.HasIndex("ItemId", "WarehouseId")
.IsUnique();
b.ToTable("item_reorders", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Uom", b =>
{
b.Property<long>("UomId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("UomId"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("UomId");
b.HasIndex("Name")
.IsUnique();
b.ToTable("uoms", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b =>
{
b.Property<long>("ConversionId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ConversionId"));
b.Property<decimal>("Factor")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<long>("FromUomId")
.HasColumnType("bigint");
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<long>("ToUomId")
.HasColumnType("bigint");
b.HasKey("ConversionId");
b.HasIndex("FromUomId");
b.HasIndex("ToUomId");
b.HasIndex("ItemId", "FromUomId", "ToUomId")
.IsUnique();
b.ToTable("uom_conversions", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Vendor", b =>
{
b.Property<long>("VendorId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("VendorId"));
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<string>("Currency")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(3)
.HasColumnType("character varying(3)")
.HasDefaultValue("LKR");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Active");
b.Property<string>("TaxReg")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Terms")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("VendorId");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("Status");
b.ToTable("vendors", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b =>
{
b.Property<long>("WarehouseId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("WarehouseId"));
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.HasKey("WarehouseId");
b.HasIndex("Code")
.IsUnique();
b.ToTable("warehouses", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b =>
{
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany("Bins")
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.HasOne("ERPCore.Domain.Entities.Category", "Parent")
.WithMany("Children")
.HasForeignKey("ParentId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Parent");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.HasOne("ERPCore.Domain.Entities.Uom", "BaseUom")
.WithMany()
.HasForeignKey("BaseUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Category", "Category")
.WithMany()
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Vendor", "DefaultVendor")
.WithMany()
.HasForeignKey("DefaultVendorId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("BaseUom");
b.Navigation("Category");
b.Navigation("DefaultVendor");
});
modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany("ReorderSettings")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany()
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Item");
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b =>
{
b.HasOne("ERPCore.Domain.Entities.Uom", "FromUom")
.WithMany()
.HasForeignKey("FromUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany("UomConversions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Uom", "ToUom")
.WithMany()
.HasForeignKey("ToUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("FromUom");
b.Navigation("Item");
b.Navigation("ToUom");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.Navigation("Children");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.Navigation("ReorderSettings");
b.Navigation("UomConversions");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b =>
{
b.Navigation("Bins");
});
#pragma warning restore 612, 618
}
}
}
@@ -1,22 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
/// <inheritdoc />
public partial class initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
@@ -1,987 +0,0 @@
// <auto-generated />
using System;
using ERPCore.Infra.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
[DbContext(typeof(ErpDbContext))]
[Migration("20260710090753_AddProcurement")]
partial class AddProcurement
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b =>
{
b.Property<long>("BinId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("BinId"));
b.Property<string>("BinType")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<long>("WarehouseId")
.HasColumnType("bigint");
b.HasKey("BinId");
b.HasIndex("WarehouseId", "Code")
.IsUnique();
b.ToTable("bins", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.Property<long>("CategoryId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("CategoryId"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<long?>("ParentId")
.HasColumnType("bigint");
b.HasKey("CategoryId");
b.HasIndex("ParentId");
b.ToTable("categories", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.Property<long>("ItemId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ItemId"));
b.Property<long>("BaseUomId")
.HasColumnType("bigint");
b.Property<long>("CategoryId")
.HasColumnType("bigint");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<long?>("DefaultVendorId")
.HasColumnType("bigint");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)");
b.Property<string>("ItemType")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Sku")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Active");
b.Property<string>("TaxClass")
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("TrackingMode")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("ItemId");
b.HasIndex("BaseUomId");
b.HasIndex("CategoryId");
b.HasIndex("DefaultVendorId");
b.HasIndex("Sku")
.IsUnique();
b.HasIndex("Status");
b.ToTable("items", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b =>
{
b.Property<long>("ReorderId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ReorderId"));
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<decimal>("ReorderPoint")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("ReorderQty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<long>("WarehouseId")
.HasColumnType("bigint");
b.HasKey("ReorderId");
b.HasIndex("WarehouseId");
b.HasIndex("ItemId", "WarehouseId")
.IsUnique();
b.ToTable("item_reorders", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.NumberSequence", b =>
{
b.Property<long>("SequenceId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("SequenceId"));
b.Property<string>("DocType")
.IsRequired()
.HasMaxLength(10)
.HasColumnType("character varying(10)")
.HasColumnName("doc_type");
b.Property<long>("LastNumber")
.HasColumnType("bigint")
.HasColumnName("last_number");
b.Property<int>("Year")
.HasColumnType("integer")
.HasColumnName("year");
b.HasKey("SequenceId");
b.HasIndex("DocType", "Year")
.IsUnique();
b.ToTable("number_sequences", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.PoLine", b =>
{
b.Property<long>("PoLineId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("PoLineId"));
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<long>("PoId")
.HasColumnType("bigint");
b.Property<decimal>("Qty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("QtyReceived")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<decimal>("Tax")
.HasPrecision(9, 4)
.HasColumnType("numeric(9,4)");
b.Property<decimal>("UnitPrice")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<long>("UomId")
.HasColumnType("bigint");
b.Property<long>("WarehouseId")
.HasColumnType("bigint");
b.HasKey("PoLineId");
b.HasIndex("ItemId");
b.HasIndex("PoId");
b.HasIndex("UomId");
b.HasIndex("WarehouseId");
b.ToTable("po_lines", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b =>
{
b.Property<long>("PoId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("PoId"));
b.Property<bool>("ApprovalRequired")
.HasColumnType("boolean");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<long>("CreatedBy")
.HasColumnType("bigint");
b.Property<string>("DocNo")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("character varying(30)");
b.Property<long?>("RequisitionId")
.HasColumnType("bigint");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.Property<long>("VendorId")
.HasColumnType("bigint");
b.HasKey("PoId");
b.HasIndex("CreatedBy");
b.HasIndex("DocNo")
.IsUnique();
b.HasIndex("RequisitionId");
b.HasIndex("Status");
b.HasIndex("VendorId");
b.ToTable("purchase_orders", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Requisition", b =>
{
b.Property<long>("RequisitionId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("RequisitionId"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<string>("DocNo")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("character varying(30)");
b.Property<long>("RequestedBy")
.HasColumnType("bigint");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.HasKey("RequisitionId");
b.HasIndex("DocNo")
.IsUnique();
b.HasIndex("RequestedBy");
b.HasIndex("Status");
b.ToTable("requisitions", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.RequisitionLine", b =>
{
b.Property<long>("ReqLineId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ReqLineId"));
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<decimal>("Qty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<DateOnly?>("RequiredBy")
.HasColumnType("date");
b.Property<long>("RequisitionId")
.HasColumnType("bigint");
b.HasKey("ReqLineId");
b.HasIndex("ItemId");
b.HasIndex("RequisitionId");
b.ToTable("requisition_lines", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Rfq", b =>
{
b.Property<long>("RfqId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("RfqId"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<string>("DocNo")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("character varying(30)");
b.Property<long>("RequisitionId")
.HasColumnType("bigint");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.HasKey("RfqId");
b.HasIndex("DocNo")
.IsUnique();
b.HasIndex("RequisitionId");
b.ToTable("rfqs", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.RfqLine", b =>
{
b.Property<long>("RfqLineId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("RfqLineId"));
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<decimal>("Qty")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.Property<long>("RfqId")
.HasColumnType("bigint");
b.HasKey("RfqLineId");
b.HasIndex("ItemId");
b.HasIndex("RfqId");
b.ToTable("rfq_lines", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Uom", b =>
{
b.Property<long>("UomId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("UomId"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.HasKey("UomId");
b.HasIndex("Name")
.IsUnique();
b.ToTable("uoms", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b =>
{
b.Property<long>("ConversionId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("ConversionId"));
b.Property<decimal>("Factor")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<long>("FromUomId")
.HasColumnType("bigint");
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<long>("ToUomId")
.HasColumnType("bigint");
b.HasKey("ConversionId");
b.HasIndex("FromUomId");
b.HasIndex("ToUomId");
b.HasIndex("ItemId", "FromUomId", "ToUomId")
.IsUnique();
b.ToTable("uom_conversions", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.User", b =>
{
b.Property<long>("UserId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("UserId"));
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("Username")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.HasKey("UserId");
b.HasIndex("Username")
.IsUnique();
b.ToTable("users", (string)null);
b.HasData(
new
{
UserId = 1L,
DisplayName = "System",
Status = "Active",
Username = "system"
});
});
modelBuilder.Entity("ERPCore.Domain.Entities.Vendor", b =>
{
b.Property<long>("VendorId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("VendorId"));
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<string>("Currency")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(3)
.HasColumnType("character varying(3)")
.HasDefaultValue("LKR");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.Property<uint>("RowVersion")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.Property<string>("Status")
.IsRequired()
.ValueGeneratedOnAdd()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasDefaultValue("Active");
b.Property<string>("TaxReg")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Terms")
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<DateTime?>("UpdatedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("VendorId");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("Status");
b.ToTable("vendors", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b =>
{
b.Property<long>("QuotationId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("QuotationId"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<long>("RfqId")
.HasColumnType("bigint");
b.Property<long>("VendorId")
.HasColumnType("bigint");
b.HasKey("QuotationId");
b.HasIndex("VendorId");
b.HasIndex("RfqId", "VendorId")
.IsUnique();
b.ToTable("vendor_quotations", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotationLine", b =>
{
b.Property<long>("QuotationLineId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("QuotationLineId"));
b.Property<long>("ItemId")
.HasColumnType("bigint");
b.Property<int>("LeadDays")
.HasColumnType("integer");
b.Property<long>("QuotationId")
.HasColumnType("bigint");
b.Property<decimal>("UnitPrice")
.HasPrecision(18, 4)
.HasColumnType("numeric(18,4)");
b.HasKey("QuotationLineId");
b.HasIndex("ItemId");
b.HasIndex("QuotationId");
b.ToTable("vendor_quotation_lines", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b =>
{
b.Property<long>("WarehouseId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("WarehouseId"));
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)");
b.HasKey("WarehouseId");
b.HasIndex("Code")
.IsUnique();
b.ToTable("warehouses", (string)null);
});
modelBuilder.Entity("ERPCore.Domain.Entities.Bin", b =>
{
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany("Bins")
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.HasOne("ERPCore.Domain.Entities.Category", "Parent")
.WithMany("Children")
.HasForeignKey("ParentId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Parent");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.HasOne("ERPCore.Domain.Entities.Uom", "BaseUom")
.WithMany()
.HasForeignKey("BaseUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Category", "Category")
.WithMany()
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Vendor", "DefaultVendor")
.WithMany()
.HasForeignKey("DefaultVendorId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("BaseUom");
b.Navigation("Category");
b.Navigation("DefaultVendor");
});
modelBuilder.Entity("ERPCore.Domain.Entities.ItemReorder", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany("ReorderSettings")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany()
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Item");
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.PoLine", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany()
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.PurchaseOrder", "PurchaseOrder")
.WithMany("Lines")
.HasForeignKey("PoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Uom", "Uom")
.WithMany()
.HasForeignKey("UomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Warehouse", "Warehouse")
.WithMany()
.HasForeignKey("WarehouseId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Item");
b.Navigation("PurchaseOrder");
b.Navigation("Uom");
b.Navigation("Warehouse");
});
modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b =>
{
b.HasOne("ERPCore.Domain.Entities.User", "Creator")
.WithMany()
.HasForeignKey("CreatedBy")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition")
.WithMany()
.HasForeignKey("RequisitionId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor")
.WithMany()
.HasForeignKey("VendorId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Creator");
b.Navigation("Requisition");
b.Navigation("Vendor");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Requisition", b =>
{
b.HasOne("ERPCore.Domain.Entities.User", "Requester")
.WithMany()
.HasForeignKey("RequestedBy")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Requester");
});
modelBuilder.Entity("ERPCore.Domain.Entities.RequisitionLine", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany()
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition")
.WithMany("Lines")
.HasForeignKey("RequisitionId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Item");
b.Navigation("Requisition");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Rfq", b =>
{
b.HasOne("ERPCore.Domain.Entities.Requisition", "Requisition")
.WithMany()
.HasForeignKey("RequisitionId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Requisition");
});
modelBuilder.Entity("ERPCore.Domain.Entities.RfqLine", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany()
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Rfq", "Rfq")
.WithMany("Lines")
.HasForeignKey("RfqId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Item");
b.Navigation("Rfq");
});
modelBuilder.Entity("ERPCore.Domain.Entities.UomConversion", b =>
{
b.HasOne("ERPCore.Domain.Entities.Uom", "FromUom")
.WithMany()
.HasForeignKey("FromUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany("UomConversions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Uom", "ToUom")
.WithMany()
.HasForeignKey("ToUomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("FromUom");
b.Navigation("Item");
b.Navigation("ToUom");
});
modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b =>
{
b.HasOne("ERPCore.Domain.Entities.Rfq", "Rfq")
.WithMany("Quotations")
.HasForeignKey("RfqId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.Vendor", "Vendor")
.WithMany()
.HasForeignKey("VendorId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Rfq");
b.Navigation("Vendor");
});
modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotationLine", b =>
{
b.HasOne("ERPCore.Domain.Entities.Item", "Item")
.WithMany()
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("ERPCore.Domain.Entities.VendorQuotation", "Quotation")
.WithMany("Lines")
.HasForeignKey("QuotationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Item");
b.Navigation("Quotation");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Category", b =>
{
b.Navigation("Children");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Item", b =>
{
b.Navigation("ReorderSettings");
b.Navigation("UomConversions");
});
modelBuilder.Entity("ERPCore.Domain.Entities.PurchaseOrder", b =>
{
b.Navigation("Lines");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Requisition", b =>
{
b.Navigation("Lines");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Rfq", b =>
{
b.Navigation("Lines");
b.Navigation("Quotations");
});
modelBuilder.Entity("ERPCore.Domain.Entities.VendorQuotation", b =>
{
b.Navigation("Lines");
});
modelBuilder.Entity("ERPCore.Domain.Entities.Warehouse", b =>
{
b.Navigation("Bins");
});
#pragma warning restore 612, 618
}
}
}
@@ -1,448 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddProcurement : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "number_sequences",
columns: table => new
{
SequenceId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
doc_type = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: false),
year = table.Column<int>(type: "integer", nullable: false),
last_number = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_number_sequences", x => x.SequenceId);
});
migrationBuilder.CreateTable(
name: "users",
columns: table => new
{
UserId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Username = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
DisplayName = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_users", x => x.UserId);
});
migrationBuilder.CreateTable(
name: "requisitions",
columns: table => new
{
RequisitionId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DocNo = table.Column<string>(type: "character varying(30)", maxLength: 30, nullable: false),
RequestedBy = table.Column<long>(type: "bigint", nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_requisitions", x => x.RequisitionId);
table.ForeignKey(
name: "FK_requisitions_users_RequestedBy",
column: x => x.RequestedBy,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "purchase_orders",
columns: table => new
{
PoId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DocNo = table.Column<string>(type: "character varying(30)", maxLength: 30, nullable: false),
VendorId = table.Column<long>(type: "bigint", nullable: false),
RequisitionId = table.Column<long>(type: "bigint", nullable: true),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
ApprovalRequired = table.Column<bool>(type: "boolean", nullable: false),
CreatedBy = table.Column<long>(type: "bigint", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
xmin = table.Column<uint>(type: "xid", rowVersion: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_purchase_orders", x => x.PoId);
table.ForeignKey(
name: "FK_purchase_orders_requisitions_RequisitionId",
column: x => x.RequisitionId,
principalTable: "requisitions",
principalColumn: "RequisitionId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_purchase_orders_users_CreatedBy",
column: x => x.CreatedBy,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_purchase_orders_vendors_VendorId",
column: x => x.VendorId,
principalTable: "vendors",
principalColumn: "VendorId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "requisition_lines",
columns: table => new
{
ReqLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RequisitionId = table.Column<long>(type: "bigint", nullable: false),
ItemId = table.Column<long>(type: "bigint", nullable: false),
Qty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
RequiredBy = table.Column<DateOnly>(type: "date", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_requisition_lines", x => x.ReqLineId);
table.ForeignKey(
name: "FK_requisition_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_requisition_lines_requisitions_RequisitionId",
column: x => x.RequisitionId,
principalTable: "requisitions",
principalColumn: "RequisitionId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "rfqs",
columns: table => new
{
RfqId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DocNo = table.Column<string>(type: "character varying(30)", maxLength: 30, nullable: false),
RequisitionId = table.Column<long>(type: "bigint", nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_rfqs", x => x.RfqId);
table.ForeignKey(
name: "FK_rfqs_requisitions_RequisitionId",
column: x => x.RequisitionId,
principalTable: "requisitions",
principalColumn: "RequisitionId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "po_lines",
columns: table => new
{
PoLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
PoId = table.Column<long>(type: "bigint", nullable: false),
ItemId = table.Column<long>(type: "bigint", nullable: false),
UomId = table.Column<long>(type: "bigint", nullable: false),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
Qty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
UnitPrice = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
Tax = table.Column<decimal>(type: "numeric(9,4)", precision: 9, scale: 4, nullable: false),
QtyReceived = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_po_lines", x => x.PoLineId);
table.ForeignKey(
name: "FK_po_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_po_lines_purchase_orders_PoId",
column: x => x.PoId,
principalTable: "purchase_orders",
principalColumn: "PoId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_po_lines_uoms_UomId",
column: x => x.UomId,
principalTable: "uoms",
principalColumn: "UomId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_po_lines_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "rfq_lines",
columns: table => new
{
RfqLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RfqId = table.Column<long>(type: "bigint", nullable: false),
ItemId = table.Column<long>(type: "bigint", nullable: false),
Qty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_rfq_lines", x => x.RfqLineId);
table.ForeignKey(
name: "FK_rfq_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_rfq_lines_rfqs_RfqId",
column: x => x.RfqId,
principalTable: "rfqs",
principalColumn: "RfqId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "vendor_quotations",
columns: table => new
{
QuotationId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RfqId = table.Column<long>(type: "bigint", nullable: false),
VendorId = table.Column<long>(type: "bigint", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_vendor_quotations", x => x.QuotationId);
table.ForeignKey(
name: "FK_vendor_quotations_rfqs_RfqId",
column: x => x.RfqId,
principalTable: "rfqs",
principalColumn: "RfqId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_vendor_quotations_vendors_VendorId",
column: x => x.VendorId,
principalTable: "vendors",
principalColumn: "VendorId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "vendor_quotation_lines",
columns: table => new
{
QuotationLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
QuotationId = table.Column<long>(type: "bigint", nullable: false),
ItemId = table.Column<long>(type: "bigint", nullable: false),
UnitPrice = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
LeadDays = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_vendor_quotation_lines", x => x.QuotationLineId);
table.ForeignKey(
name: "FK_vendor_quotation_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_vendor_quotation_lines_vendor_quotations_QuotationId",
column: x => x.QuotationId,
principalTable: "vendor_quotations",
principalColumn: "QuotationId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "users",
columns: new[] { "UserId", "DisplayName", "Status", "Username" },
values: new object[] { 1L, "System", "Active", "system" });
migrationBuilder.CreateIndex(
name: "IX_number_sequences_doc_type_year",
table: "number_sequences",
columns: new[] { "doc_type", "year" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_po_lines_ItemId",
table: "po_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_po_lines_PoId",
table: "po_lines",
column: "PoId");
migrationBuilder.CreateIndex(
name: "IX_po_lines_UomId",
table: "po_lines",
column: "UomId");
migrationBuilder.CreateIndex(
name: "IX_po_lines_WarehouseId",
table: "po_lines",
column: "WarehouseId");
migrationBuilder.CreateIndex(
name: "IX_purchase_orders_CreatedBy",
table: "purchase_orders",
column: "CreatedBy");
migrationBuilder.CreateIndex(
name: "IX_purchase_orders_DocNo",
table: "purchase_orders",
column: "DocNo",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_purchase_orders_RequisitionId",
table: "purchase_orders",
column: "RequisitionId");
migrationBuilder.CreateIndex(
name: "IX_purchase_orders_Status",
table: "purchase_orders",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_purchase_orders_VendorId",
table: "purchase_orders",
column: "VendorId");
migrationBuilder.CreateIndex(
name: "IX_requisition_lines_ItemId",
table: "requisition_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_requisition_lines_RequisitionId",
table: "requisition_lines",
column: "RequisitionId");
migrationBuilder.CreateIndex(
name: "IX_requisitions_DocNo",
table: "requisitions",
column: "DocNo",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_requisitions_RequestedBy",
table: "requisitions",
column: "RequestedBy");
migrationBuilder.CreateIndex(
name: "IX_requisitions_Status",
table: "requisitions",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_rfq_lines_ItemId",
table: "rfq_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_rfq_lines_RfqId",
table: "rfq_lines",
column: "RfqId");
migrationBuilder.CreateIndex(
name: "IX_rfqs_DocNo",
table: "rfqs",
column: "DocNo",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_rfqs_RequisitionId",
table: "rfqs",
column: "RequisitionId");
migrationBuilder.CreateIndex(
name: "IX_users_Username",
table: "users",
column: "Username",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_vendor_quotation_lines_ItemId",
table: "vendor_quotation_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_vendor_quotation_lines_QuotationId",
table: "vendor_quotation_lines",
column: "QuotationId");
migrationBuilder.CreateIndex(
name: "IX_vendor_quotations_RfqId_VendorId",
table: "vendor_quotations",
columns: new[] { "RfqId", "VendorId" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_vendor_quotations_VendorId",
table: "vendor_quotations",
column: "VendorId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "number_sequences");
migrationBuilder.DropTable(
name: "po_lines");
migrationBuilder.DropTable(
name: "requisition_lines");
migrationBuilder.DropTable(
name: "rfq_lines");
migrationBuilder.DropTable(
name: "vendor_quotation_lines");
migrationBuilder.DropTable(
name: "purchase_orders");
migrationBuilder.DropTable(
name: "vendor_quotations");
migrationBuilder.DropTable(
name: "rfqs");
migrationBuilder.DropTable(
name: "requisitions");
migrationBuilder.DropTable(
name: "users");
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,434 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddStockAndGrn : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "batches",
columns: table => new
{
BatchId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ItemId = table.Column<long>(type: "bigint", nullable: false),
BatchNo = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
ExpiryDate = table.Column<DateOnly>(type: "date", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_batches", x => x.BatchId);
table.ForeignKey(
name: "FK_batches_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "grns",
columns: table => new
{
GrnId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DocNo = table.Column<string>(type: "character varying(30)", maxLength: 30, nullable: false),
PoId = table.Column<long>(type: "bigint", nullable: true),
VendorId = table.Column<long>(type: "bigint", nullable: false),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreatedBy = table.Column<long>(type: "bigint", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
PostedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
xmin = table.Column<uint>(type: "xid", rowVersion: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_grns", x => x.GrnId);
table.ForeignKey(
name: "FK_grns_purchase_orders_PoId",
column: x => x.PoId,
principalTable: "purchase_orders",
principalColumn: "PoId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_grns_users_CreatedBy",
column: x => x.CreatedBy,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_grns_vendors_VendorId",
column: x => x.VendorId,
principalTable: "vendors",
principalColumn: "VendorId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_grns_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "serials",
columns: table => new
{
SerialId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ItemId = table.Column<long>(type: "bigint", nullable: false),
SerialNo = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_serials", x => x.SerialId);
table.ForeignKey(
name: "FK_serials_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "grn_lines",
columns: table => new
{
GrnLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
GrnId = table.Column<long>(type: "bigint", nullable: false),
PoLineId = table.Column<long>(type: "bigint", nullable: true),
ItemId = table.Column<long>(type: "bigint", nullable: false),
UomId = table.Column<long>(type: "bigint", nullable: false),
BinId = table.Column<long>(type: "bigint", nullable: true),
BatchId = table.Column<long>(type: "bigint", nullable: true),
Qty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
UnitCost = table.Column<decimal>(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false),
ReceivedValue = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
HoldStatus = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_grn_lines", x => x.GrnLineId);
table.ForeignKey(
name: "FK_grn_lines_batches_BatchId",
column: x => x.BatchId,
principalTable: "batches",
principalColumn: "BatchId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_grn_lines_bins_BinId",
column: x => x.BinId,
principalTable: "bins",
principalColumn: "BinId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_grn_lines_grns_GrnId",
column: x => x.GrnId,
principalTable: "grns",
principalColumn: "GrnId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_grn_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_grn_lines_po_lines_PoLineId",
column: x => x.PoLineId,
principalTable: "po_lines",
principalColumn: "PoLineId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_grn_lines_uoms_UomId",
column: x => x.UomId,
principalTable: "uoms",
principalColumn: "UomId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "stock_ledger",
columns: table => new
{
LedgerId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ItemId = table.Column<long>(type: "bigint", nullable: false),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
BinId = table.Column<long>(type: "bigint", nullable: true),
BatchId = table.Column<long>(type: "bigint", nullable: true),
SerialId = table.Column<long>(type: "bigint", nullable: true),
UserId = table.Column<long>(type: "bigint", nullable: false),
Direction = table.Column<string>(type: "character varying(5)", maxLength: 5, nullable: false),
QtyBase = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
UnitCost = table.Column<decimal>(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false),
Value = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
RunningBalance = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
SourceDocType = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: false),
SourceDocId = table.Column<long>(type: "bigint", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_stock_ledger", x => x.LedgerId);
table.ForeignKey(
name: "FK_stock_ledger_batches_BatchId",
column: x => x.BatchId,
principalTable: "batches",
principalColumn: "BatchId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_ledger_bins_BinId",
column: x => x.BinId,
principalTable: "bins",
principalColumn: "BinId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_ledger_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_ledger_serials_SerialId",
column: x => x.SerialId,
principalTable: "serials",
principalColumn: "SerialId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_ledger_users_UserId",
column: x => x.UserId,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_ledger_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "stock_layers",
columns: table => new
{
LayerId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ItemId = table.Column<long>(type: "bigint", nullable: false),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
BatchId = table.Column<long>(type: "bigint", nullable: true),
SerialId = table.Column<long>(type: "bigint", nullable: true),
GrnLineId = table.Column<long>(type: "bigint", nullable: true),
QtyReceived = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
QtyRemaining = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
UnitCost = table.Column<decimal>(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false),
ReceiptDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_stock_layers", x => x.LayerId);
table.ForeignKey(
name: "FK_stock_layers_batches_BatchId",
column: x => x.BatchId,
principalTable: "batches",
principalColumn: "BatchId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_layers_grn_lines_GrnLineId",
column: x => x.GrnLineId,
principalTable: "grn_lines",
principalColumn: "GrnLineId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_layers_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_layers_serials_SerialId",
column: x => x.SerialId,
principalTable: "serials",
principalColumn: "SerialId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_layers_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_batches_ItemId_BatchNo",
table: "batches",
columns: new[] { "ItemId", "BatchNo" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_grn_lines_BatchId",
table: "grn_lines",
column: "BatchId");
migrationBuilder.CreateIndex(
name: "IX_grn_lines_BinId",
table: "grn_lines",
column: "BinId");
migrationBuilder.CreateIndex(
name: "IX_grn_lines_GrnId",
table: "grn_lines",
column: "GrnId");
migrationBuilder.CreateIndex(
name: "IX_grn_lines_ItemId",
table: "grn_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_grn_lines_PoLineId",
table: "grn_lines",
column: "PoLineId");
migrationBuilder.CreateIndex(
name: "IX_grn_lines_UomId",
table: "grn_lines",
column: "UomId");
migrationBuilder.CreateIndex(
name: "IX_grns_CreatedBy",
table: "grns",
column: "CreatedBy");
migrationBuilder.CreateIndex(
name: "IX_grns_DocNo",
table: "grns",
column: "DocNo",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_grns_PoId",
table: "grns",
column: "PoId");
migrationBuilder.CreateIndex(
name: "IX_grns_Status",
table: "grns",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_grns_VendorId",
table: "grns",
column: "VendorId");
migrationBuilder.CreateIndex(
name: "IX_grns_WarehouseId",
table: "grns",
column: "WarehouseId");
migrationBuilder.CreateIndex(
name: "IX_serials_ItemId_SerialNo",
table: "serials",
columns: new[] { "ItemId", "SerialNo" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_stock_layers_BatchId",
table: "stock_layers",
column: "BatchId");
migrationBuilder.CreateIndex(
name: "IX_stock_layers_GrnLineId",
table: "stock_layers",
column: "GrnLineId");
migrationBuilder.CreateIndex(
name: "IX_stock_layers_ItemId_WarehouseId_ReceiptDate_LayerId",
table: "stock_layers",
columns: new[] { "ItemId", "WarehouseId", "ReceiptDate", "LayerId" });
migrationBuilder.CreateIndex(
name: "IX_stock_layers_SerialId",
table: "stock_layers",
column: "SerialId");
migrationBuilder.CreateIndex(
name: "IX_stock_layers_WarehouseId",
table: "stock_layers",
column: "WarehouseId");
migrationBuilder.CreateIndex(
name: "IX_stock_ledger_BatchId",
table: "stock_ledger",
column: "BatchId");
migrationBuilder.CreateIndex(
name: "IX_stock_ledger_BinId",
table: "stock_ledger",
column: "BinId");
migrationBuilder.CreateIndex(
name: "IX_stock_ledger_ItemId_WarehouseId_CreatedAt",
table: "stock_ledger",
columns: new[] { "ItemId", "WarehouseId", "CreatedAt" });
migrationBuilder.CreateIndex(
name: "IX_stock_ledger_ItemId_WarehouseId_LedgerId",
table: "stock_ledger",
columns: new[] { "ItemId", "WarehouseId", "LedgerId" });
migrationBuilder.CreateIndex(
name: "IX_stock_ledger_SerialId",
table: "stock_ledger",
column: "SerialId");
migrationBuilder.CreateIndex(
name: "IX_stock_ledger_SourceDocType_SourceDocId",
table: "stock_ledger",
columns: new[] { "SourceDocType", "SourceDocId" });
migrationBuilder.CreateIndex(
name: "IX_stock_ledger_UserId",
table: "stock_ledger",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_stock_ledger_WarehouseId",
table: "stock_ledger",
column: "WarehouseId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "stock_layers");
migrationBuilder.DropTable(
name: "stock_ledger");
migrationBuilder.DropTable(
name: "grn_lines");
migrationBuilder.DropTable(
name: "serials");
migrationBuilder.DropTable(
name: "batches");
migrationBuilder.DropTable(
name: "grns");
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,337 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddStockTransactions : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "reason_codes",
columns: table => new
{
ReasonCodeId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Code = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
Description = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
Context = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_reason_codes", x => x.ReasonCodeId);
});
migrationBuilder.CreateTable(
name: "stock_transfers",
columns: table => new
{
TransferId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DocNo = table.Column<string>(type: "character varying(30)", maxLength: 30, nullable: false),
SrcWarehouseId = table.Column<long>(type: "bigint", nullable: false),
DestWarehouseId = table.Column<long>(type: "bigint", nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreatedBy = table.Column<long>(type: "bigint", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
xmin = table.Column<uint>(type: "xid", rowVersion: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_stock_transfers", x => x.TransferId);
table.ForeignKey(
name: "FK_stock_transfers_users_CreatedBy",
column: x => x.CreatedBy,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_transfers_warehouses_DestWarehouseId",
column: x => x.DestWarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_transfers_warehouses_SrcWarehouseId",
column: x => x.SrcWarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "stock_adjustments",
columns: table => new
{
AdjustmentId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DocNo = table.Column<string>(type: "character varying(30)", maxLength: 30, nullable: false),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
ReasonCodeId = table.Column<long>(type: "bigint", nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreatedBy = table.Column<long>(type: "bigint", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
xmin = table.Column<uint>(type: "xid", rowVersion: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_stock_adjustments", x => x.AdjustmentId);
table.ForeignKey(
name: "FK_stock_adjustments_reason_codes_ReasonCodeId",
column: x => x.ReasonCodeId,
principalTable: "reason_codes",
principalColumn: "ReasonCodeId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_adjustments_users_CreatedBy",
column: x => x.CreatedBy,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_adjustments_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "stock_transfer_lines",
columns: table => new
{
TransferLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
TransferId = table.Column<long>(type: "bigint", nullable: false),
ItemId = table.Column<long>(type: "bigint", nullable: false),
SrcBinId = table.Column<long>(type: "bigint", nullable: true),
DestBinId = table.Column<long>(type: "bigint", nullable: true),
BatchId = table.Column<long>(type: "bigint", nullable: true),
SerialId = table.Column<long>(type: "bigint", nullable: true),
Qty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
UnitCost = table.Column<decimal>(type: "numeric(18,6)", precision: 18, scale: 6, nullable: true),
QtyReceived = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_stock_transfer_lines", x => x.TransferLineId);
table.ForeignKey(
name: "FK_stock_transfer_lines_batches_BatchId",
column: x => x.BatchId,
principalTable: "batches",
principalColumn: "BatchId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_transfer_lines_bins_DestBinId",
column: x => x.DestBinId,
principalTable: "bins",
principalColumn: "BinId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_transfer_lines_bins_SrcBinId",
column: x => x.SrcBinId,
principalTable: "bins",
principalColumn: "BinId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_transfer_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_transfer_lines_serials_SerialId",
column: x => x.SerialId,
principalTable: "serials",
principalColumn: "SerialId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_transfer_lines_stock_transfers_TransferId",
column: x => x.TransferId,
principalTable: "stock_transfers",
principalColumn: "TransferId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "stock_adjustment_lines",
columns: table => new
{
AdjLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
AdjustmentId = table.Column<long>(type: "bigint", nullable: false),
ItemId = table.Column<long>(type: "bigint", nullable: false),
BinId = table.Column<long>(type: "bigint", nullable: true),
BatchId = table.Column<long>(type: "bigint", nullable: true),
SerialId = table.Column<long>(type: "bigint", nullable: true),
QtyDelta = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_stock_adjustment_lines", x => x.AdjLineId);
table.ForeignKey(
name: "FK_stock_adjustment_lines_batches_BatchId",
column: x => x.BatchId,
principalTable: "batches",
principalColumn: "BatchId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_adjustment_lines_bins_BinId",
column: x => x.BinId,
principalTable: "bins",
principalColumn: "BinId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_adjustment_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_adjustment_lines_serials_SerialId",
column: x => x.SerialId,
principalTable: "serials",
principalColumn: "SerialId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_adjustment_lines_stock_adjustments_AdjustmentId",
column: x => x.AdjustmentId,
principalTable: "stock_adjustments",
principalColumn: "AdjustmentId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_reason_codes_Context_Code",
table: "reason_codes",
columns: new[] { "Context", "Code" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_stock_adjustment_lines_AdjustmentId",
table: "stock_adjustment_lines",
column: "AdjustmentId");
migrationBuilder.CreateIndex(
name: "IX_stock_adjustment_lines_BatchId",
table: "stock_adjustment_lines",
column: "BatchId");
migrationBuilder.CreateIndex(
name: "IX_stock_adjustment_lines_BinId",
table: "stock_adjustment_lines",
column: "BinId");
migrationBuilder.CreateIndex(
name: "IX_stock_adjustment_lines_ItemId",
table: "stock_adjustment_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_stock_adjustment_lines_SerialId",
table: "stock_adjustment_lines",
column: "SerialId");
migrationBuilder.CreateIndex(
name: "IX_stock_adjustments_CreatedBy",
table: "stock_adjustments",
column: "CreatedBy");
migrationBuilder.CreateIndex(
name: "IX_stock_adjustments_DocNo",
table: "stock_adjustments",
column: "DocNo",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_stock_adjustments_ReasonCodeId",
table: "stock_adjustments",
column: "ReasonCodeId");
migrationBuilder.CreateIndex(
name: "IX_stock_adjustments_WarehouseId",
table: "stock_adjustments",
column: "WarehouseId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfer_lines_BatchId",
table: "stock_transfer_lines",
column: "BatchId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfer_lines_DestBinId",
table: "stock_transfer_lines",
column: "DestBinId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfer_lines_ItemId",
table: "stock_transfer_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfer_lines_SerialId",
table: "stock_transfer_lines",
column: "SerialId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfer_lines_SrcBinId",
table: "stock_transfer_lines",
column: "SrcBinId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfer_lines_TransferId",
table: "stock_transfer_lines",
column: "TransferId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfers_CreatedBy",
table: "stock_transfers",
column: "CreatedBy");
migrationBuilder.CreateIndex(
name: "IX_stock_transfers_DestWarehouseId",
table: "stock_transfers",
column: "DestWarehouseId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfers_DocNo",
table: "stock_transfers",
column: "DocNo",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_stock_transfers_SrcWarehouseId",
table: "stock_transfers",
column: "SrcWarehouseId");
migrationBuilder.CreateIndex(
name: "IX_stock_transfers_Status",
table: "stock_transfers",
column: "Status");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "stock_adjustment_lines");
migrationBuilder.DropTable(
name: "stock_transfer_lines");
migrationBuilder.DropTable(
name: "stock_adjustments");
migrationBuilder.DropTable(
name: "stock_transfers");
migrationBuilder.DropTable(
name: "reason_codes");
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,253 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddCountsAndReturns : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "purchase_returns",
columns: table => new
{
ReturnId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DocNo = table.Column<string>(type: "character varying(30)", maxLength: 30, nullable: false),
VendorId = table.Column<long>(type: "bigint", nullable: false),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
ReasonCodeId = table.Column<long>(type: "bigint", nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreatedBy = table.Column<long>(type: "bigint", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_purchase_returns", x => x.ReturnId);
table.ForeignKey(
name: "FK_purchase_returns_reason_codes_ReasonCodeId",
column: x => x.ReasonCodeId,
principalTable: "reason_codes",
principalColumn: "ReasonCodeId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_purchase_returns_users_CreatedBy",
column: x => x.CreatedBy,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_purchase_returns_vendors_VendorId",
column: x => x.VendorId,
principalTable: "vendors",
principalColumn: "VendorId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_purchase_returns_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "stock_counts",
columns: table => new
{
CountId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DocNo = table.Column<string>(type: "character varying(30)", maxLength: 30, nullable: false),
WarehouseId = table.Column<long>(type: "bigint", nullable: false),
CountType = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreatedBy = table.Column<long>(type: "bigint", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
xmin = table.Column<uint>(type: "xid", rowVersion: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_stock_counts", x => x.CountId);
table.ForeignKey(
name: "FK_stock_counts_users_CreatedBy",
column: x => x.CreatedBy,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_counts_warehouses_WarehouseId",
column: x => x.WarehouseId,
principalTable: "warehouses",
principalColumn: "WarehouseId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "purchase_return_lines",
columns: table => new
{
ReturnLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ReturnId = table.Column<long>(type: "bigint", nullable: false),
GrnLineId = table.Column<long>(type: "bigint", nullable: true),
ItemId = table.Column<long>(type: "bigint", nullable: false),
Qty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_purchase_return_lines", x => x.ReturnLineId);
table.ForeignKey(
name: "FK_purchase_return_lines_grn_lines_GrnLineId",
column: x => x.GrnLineId,
principalTable: "grn_lines",
principalColumn: "GrnLineId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_purchase_return_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_purchase_return_lines_purchase_returns_ReturnId",
column: x => x.ReturnId,
principalTable: "purchase_returns",
principalColumn: "ReturnId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "stock_count_lines",
columns: table => new
{
CountLineId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CountId = table.Column<long>(type: "bigint", nullable: false),
ItemId = table.Column<long>(type: "bigint", nullable: false),
BinId = table.Column<long>(type: "bigint", nullable: true),
SystemQty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
CountedQty = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true),
Variance = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_stock_count_lines", x => x.CountLineId);
table.ForeignKey(
name: "FK_stock_count_lines_bins_BinId",
column: x => x.BinId,
principalTable: "bins",
principalColumn: "BinId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_count_lines_items_ItemId",
column: x => x.ItemId,
principalTable: "items",
principalColumn: "ItemId",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_stock_count_lines_stock_counts_CountId",
column: x => x.CountId,
principalTable: "stock_counts",
principalColumn: "CountId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_purchase_return_lines_GrnLineId",
table: "purchase_return_lines",
column: "GrnLineId");
migrationBuilder.CreateIndex(
name: "IX_purchase_return_lines_ItemId",
table: "purchase_return_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_purchase_return_lines_ReturnId",
table: "purchase_return_lines",
column: "ReturnId");
migrationBuilder.CreateIndex(
name: "IX_purchase_returns_CreatedBy",
table: "purchase_returns",
column: "CreatedBy");
migrationBuilder.CreateIndex(
name: "IX_purchase_returns_DocNo",
table: "purchase_returns",
column: "DocNo",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_purchase_returns_ReasonCodeId",
table: "purchase_returns",
column: "ReasonCodeId");
migrationBuilder.CreateIndex(
name: "IX_purchase_returns_VendorId",
table: "purchase_returns",
column: "VendorId");
migrationBuilder.CreateIndex(
name: "IX_purchase_returns_WarehouseId",
table: "purchase_returns",
column: "WarehouseId");
migrationBuilder.CreateIndex(
name: "IX_stock_count_lines_BinId",
table: "stock_count_lines",
column: "BinId");
migrationBuilder.CreateIndex(
name: "IX_stock_count_lines_CountId",
table: "stock_count_lines",
column: "CountId");
migrationBuilder.CreateIndex(
name: "IX_stock_count_lines_ItemId",
table: "stock_count_lines",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_stock_counts_CreatedBy",
table: "stock_counts",
column: "CreatedBy");
migrationBuilder.CreateIndex(
name: "IX_stock_counts_DocNo",
table: "stock_counts",
column: "DocNo",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_stock_counts_Status",
table: "stock_counts",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_stock_counts_WarehouseId",
table: "stock_counts",
column: "WarehouseId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "purchase_return_lines");
migrationBuilder.DropTable(
name: "stock_count_lines");
migrationBuilder.DropTable(
name: "purchase_returns");
migrationBuilder.DropTable(
name: "stock_counts");
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,87 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddAuditAndJournal : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "audit_logs",
columns: table => new
{
AuditId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
UserId = table.Column<long>(type: "bigint", nullable: false),
EntityType = table.Column<string>(type: "character varying(80)", maxLength: 80, nullable: false),
EntityId = table.Column<long>(type: "bigint", nullable: false),
Action = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: false),
ChangeSet = table.Column<string>(type: "jsonb", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_audit_logs", x => x.AuditId);
table.ForeignKey(
name: "FK_audit_logs_users_UserId",
column: x => x.UserId,
principalTable: "users",
principalColumn: "UserId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "journal_entry_stubs",
columns: table => new
{
JournalId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
SourceDocType = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: false),
SourceDocId = table.Column<long>(type: "bigint", nullable: false),
DebitAccount = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
CreditAccount = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
Amount = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_journal_entry_stubs", x => x.JournalId);
});
migrationBuilder.CreateIndex(
name: "IX_audit_logs_CreatedAt",
table: "audit_logs",
column: "CreatedAt");
migrationBuilder.CreateIndex(
name: "IX_audit_logs_EntityType_EntityId",
table: "audit_logs",
columns: new[] { "EntityType", "EntityId" });
migrationBuilder.CreateIndex(
name: "IX_audit_logs_UserId",
table: "audit_logs",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_journal_entry_stubs_SourceDocType_SourceDocId",
table: "journal_entry_stubs",
columns: new[] { "SourceDocType", "SourceDocId" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "audit_logs");
migrationBuilder.DropTable(
name: "journal_entry_stubs");
}
}
}
@@ -1,46 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ERPCore.Infra.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddAuthUserId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "auth_user_id",
table: "users",
type: "uuid",
nullable: true);
migrationBuilder.UpdateData(
table: "users",
keyColumn: "UserId",
keyValue: 1L,
column: "auth_user_id",
value: null);
migrationBuilder.CreateIndex(
name: "IX_users_auth_user_id",
table: "users",
column: "auth_user_id",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_users_auth_user_id",
table: "users");
migrationBuilder.DropColumn(
name: "auth_user_id",
table: "users");
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -36,7 +36,7 @@ builder.Services.AddExceptionHandler<DomainExceptionHandler>();
builder.Services.AddErpJwtAuth(builder.Configuration); builder.Services.AddErpJwtAuth(builder.Configuration);
// Current-user (audit actor). AuthHex has no sub/nameid → a claims transformation // Current-user (audit actor). AuthHex has no sub/nameid → a claims transformation
// JIT-provisions a local shadow user and injects the local `long` id as `nameid`. // JIT-provisions a local shadow user and injects the local `int` id as `nameid`.
builder.Services.AddHttpContextAccessor(); builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<ICurrentUser, CurrentUser>(); builder.Services.AddScoped<ICurrentUser, CurrentUser>();
builder.Services.AddScoped<IClaimsTransformation, ShadowUserClaimsTransformation>(); builder.Services.AddScoped<IClaimsTransformation, ShadowUserClaimsTransformation>();
@@ -4,7 +4,8 @@
"http": { "http": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": false, "launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5224", "applicationUrl": "http://localhost:5224",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
@@ -13,7 +14,8 @@
"https": { "https": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": false, "launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7112;http://localhost:5224", "applicationUrl": "https://localhost:7112;http://localhost:5224",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
+2 -2
View File
@@ -20,7 +20,7 @@ public sealed class AuditService : IAuditService
} }
public async Task<PagedResponse<AuditLogDto>> ListLogsAsync( public async Task<PagedResponse<AuditLogDto>> ListLogsAsync(
string? entityType, long? entityId, long? userId, DateOnly? from, DateOnly? to, PageQuery query, CancellationToken ct = default) string? entityType, int? entityId, int? userId, DateOnly? from, DateOnly? to, PageQuery query, CancellationToken ct = default)
{ {
var q = _logs.Query().AsNoTracking(); var q = _logs.Query().AsNoTracking();
if (!string.IsNullOrWhiteSpace(entityType)) q = q.Where(l => l.EntityType == entityType); if (!string.IsNullOrWhiteSpace(entityType)) q = q.Where(l => l.EntityType == entityType);
@@ -41,7 +41,7 @@ public sealed class AuditService : IAuditService
} }
public async Task<PagedResponse<JournalEntryStubDto>> ListJournalAsync( public async Task<PagedResponse<JournalEntryStubDto>> ListJournalAsync(
string? sourceDocType, long? sourceDocId, PageQuery query, CancellationToken ct = default) string? sourceDocType, int? sourceDocId, PageQuery query, CancellationToken ct = default)
{ {
var q = _journal.Query().AsNoTracking(); var q = _journal.Query().AsNoTracking();
if (!string.IsNullOrWhiteSpace(sourceDocType)) q = q.Where(j => j.SourceDocType == sourceDocType); if (!string.IsNullOrWhiteSpace(sourceDocType)) q = q.Where(j => j.SourceDocType == sourceDocType);
+1 -1
View File
@@ -47,7 +47,7 @@ public sealed class CategoryService : ICategoryService
var byParent = all.ToLookup(c => c.ParentId); var byParent = all.ToLookup(c => c.ParentId);
List<CategoryTreeDto> Build(long? parentId) => List<CategoryTreeDto> Build(int? parentId) =>
byParent[parentId] byParent[parentId]
.Select(c => new CategoryTreeDto(c.CategoryId, c.Name, c.ParentId, Build(c.CategoryId))) .Select(c => new CategoryTreeDto(c.CategoryId, c.Name, c.ParentId, Build(c.CategoryId)))
.ToList(); .ToList();
+4 -4
View File
@@ -49,7 +49,7 @@ public sealed class CountService : ICountService
_uow = uow; _uow = uow;
} }
public async Task<CountDto?> GetAsync(long countId, CancellationToken ct = default) public async Task<CountDto?> GetAsync(int countId, CancellationToken ct = default)
{ {
var count = await _counts.Query().AsNoTracking().Include(c => c.Lines) var count = await _counts.Query().AsNoTracking().Include(c => c.Lines)
.FirstOrDefaultAsync(c => c.CountId == countId, ct); .FirstOrDefaultAsync(c => c.CountId == countId, ct);
@@ -94,7 +94,7 @@ public sealed class CountService : ICountService
return Map(count); return Map(count);
} }
public async Task<CountDto> EnterCountsAsync(long countId, EnterCountsRequest request, CancellationToken ct = default) public async Task<CountDto> EnterCountsAsync(int countId, EnterCountsRequest request, CancellationToken ct = default)
{ {
var count = await _counts.Query().Include(c => c.Lines) var count = await _counts.Query().Include(c => c.Lines)
.FirstOrDefaultAsync(c => c.CountId == countId, ct) .FirstOrDefaultAsync(c => c.CountId == countId, ct)
@@ -115,7 +115,7 @@ public sealed class CountService : ICountService
return Map(count); return Map(count);
} }
public async Task<CountPostResultDto> PostAsync(long countId, CancellationToken ct = default) public async Task<CountPostResultDto> PostAsync(int countId, CancellationToken ct = default)
{ {
var count = await _counts.Query().Include(c => c.Lines) var count = await _counts.Query().Include(c => c.Lines)
.FirstOrDefaultAsync(c => c.CountId == countId, ct) .FirstOrDefaultAsync(c => c.CountId == countId, ct)
@@ -135,7 +135,7 @@ public sealed class CountService : ICountService
{ {
count.Status = CountStatus.Posted; count.Status = CountStatus.Posted;
await _uow.SaveChangesAsync(ct); await _uow.SaveChangesAsync(ct);
return new CountPostResultDto(count.CountId, count.Status, null, Array.Empty<long>()); return new CountPostResultDto(count.CountId, count.Status, null, Array.Empty<int>());
} }
var reason = await _reasonCodes.Query().AsNoTracking() var reason = await _reasonCodes.Query().AsNoTracking()
+10 -10
View File
@@ -65,7 +65,7 @@ public sealed class GrnService : IGrnService
_uow = uow; _uow = uow;
} }
public async Task<GrnDto?> GetAsync(long grnId, CancellationToken ct = default) public async Task<GrnDto?> GetAsync(int grnId, CancellationToken ct = default)
{ {
var grn = await _grns.Query().AsNoTracking() var grn = await _grns.Query().AsNoTracking()
.Include(g => g.Lines) .Include(g => g.Lines)
@@ -80,7 +80,7 @@ public sealed class GrnService : IGrnService
// Resolve vendor + PO context. // Resolve vendor + PO context.
PurchaseOrder? po = null; PurchaseOrder? po = null;
long vendorId; int vendorId;
if (request.PoId is not null) if (request.PoId is not null)
{ {
po = await _pos.Query().AsNoTracking().Include(p => p.Lines) po = await _pos.Query().AsNoTracking().Include(p => p.Lines)
@@ -100,7 +100,7 @@ public sealed class GrnService : IGrnService
} }
var lines = new List<GrnLine>(); var lines = new List<GrnLine>();
var batchCache = new Dictionary<(long ItemId, string BatchNo), Batch>(); var batchCache = new Dictionary<(int ItemId, string BatchNo), Batch>();
foreach (var input in request.Lines) foreach (var input in request.Lines)
{ {
@@ -169,7 +169,7 @@ public sealed class GrnService : IGrnService
return Map(grn); return Map(grn);
} }
public async Task<GrnConfirmResultDto> ConfirmAsync(long grnId, string? idempotencyKey, CancellationToken ct = default) public async Task<GrnConfirmResultDto> ConfirmAsync(int grnId, string? idempotencyKey, CancellationToken ct = default)
{ {
var grn = await _grns.Query() var grn = await _grns.Query()
.Include(g => g.Lines) .Include(g => g.Lines)
@@ -184,7 +184,7 @@ public sealed class GrnService : IGrnService
var actor = _currentUser.AuditUserId; var actor = _currentUser.AuditUserId;
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
var runningBalance = new Dictionary<(long, long), decimal>(); var runningBalance = new Dictionary<(int, int), decimal>();
var createdLayers = new List<StockLayer>(); var createdLayers = new List<StockLayer>();
var ledgerRefs = new List<StockLedger>(); var ledgerRefs = new List<StockLedger>();
@@ -232,7 +232,7 @@ public sealed class GrnService : IGrnService
await GetPoStatusAsync(grn.PoId, ct)); await GetPoStatusAsync(grn.PoId, ct));
} }
public async Task<ReleaseLineResultDto> ReleaseLineAsync(long grnId, long grnLineId, string action, CancellationToken ct = default) public async Task<ReleaseLineResultDto> ReleaseLineAsync(int grnId, int grnLineId, string action, CancellationToken ct = default)
{ {
var grn = await _grns.Query() var grn = await _grns.Query()
.Include(g => g.Lines) .Include(g => g.Lines)
@@ -279,7 +279,7 @@ public sealed class GrnService : IGrnService
} }
private async Task<Batch?> ResolveBatchAsync( private async Task<Batch?> ResolveBatchAsync(
Item item, BatchInput? batch, Dictionary<(long, string), Batch> cache, CancellationToken ct) Item item, BatchInput? batch, Dictionary<(int, string), Batch> cache, CancellationToken ct)
{ {
if (item.TrackingMode == TrackingMode.Batch && batch is null) if (item.TrackingMode == TrackingMode.Batch && batch is null)
throw new DomainException(ErrorCodes.Validation, $"Item {item.ItemId} is batch-tracked; a batch is required.", 422); throw new DomainException(ErrorCodes.Validation, $"Item {item.ItemId} is batch-tracked; a batch is required.", 422);
@@ -302,7 +302,7 @@ public sealed class GrnService : IGrnService
} }
private async Task<(decimal QtyBase, decimal UnitCostBase)> ToBaseAsync( private async Task<(decimal QtyBase, decimal UnitCostBase)> ToBaseAsync(
Item item, long uomId, decimal qty, decimal unitCostPerUom, CancellationToken ct) Item item, int uomId, decimal qty, decimal unitCostPerUom, CancellationToken ct)
{ {
if (uomId == item.BaseUomId) if (uomId == item.BaseUomId)
return (qty, unitCostPerUom); return (qty, unitCostPerUom);
@@ -315,7 +315,7 @@ public sealed class GrnService : IGrnService
return (qty * conv.Factor, unitCostPerUom / conv.Factor); return (qty * conv.Factor, unitCostPerUom / conv.Factor);
} }
private async Task UpdatePoStatusAsync(long? poId, CancellationToken ct) private async Task UpdatePoStatusAsync(int? poId, CancellationToken ct)
{ {
if (poId is null) return; if (poId is null) return;
var po = await _pos.Query().Include(p => p.Lines).FirstOrDefaultAsync(p => p.PoId == poId, ct); var po = await _pos.Query().Include(p => p.Lines).FirstOrDefaultAsync(p => p.PoId == poId, ct);
@@ -327,7 +327,7 @@ public sealed class GrnService : IGrnService
po.UpdatedAt = DateTime.UtcNow; po.UpdatedAt = DateTime.UtcNow;
} }
private async Task<PurchaseOrderStatus?> GetPoStatusAsync(long? poId, CancellationToken ct) private async Task<PurchaseOrderStatus?> GetPoStatusAsync(int? poId, CancellationToken ct)
{ {
if (poId is null) return null; if (poId is null) return null;
return await _pos.Query().AsNoTracking().Where(p => p.PoId == poId).Select(p => (PurchaseOrderStatus?)p.Status).FirstOrDefaultAsync(ct); return await _pos.Query().AsNoTracking().Where(p => p.PoId == poId).Select(p => (PurchaseOrderStatus?)p.Status).FirstOrDefaultAsync(ct);
@@ -10,8 +10,8 @@ namespace ERPCore.Services.Interfaces;
public interface IAuditService public interface IAuditService
{ {
Task<PagedResponse<AuditLogDto>> ListLogsAsync( Task<PagedResponse<AuditLogDto>> ListLogsAsync(
string? entityType, long? entityId, long? userId, DateOnly? from, DateOnly? to, PageQuery query, CancellationToken ct = default); string? entityType, int? entityId, int? userId, DateOnly? from, DateOnly? to, PageQuery query, CancellationToken ct = default);
Task<PagedResponse<JournalEntryStubDto>> ListJournalAsync( Task<PagedResponse<JournalEntryStubDto>> ListJournalAsync(
string? sourceDocType, long? sourceDocId, PageQuery query, CancellationToken ct = default); string? sourceDocType, int? sourceDocId, PageQuery query, CancellationToken ct = default);
} }
@@ -5,8 +5,8 @@ namespace ERPCore.Services.Interfaces;
/// <summary>Cycle/full stock-count business logic (docs/11 §5.6; FR-STK-08).</summary> /// <summary>Cycle/full stock-count business logic (docs/11 §5.6; FR-STK-08).</summary>
public interface ICountService public interface ICountService
{ {
Task<CountDto?> GetAsync(long countId, CancellationToken ct = default); Task<CountDto?> GetAsync(int countId, CancellationToken ct = default);
Task<CountDto> CreateAsync(CreateCountRequest request, CancellationToken ct = default); Task<CountDto> CreateAsync(CreateCountRequest request, CancellationToken ct = default);
Task<CountDto> EnterCountsAsync(long countId, EnterCountsRequest request, CancellationToken ct = default); Task<CountDto> EnterCountsAsync(int countId, EnterCountsRequest request, CancellationToken ct = default);
Task<CountPostResultDto> PostAsync(long countId, CancellationToken ct = default); Task<CountPostResultDto> PostAsync(int countId, CancellationToken ct = default);
} }
@@ -15,7 +15,7 @@ public interface IFifoCostingService
{ {
/// <summary>Create an inbound FIFO layer (qty and unit cost in the item's base UOM).</summary> /// <summary>Create an inbound FIFO layer (qty and unit cost in the item's base UOM).</summary>
Task<StockLayer> CreateInboundLayerAsync( Task<StockLayer> CreateInboundLayerAsync(
long itemId, long warehouseId, long? batchId, long? serialId, long? grnLineId, int itemId, int warehouseId, int? batchId, int? serialId, int? grnLineId,
decimal qtyBase, decimal unitCost, DateTime receiptDate, CancellationToken ct = default); decimal qtyBase, decimal unitCost, DateTime receiptDate, CancellationToken ct = default);
/// <summary> /// <summary>
@@ -27,20 +27,20 @@ public interface IFifoCostingService
/// and ledger costing). Must run inside a UoW transaction. /// and ledger costing). Must run inside a UoW transaction.
/// </summary> /// </summary>
Task<IReadOnlyList<ConsumedSegment>> ConsumeAsync( Task<IReadOnlyList<ConsumedSegment>> ConsumeAsync(
long itemId, long warehouseId, long? batchId, decimal qtyBase, CancellationToken ct = default); int itemId, int warehouseId, int? batchId, decimal qtyBase, CancellationToken ct = default);
/// <summary>Append an immutable ledger entry (value = qtyBase × unitCost).</summary> /// <summary>Append an immutable ledger entry (value = qtyBase × unitCost).</summary>
Task<StockLedger> PostLedgerAsync( Task<StockLedger> PostLedgerAsync(
long itemId, long warehouseId, long? binId, long? batchId, long? serialId, long userId, int itemId, int warehouseId, int? binId, int? batchId, int? serialId, int userId,
Direction direction, decimal qtyBase, decimal unitCost, decimal runningBalance, Direction direction, decimal qtyBase, decimal unitCost, decimal runningBalance,
string sourceDocType, long sourceDocId, DateTime createdAt, CancellationToken ct = default); string sourceDocType, int sourceDocId, DateTime createdAt, CancellationToken ct = default);
/// <summary>Current on-hand (Σ open-layer qtyRemaining) for an item at a warehouse.</summary> /// <summary>Current on-hand (Σ open-layer qtyRemaining) for an item at a warehouse.</summary>
Task<decimal> GetOnHandAsync(long itemId, long warehouseId, CancellationToken ct = default); Task<decimal> GetOnHandAsync(int itemId, int warehouseId, CancellationToken ct = default);
/// <summary>Valuation over open layers: Σ(qtyRemaining × unitCost) (FR-STK-04).</summary> /// <summary>Valuation over open layers: Σ(qtyRemaining × unitCost) (FR-STK-04).</summary>
Task<StockValuationDto> GetValuationAsync(long itemId, long warehouseId, CancellationToken ct = default); Task<StockValuationDto> GetValuationAsync(int itemId, int warehouseId, CancellationToken ct = default);
} }
/// <summary>A quantity consumed from one FIFO layer at that layer's unit cost.</summary> /// <summary>A quantity consumed from one FIFO layer at that layer's unit cost.</summary>
public sealed record ConsumedSegment(long LayerId, decimal Qty, decimal UnitCost); public sealed record ConsumedSegment(int LayerId, decimal Qty, decimal UnitCost);
@@ -5,11 +5,11 @@ namespace ERPCore.Services.Interfaces;
/// <summary>Goods-receipt business logic (docs/11 §4; FR-GRN-01..08).</summary> /// <summary>Goods-receipt business logic (docs/11 §4; FR-GRN-01..08).</summary>
public interface IGrnService public interface IGrnService
{ {
Task<GrnDto?> GetAsync(long grnId, CancellationToken ct = default); Task<GrnDto?> GetAsync(int grnId, CancellationToken ct = default);
Task<GrnDto> CreateAsync(CreateGrnRequest request, CancellationToken ct = default); Task<GrnDto> CreateAsync(CreateGrnRequest request, CancellationToken ct = default);
/// <summary>Confirm: create FIFO layers + inbound ledger + update PO receipts, atomically.</summary> /// <summary>Confirm: create FIFO layers + inbound ledger + update PO receipts, atomically.</summary>
Task<GrnConfirmResultDto> ConfirmAsync(long grnId, string? idempotencyKey, CancellationToken ct = default); Task<GrnConfirmResultDto> ConfirmAsync(int grnId, string? idempotencyKey, CancellationToken ct = default);
Task<ReleaseLineResultDto> ReleaseLineAsync(long grnId, long grnLineId, string action, CancellationToken ct = default); Task<ReleaseLineResultDto> ReleaseLineAsync(int grnId, int grnLineId, string action, CancellationToken ct = default);
} }
@@ -12,17 +12,17 @@ namespace ERPCore.Services.Interfaces;
public interface IItemService public interface IItemService
{ {
Task<PagedResponse<ItemListItemDto>> ListAsync( Task<PagedResponse<ItemListItemDto>> ListAsync(
PageQuery query, EntityStatus? status, long? categoryId, TrackingMode? trackingMode, CancellationToken ct = default); PageQuery query, EntityStatus? status, int? categoryId, TrackingMode? trackingMode, CancellationToken ct = default);
Task<ETagged<ItemDetailDto>?> GetAsync(long itemId, CancellationToken ct = default); Task<ETagged<ItemDetailDto>?> GetAsync(int itemId, CancellationToken ct = default);
Task<ETagged<ItemDetailDto>> CreateAsync(CreateItemRequest request, CancellationToken ct = default); Task<ETagged<ItemDetailDto>> CreateAsync(CreateItemRequest request, CancellationToken ct = default);
Task<ETagged<ItemDetailDto>> UpdateAsync(long itemId, UpdateItemRequest request, uint expectedRowVersion, CancellationToken ct = default); Task<ETagged<ItemDetailDto>> UpdateAsync(int itemId, UpdateItemRequest request, uint expectedRowVersion, CancellationToken ct = default);
Task SetStatusAsync(long itemId, EntityStatus status, CancellationToken ct = default); Task SetStatusAsync(int itemId, EntityStatus status, CancellationToken ct = default);
Task<ItemReorderSettingsDto> UpdateReorderAsync(long itemId, UpdateReorderRequest request, CancellationToken ct = default); Task<ItemReorderSettingsDto> UpdateReorderAsync(int itemId, UpdateReorderRequest request, CancellationToken ct = default);
Task<ItemUomConversionsDto> UpdateUomConversionsAsync(long itemId, UpdateUomConversionsRequest request, CancellationToken ct = default); Task<ItemUomConversionsDto> UpdateUomConversionsAsync(int itemId, UpdateUomConversionsRequest request, CancellationToken ct = default);
} }
@@ -9,11 +9,11 @@ namespace ERPCore.Services.Interfaces;
public interface IPurchaseOrderService public interface IPurchaseOrderService
{ {
Task<PagedResponse<PurchaseOrderSummaryDto>> ListAsync( Task<PagedResponse<PurchaseOrderSummaryDto>> ListAsync(
PageQuery query, PurchaseOrderStatus? status, long? vendorId, CancellationToken ct = default); PageQuery query, PurchaseOrderStatus? status, int? vendorId, CancellationToken ct = default);
Task<ETagged<PurchaseOrderDto>?> GetAsync(long poId, CancellationToken ct = default); Task<ETagged<PurchaseOrderDto>?> GetAsync(int poId, CancellationToken ct = default);
Task<ETagged<PurchaseOrderDto>> CreateAsync(CreatePurchaseOrderRequest request, CancellationToken ct = default); Task<ETagged<PurchaseOrderDto>> CreateAsync(CreatePurchaseOrderRequest request, CancellationToken ct = default);
Task<ETagged<PurchaseOrderDto>> UpdateAsync(long poId, UpdatePurchaseOrderRequest request, uint expectedRowVersion, CancellationToken ct = default); Task<ETagged<PurchaseOrderDto>> UpdateAsync(int poId, UpdatePurchaseOrderRequest request, uint expectedRowVersion, CancellationToken ct = default);
Task<PurchaseOrderDto> ApproveAsync(long poId, CancellationToken ct = default); Task<PurchaseOrderDto> ApproveAsync(int poId, CancellationToken ct = default);
Task<PurchaseOrderDto> CancelAsync(long poId, string? reason, CancellationToken ct = default); Task<PurchaseOrderDto> CancelAsync(int poId, string? reason, CancellationToken ct = default);
} }
@@ -7,6 +7,6 @@ namespace ERPCore.Services.Interfaces;
/// <summary>Reorder alerts and suggested requisitions (docs/11 §5.7; FR-STK-10).</summary> /// <summary>Reorder alerts and suggested requisitions (docs/11 §5.7; FR-STK-10).</summary>
public interface IReorderService public interface IReorderService
{ {
Task<PagedResponse<ReorderAlertDto>> GetAlertsAsync(long? warehouseId, PageQuery query, CancellationToken ct = default); Task<PagedResponse<ReorderAlertDto>> GetAlertsAsync(int? warehouseId, PageQuery query, CancellationToken ct = default);
Task<RequisitionDto> CreateSuggestedRequisitionAsync(long itemId, long warehouseId, CancellationToken ct = default); Task<RequisitionDto> CreateSuggestedRequisitionAsync(int itemId, int warehouseId, CancellationToken ct = default);
} }
@@ -7,7 +7,7 @@ namespace ERPCore.Services.Interfaces;
public interface IRequisitionService public interface IRequisitionService
{ {
Task<PagedResponse<RequisitionSummaryDto>> ListAsync(PageQuery query, CancellationToken ct = default); Task<PagedResponse<RequisitionSummaryDto>> ListAsync(PageQuery query, CancellationToken ct = default);
Task<RequisitionDto?> GetAsync(long requisitionId, CancellationToken ct = default); Task<RequisitionDto?> GetAsync(int requisitionId, CancellationToken ct = default);
Task<RequisitionDto> CreateAsync(CreateRequisitionRequest request, CancellationToken ct = default); Task<RequisitionDto> CreateAsync(CreateRequisitionRequest request, CancellationToken ct = default);
Task<RequisitionDto> SubmitAsync(long requisitionId, CancellationToken ct = default); Task<RequisitionDto> SubmitAsync(int requisitionId, CancellationToken ct = default);
} }

Some files were not shown because too many files have changed in this diff Show More