using System.Text.Json.Serialization;
using AyCode.Core.Serializers.Attributes;
using AyCode.Core.Serializers.Toons;
using AyCode.Interfaces.TimeStampInfo;
using LinqToDB;
using LinqToDB.Mapping;
using Mango.Nop.Core.Entities;
namespace FruitBank.Common.Entities;
[AcBinarySerializable(false, true, false, true, false, false)]
[ToonDescription("NAV EKÁER declaration lifecycle record", Purpose = "Work-queue and audit row for one EKÁER road-freight declaration — one row per tradeCard: an incoming ShippingDocument (delivery note) or a completed outgoing Order. Tracks the declaration through generation, validation and submission to the Hungarian tax authority (NAV).")]
[Table(Name = FruitBankConstClient.EkaerHistoryDbTableName)]
[System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.EkaerHistoryDbTableName)]
public sealed class EkaerHistory: MgEntityBase, ITimeStampInfo
{
[ToonDescription(Purpose = "Id of the source entity the declaration belongs to: ShippingDocument.Id when IsOutgoing is false (one declaration per delivery note, matching NAV's one-TCN-per-tradeCard granularity), Order id when IsOutgoing is true.")]
public int ForeignKey { get; set; }
[ToonDescription(Purpose = "Direction of the goods movement: false = incoming shipment (Shipping), true = outgoing delivery (Order).")]
public bool IsOutgoing { get; set; }
[ToonDescription(Purpose = "Lifecycle state of the declaration, stored as int (see EkaerStatus): 0 Pending (auto-created, not yet generated), 1 Generated (tradeCard XML produced and valid), 2 ValidationError (generation produced errors, see ErrorText), 3 Sent (accepted by NAV, EkaerNumber filled), 4 SendError (NAV call failed, see ErrorText).")]
public int StatusId { get; set; }
/// A enum-nézete. A tárolt érték az int oszlop (StatusId) — a linq2db réteg
/// az enum-property-t nem perzisztálta (az oszlop kimaradt az insertből, a DB default írt 0-t), ezért a nop-minta:
/// int oszlop + nem-mappelt enum wrapper.
[NotColumn, System.ComponentModel.DataAnnotations.Schema.NotMapped, Newtonsoft.Json.JsonIgnore, JsonIgnore]
public EkaerStatus Status
{
get => (EkaerStatus)StatusId;
set => StatusId = (int)value;
}
[ToonDescription(Purpose = "The generated NAV EKÁER tradeCard request XML exactly as it was (or will be) submitted — audit copy and source of the read-only detail view. Null until the first Generate.")]
public string? XmlDoc { get; set; }
[Column(DataType = DataType.DecFloat)]
[ToonDescription(Purpose = "The conversion rate actually applied when computing this declaration's item values to HUF: 1 for domestic (HUF) suppliers (no conversion), the FX rate (e.g. EUR→HUF) for foreign suppliers. Null before the first Generate. Currency-agnostic by design — works for any source currency. Audit trail: the invoice amount times this rate yields the HUF value in the tradeCard; the NAV schema has no rate field, so this column preserves how the value was derived.")]
public double? ConversionRate { get; set; }
[ToonDescription(Purpose = "The EKÁER number (TCN) assigned by NAV after a successful submission. Null until the declaration is accepted.")]
public string? EkaerNumber { get; set; }
[ToonDescription(Purpose = "When the declaration was successfully submitted to NAV. Null until sent.")]
public DateTime? SentDate { get; set; }
[ToonDescription(Purpose = "Validation or NAV submission error details for the ValidationError / SendError states. Null when the last operation succeeded.")]
public string? ErrorText { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
}
/// Az EKÁER-bejelentés életciklus + kimenet állapota. Append-only: új érték a végére, meglévő értéke nem
/// változhat (DB-ben int-ként tárolt). Az állapot egyetlen mező; a kategorizálás a
/// segédekkel megy (külön oszlop nélkül) — a folyamat lineáris, ezért a single-enum állapotgép a tiszta illeszkedés.
public enum EkaerStatus
{
/// Automatikusan létrejött, még nem volt Generate.
Pending = 0,
/// A tradeCard XML legenerálva és valid — küldhető.
Generated = 1,
/// A Generate BLOKKOLÓ (error) hibákkal zárult (ErrorText) — a forrásadat javítandó, nem küldhető.
ValidationError = 2,
/// NAV által befogadva (EkaerNumber + SentDate töltve), hiánytalanul.
Sent = 3,
/// A NAV-hívás hibával zárult (ErrorText) — újraküldhető.
SendError = 4,
/// Legenerálva és KÜLDHETŐ, de warninggal (pl. hiányzó rendszám, ami a felrakodás megkezdéséig pótolható).
GeneratedWithWarning = 5,
/// NAV-hoz beküldve, de PÓTLÁSRA VÁR (pl. a rendszám a felrakodás megkezdéséig megadandó).
SentWithMissingData = 6,
}
/// Állapot-kategóriák — a tárolás egy mező (Status), a csoportosítás ezekkel (külön oszlop nélkül).
public static class EkaerStatusExtensions
{
/// Blokkoló hibás állapot (a bejelentés nem küldhető / a NAV-hívás bukott).
public static bool IsError(this EkaerStatus status) => status is EkaerStatus.ValidationError or EkaerStatus.SendError;
/// Beküldhető: legenerálva, blokkoló hiba nélkül (warninggal is) — innen mehet a NAV-hoz.
public static bool IsSubmittable(this EkaerStatus status) => status is EkaerStatus.Generated or EkaerStatus.GeneratedWithWarning;
/// A NAV-nál van (akár hiányosan).
public static bool IsSent(this EkaerStatus status) => status is EkaerStatus.Sent or EkaerStatus.SentWithMissingData;
/// Elküldve, de pótlásra vár (hiányos adat — pl. rendszám).
public static bool NeedsCompletion(this EkaerStatus status) => status is EkaerStatus.SentWithMissingData;
}
/// EkaerHistory-lekérdezés szűrő a tabokhoz. = 0 (minden) — szándékosan explicit, NEM nullable,
/// hogy ne kelljen null-t kezelni sehol; a default érték (0) automatikusan „minden", ami biztonságos.
public enum EkaerHistoryFilter
{
/// Minden rekord (nincs szűrés).
All = 0,
/// Beküldésre váró: minden, ami még NINCS a NAV-nál (Pending/Generated/GeneratedWithWarning/ValidationError/SendError).
ToSubmit,
/// Elküldött és hiánytalan ().
Sent,
/// Elküldve, de pótlásra vár ().
NeedsCompletion,
}
//public sealed class EkaerHistoryShipping : EkaerHistoryBase
//{
// public int ShippingId
// {
// get => ForeignItemId;
// set => ForeignItemId = value;
// }
// [Association(ThisKey = nameof(ShippingId), OtherKey = nameof(Shipping.Id), CanBeNull = true)]
// public Shipping? Shipping { get; set; }
//}
//public sealed class EkaerHistoryOrder : EkaerHistoryBase
//{
// public int ShippingId
// {
// get => ForeignItemId;
// set => ForeignItemId = value;
// }
// [Association(ThisKey = nameof(ShippingId), OtherKey = nameof(Shipping.Id), CanBeNull = true)]
// public Shipping? Shipping { get; set; }
//}
//public abstract class EkaerHistoryBase : MgEntityBase, ITimeStampInfo
//{
// [NotColumn]
// protected int ForeignItemId;
// [NotColumn]
// [ToonDescription(BusinessRule = "get => ForeignItemId", Constraints = "[#SmartTypeConstraints]")]
// public int ForeignKey => ForeignItemId;
// public DateTime Created { get; set; }
// public DateTime Modified { get; set; }
//}