using AyCode.Services.Nav; using AyCode.Services.Nav.Ekaer; using AyCode.Services.Nav.Ekaer.Models; using FruitBank.Common.Dtos; using FruitBank.Common.Entities; using FruitBank.Common.Services.Ekaer; namespace FruitBank.Common.Server.Services.Ekaer; /// /// /// A teljes lánc: map (, FruitBank.Common) → /// validate → send (, AyCode.Services). A saját cégadatot /// () és a NAV-fiók hitelesítő adatait a DI szolgáltatja. /// public sealed class FruitBankEkaerService : IFruitBankEkaerService { private readonly IShippingToEkaerMapper _mapper; private readonly IEkaerSubmitService _submitService; private readonly IEkaerTradeCardValidator _validator; private readonly IEkaerSettings _settings; public FruitBankEkaerService(IShippingToEkaerMapper mapper, IEkaerSubmitService submitService, IEkaerTradeCardValidator validator, IEkaerSettings settings) { _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); _submitService = submitService ?? throw new ArgumentNullException(nameof(submitService)); _validator = validator ?? throw new ArgumentNullException(nameof(validator)); _settings = settings ?? throw new ArgumentNullException(nameof(settings)); } public Task SubmitShippingAsync(Shipping shipping, OperationType operation = OperationType.Create, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(shipping); // map (FruitBank.Common) → submit: validate → send (AyCode.Services) var operations = _mapper.MapShipping(shipping, _settings.Company, operation); return _submitService.SubmitAsync(operations, cancellationToken); } public EkaerHistory GenerateEkaerXmlDocument(ShippingDocument document, EkaerHistory? ekaerHistory = null) { ArgumentNullException.ThrowIfNull(document); ekaerHistory ??= new EkaerHistory { ForeignKey = document.Id, IsOutgoing = false }; var currency = document.Partner?.Currency; return TryConfigError(ekaerHistory, currency) ?? Finalize(ekaerHistory, _mapper.MapDocument(document, _settings.Company), currency); } public EkaerHistory GenerateEkaerXmlDocument(OrderDto order, EkaerHistory? ekaerHistory = null) { ArgumentNullException.ThrowIfNull(order); ekaerHistory ??= new EkaerHistory { ForeignKey = order.Id, IsOutgoing = true }; // Kimenő pénznem: jelenleg minden HUF (a deviza az OrderDto-ba kerül, amint bekötik) → ConversionRate = 1. const string currency = "HUF"; return TryConfigError(ekaerHistory, currency) ?? Finalize(ekaerHistory, _mapper.MapOrder(order, _settings.Company), currency); } /// Config-kapu: külföldi (nem HUF) feladónál az árfolyam kötelező — különben a leképezés ELŐTT /// ValidationError (nincs félrevezető XML). null = rendben, mehet a generálás. private EkaerHistory? TryConfigError(EkaerHistory ekaerHistory, string? currency) { if (EkaerValueCalculator.IsHuf(currency) || _settings.EurHufRate > 0) return null; ekaerHistory.Status = EkaerStatus.ValidationError; ekaerHistory.ErrorText = "EKÁER EUR-HUF árfolyam nincs konfigurálva (appsettings Ekaer:ExchangeRate:EurHuf) — a tétel-érték nem számolható."; return ekaerHistory; } /// Közös befejezés (bejövő/kimenő): validál, szerializál; az XML validációs hibánál IS tárolódik /// (a detail-nézethez), és rögzíti a ténylegesen alkalmazott árfolyamot (HUF → 1, külföldi → FX-ráta). private EkaerHistory Finalize(EkaerHistory ekaerHistory, TradeCardType tradeCard, string? currency) { var operation = new TradeCardOperationType { Index = 1, Operation = OperationType.Create, TradeCard = tradeCard }; var errors = _validator.Validate(operation); ekaerHistory.XmlDoc = NavXmlHelper.Serialize(tradeCard); ekaerHistory.ConversionRate = EkaerValueCalculator.ResolveRateToHuf(currency, _settings.EurHufRate); ekaerHistory.Status = errors.Count == 0 ? EkaerStatus.Generated : EkaerStatus.ValidationError; ekaerHistory.ErrorText = errors.Count == 0 ? null : string.Join(Environment.NewLine, errors.Select(e => e.ErrorMessage)); return ekaerHistory; } }