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; }
}