using AyCode.Core.Serializers.Attributes; using AyCode.Core.Serializers.Toons; using FruitBank.Common.Enums; using LinqToDB.Mapping; using Mango.Nop.Core.Entities; namespace FruitBank.Common.Entities; [AcBinarySerializable(false, true, false, true, false, false)] [Table(Name = FruitBankConstClient.OrderDraftDbTableName)] [System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.OrderDraftDbTableName)] [ToonDescription("AI-parsed order draft created from an incoming text message", Purpose = "Temporary order intent parsed from a free-text message (Viber, email, dictation). Contains the original raw message and AI-resolved line items. An admin must review and approve within 24 hours; drafts are auto-expired after 14 days. Approval converts the draft into a PreOrder or Order depending on ParsedDeliveryDate.")] public sealed class OrderDraft : MgEntityBase { [ToonDescription(Purpose = "The external identifier of the sender (e.g. Viber user ID, email address). Used to look up the mapped NopCommerce CustomerId via ExternalUserPartnerMap.")] public string ExternalUsername { get; set; } = string.Empty; [ToonDescription(Purpose = "FK to the NopCommerce Customer resolved from ExternalUsername. Null if no mapping exists yet — admin must assign before approval.")] public int? CustomerId { get; set; } [ToonDescription(Purpose = "The full original message text as received. Stored verbatim and shown to the admin during review.")] public string RawMessageText { get; set; } = string.Empty; [ToonDescription(Purpose = "Delivery date parsed from the message by AI. Drives IsPreorder logic on each item (>4 days ahead = preorder).")] public DateTime ParsedDeliveryDate { get; set; } [ToonDescription(Purpose = "Draft lifecycle: Pending / Approved / Rejected / Expired.", BusinessRule = "Pending on creation. Admin sets Approved or Rejected. Background job sets Expired after 14 days if still Pending.")] public OrderDraftStatus Status { get; set; } [ToonDescription(Purpose = "Admin who resolved (approved or rejected) this draft. Null until resolved.")] public int? ResolvedByAdminId { get; set; } [ToonDescription(Purpose = "Optional admin note on rejection.")] public string? AdminNote { get; set; } public DateTime CreatedOnUtc { get; set; } public DateTime? ResolvedOnUtc { get; set; } public List Items { get; set; } = []; }