using ERPCore.Domain.Enums;

namespace ERPCore.Domain.Entities;

/// <summary>
/// Goods Receipt Note header (FR-GRN-01/02). Raised against a PO or direct
/// (<see cref="PoId"/> null). On confirm each line creates a FIFO layer and posts
/// an inbound ledger entry. Mutable aggregate with an <see cref="RowVersion"/>
/// concurrency token (docs/10 C.10). Model: docs/10 Part C.3.
/// </summary>
public class Grn
{
    public int GrnId { get; set; }
    public string DocNo { get; set; } = string.Empty;

    public int? PoId { get; set; }
    public PurchaseOrder? PurchaseOrder { get; set; }

    public int VendorId { get; set; }
    public Vendor? Vendor { get; set; }

    public int WarehouseId { get; set; }
    public Warehouse? Warehouse { get; set; }

    public GrnStatus Status { get; set; } = GrnStatus.Draft;

    public int CreatedBy { get; set; }
    public User? Creator { get; set; }

    public DateTime CreatedAt { get; set; }
    public DateTime? PostedAt { get; set; }

    /// <summary>Journal number of the real GL journal entry posted for this GRN's receipt (set on confirm).</summary>
    public string? GlJournalNo { get; set; }
    public DateTime? GlPostedAt { get; set; }

    /// <summary>Sum of vendor payments made against this GRN's total payable (<see cref="GrnLine.LineTotal"/>).</summary>
    public decimal PaidAmount { get; set; }
    /// <summary>Total payable minus <see cref="PaidAmount"/>; installments accrue against this until it reaches zero.</summary>
    public decimal BalanceAmount { get; set; }

    /// <summary>PostgreSQL xmin-backed optimistic concurrency token.</summary>
    public uint RowVersion { get; set; }

    public ICollection<GrnLine> Lines { get; set; } = new List<GrnLine>();
    public ICollection<GrnPayment> Payments { get; set; } = new List<GrnPayment>();
}
