Initial commit

This commit is contained in:
2026-04-23 21:38:24 -04:00
commit 63e12a9636
1762 changed files with 1672620 additions and 0 deletions
@@ -0,0 +1,196 @@
using System.ComponentModel.DataAnnotations;
using PowderCoating.Core.Enums;
namespace PowderCoating.Application.DTOs.PurchaseOrder;
// ============================================================================
// LIST / SUMMARY
// ============================================================================
public class PurchaseOrderListDto
{
public int Id { get; set; }
public string PoNumber { get; set; } = string.Empty;
public int VendorId { get; set; }
public string VendorName { get; set; } = string.Empty;
public PurchaseOrderStatus Status { get; set; }
public DateTime OrderDate { get; set; }
public DateTime? ExpectedDeliveryDate { get; set; }
public DateTime? ReceivedDate { get; set; }
public decimal ShippingCost { get; set; }
public decimal SubTotal { get; set; }
public decimal TotalAmount { get; set; }
public int ItemCount { get; set; }
public bool IsOverdue =>
Status is PurchaseOrderStatus.Draft or PurchaseOrderStatus.Submitted or PurchaseOrderStatus.PartiallyReceived
&& ExpectedDeliveryDate.HasValue
&& ExpectedDeliveryDate.Value.Date < DateTime.UtcNow.Date;
}
// ============================================================================
// DETAILS
// ============================================================================
public class PurchaseOrderDto
{
public int Id { get; set; }
public string PoNumber { get; set; } = string.Empty;
public int VendorId { get; set; }
public string VendorName { get; set; } = string.Empty;
public string? VendorEmail { get; set; }
public string? VendorPhone { get; set; }
public PurchaseOrderStatus Status { get; set; }
public DateTime OrderDate { get; set; }
public DateTime? ExpectedDeliveryDate { get; set; }
public DateTime? ReceivedDate { get; set; }
public decimal ShippingCost { get; set; }
public decimal SubTotal { get; set; }
public decimal TotalAmount { get; set; }
public string? Notes { get; set; }
public string? InternalNotes { get; set; }
public int? BillId { get; set; }
public string? BillNumber { get; set; }
public List<PurchaseOrderItemDto> Items { get; set; } = new();
public bool IsOverdue =>
Status is PurchaseOrderStatus.Draft or PurchaseOrderStatus.Submitted or PurchaseOrderStatus.PartiallyReceived
&& ExpectedDeliveryDate.HasValue
&& ExpectedDeliveryDate.Value.Date < DateTime.UtcNow.Date;
}
// ============================================================================
// CREATE / UPDATE
// ============================================================================
public class CreatePurchaseOrderDto
{
[Required]
public int VendorId { get; set; }
[Required]
[Display(Name = "Order Date")]
public DateTime OrderDate { get; set; } = DateTime.Today;
[Display(Name = "Expected Delivery")]
public DateTime? ExpectedDeliveryDate { get; set; }
[Display(Name = "Shipping Cost")]
[Range(0, 999999)]
public decimal ShippingCost { get; set; } = 0;
[Display(Name = "Notes")]
[StringLength(1000)]
public string? Notes { get; set; }
[Display(Name = "Internal Notes")]
[StringLength(1000)]
public string? InternalNotes { get; set; }
public List<CreatePurchaseOrderItemDto> Items { get; set; } = new();
}
public class UpdatePurchaseOrderDto
{
[Required]
public int VendorId { get; set; }
[Required]
[Display(Name = "Order Date")]
public DateTime OrderDate { get; set; } = DateTime.Today;
[Display(Name = "Expected Delivery")]
public DateTime? ExpectedDeliveryDate { get; set; }
[Display(Name = "Shipping Cost")]
[Range(0, 999999)]
public decimal ShippingCost { get; set; } = 0;
[Display(Name = "Notes")]
[StringLength(1000)]
public string? Notes { get; set; }
[Display(Name = "Internal Notes")]
[StringLength(1000)]
public string? InternalNotes { get; set; }
public List<CreatePurchaseOrderItemDto> Items { get; set; } = new();
}
// ============================================================================
// LINE ITEMS
// ============================================================================
public class PurchaseOrderItemDto
{
public int Id { get; set; }
public int PurchaseOrderId { get; set; }
public int? InventoryItemId { get; set; }
public string ItemName { get; set; } = string.Empty; // Inventory item name OR custom description
public string ItemSKU { get; set; } = string.Empty;
public string UnitOfMeasure { get; set; } = string.Empty;
public bool IsCustomItem => InventoryItemId == null;
public decimal QuantityOrdered { get; set; }
public decimal QuantityReceived { get; set; }
public decimal UnitCost { get; set; }
public decimal LineTotal { get; set; }
public string? Notes { get; set; }
public bool IsFullyReceived => QuantityReceived >= QuantityOrdered;
public decimal QuantityRemaining => Math.Max(0, QuantityOrdered - QuantityReceived);
}
public class CreatePurchaseOrderItemDto
{
// Null = custom/non-inventory line item
public int? InventoryItemId { get; set; }
// Required when InventoryItemId is null
[StringLength(200)]
public string? Description { get; set; }
[StringLength(50)]
public string? UnitOfMeasure { get; set; }
[Required]
[Range(0.001, 999999, ErrorMessage = "Quantity must be greater than 0")]
public decimal QuantityOrdered { get; set; }
[Required]
[Range(0, 999999)]
public decimal UnitCost { get; set; }
[StringLength(500)]
public string? Notes { get; set; }
}
// ============================================================================
// RECEIVING
// ============================================================================
public class ReceivePurchaseOrderDto
{
[Required]
[Display(Name = "Received Date")]
public DateTime ReceivedDate { get; set; } = DateTime.Today;
[StringLength(500)]
public string? Notes { get; set; }
public List<ReceiveItemDto> Items { get; set; } = new();
}
public class ReceiveItemDto
{
public int PurchaseOrderItemId { get; set; }
public int? InventoryItemId { get; set; }
public string ItemName { get; set; } = string.Empty;
public string ItemSKU { get; set; } = string.Empty;
public string UnitOfMeasure { get; set; } = string.Empty;
public decimal QuantityOrdered { get; set; }
public decimal QuantityAlreadyReceived { get; set; }
public decimal QuantityRemaining { get; set; }
[Range(0, 999999)]
public decimal QuantityToReceive { get; set; }
}