using foodmarket.Domain.Catalog; using foodmarket.Domain.Common; namespace foodmarket.Domain.Inventory; public enum LossStatus { Draft = 0, Posted = 1, } /// Причина списания. Из этого классификатора строятся ABC/XYZ-отчёты /// и фискальная отчётность (порча/просрочка) в KZ. Не строй наценочную логику /// поверх этих значений — используй ровно как business reason. public enum LossReason { /// Брак (производственный/транспортный). Defect = 0, /// Просрочка / истёк срок годности. Expired = 1, /// Повреждение (механическое, при хранении/перевозке). Damage = 2, /// Недостача (выявлена инвентаризацией; для оформления свыше — отдельный документ инвентаризации). Shortage = 3, /// Прочая причина (в комментарии). Other = 99, } /// Документ списания со склада: брак, просрочка, недостача, повреждение. /// При проведении создаёт с типом /// и отрицательным Quantity. public class Loss : TenantEntity { public string Number { get; set; } = ""; public DateTime Date { get; set; } = DateTime.UtcNow; public LossStatus Status { get; set; } = LossStatus.Draft; public Guid StoreId { get; set; } public Store Store { get; set; } = null!; public Guid CurrencyId { get; set; } public Currency Currency { get; set; } = null!; public LossReason Reason { get; set; } = LossReason.Other; public string? Notes { get; set; } /// Сумма по строкам = Σ Quantity·UnitCost. Балансовая стоимость списания. public decimal Total { get; set; } /// Если документ создан «на основании инвентаризации» (недостача) — /// ссылка на неё. Иначе null (обычное списание брака/просрочки). public Guid? InventoryDocId { get; set; } public DateTime? PostedAt { get; set; } public Guid? PostedByUserId { get; set; } public ICollection Lines { get; set; } = new List(); /// Id сущности в МойСкладе — для идемпотентного переноса истории. public string? MoySkladExternalId { get; set; } } public class LossLine : TenantEntity { public Guid LossId { get; set; } public Loss Loss { get; set; } = null!; public Guid ProductId { get; set; } public Product Product { get; set; } = null!; public decimal Quantity { get; set; } /// Балансовая цена единицы (снимок Product.Cost на момент создания строки; /// можно переопределить). Используется в Total и в отчётности. public decimal UnitCost { get; set; } public decimal LineTotal { get; set; } public int SortOrder { get; set; } }