diff --git a/Nop.Plugin.Misc.AIPlugin/Controllers/FruitBankDataController.cs b/Nop.Plugin.Misc.AIPlugin/Controllers/FruitBankDataController.cs index 961128f..d07fb60 100644 --- a/Nop.Plugin.Misc.AIPlugin/Controllers/FruitBankDataController.cs +++ b/Nop.Plugin.Misc.AIPlugin/Controllers/FruitBankDataController.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using AyCode.Core.Extensions; using AyCode.Core.Loggers; +using AyCode.Services.Nav.Ekaer; using AyCode.Services.SignalRs; using DocumentFormat.OpenXml.Office2010.Excel; using FruitBank.Common.Dtos; @@ -44,7 +45,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers ILocalizationService localizationService, PreOrderConversionService preorderConversionService, IFruitBankEkaerService fruitBankEkaerService, - EkaerSettings ekaerSettings, + IEkaerSettings ekaerSettings, IEnumerable logWriters) : BasePluginController, IFruitBankDataControllerServer { @@ -313,17 +314,27 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers } [SignalR(SignalRTags.GenerateEkaerXmlDocument)] - public async Task GenerateEkaerXmlDocument(int shippingDocumentId) + public async Task GenerateEkaerXmlDocument(int foreignKey, bool isOutgoing) { - _logger.Detail($"GenerateEkaerXmlDocument invoked; shippingDocumentId: {shippingDocumentId}"); + _logger.Detail($"GenerateEkaerXmlDocument invoked; foreignKey: {foreignKey}; isOutgoing: {isOutgoing}"); - // A GetAll(true) a mapperhez kellő teljes gráfot tölti: Partner, Items+ProductDto, Shipping→járművek/fuvarozó. - var shippingDocument = await ctx.ShippingDocuments.GetByIdAsync(shippingDocumentId, true) - ?? throw new ArgumentException($"ShippingDocument not found; id: {shippingDocumentId}", nameof(shippingDocumentId)); + // Upsert: (ForeignKey + IsOutgoing) párra EGY rekord — az újragenerálás nem duplikál. + var ekaerHistory = await ctx.EkaerHistories.GetByForeignKey(foreignKey).FirstOrDefaultAsync(eh => eh.IsOutgoing == isOutgoing); - // Upsert: dokumentumonként EGY bejövő rekord (ForeignKey + IsOutgoing) — az újragenerálás nem duplikál. - var ekaerHistory = await ctx.EkaerHistories.GetByForeignKey(shippingDocumentId).FirstOrDefaultAsync(eh => !eh.IsOutgoing); - ekaerHistory = fruitBankEkaerService.GenerateEkaerXmlDocument(shippingDocument, ekaerHistory); + if (!isOutgoing) + { + // Bejövő: a GetAll(true) a mapperhez kellő teljes gráfot tölti (Partner, Items+ProductDto, Shipping→járművek). + var shippingDocument = await ctx.ShippingDocuments.GetByIdAsync(foreignKey, true) + ?? throw new ArgumentException($"ShippingDocument not found; id: {foreignKey}", nameof(foreignKey)); + ekaerHistory = fruitBankEkaerService.GenerateEkaerXmlDocument(shippingDocument, ekaerHistory); + } + else + { + // Kimenő: a GetByIdAsync(true) betölti a Customer-t, tételeket, palettákat (GrossWeight) és a ProductDto-t. + var order = await ctx.OrderDtos.GetByIdAsync(foreignKey, true) + ?? throw new ArgumentException($"Order not found; id: {foreignKey}", nameof(foreignKey)); + ekaerHistory = fruitBankEkaerService.GenerateEkaerXmlDocument(order, ekaerHistory); + } if (ekaerHistory.Id > 0) await ctx.EkaerHistories.UpdateAsync(ekaerHistory); else await ctx.EkaerHistories.InsertAsync(ekaerHistory); diff --git a/Nop.Plugin.Misc.AIPlugin/Infrastructure/PluginNopStartup.cs b/Nop.Plugin.Misc.AIPlugin/Infrastructure/PluginNopStartup.cs index 6a09561..6f6059d 100644 --- a/Nop.Plugin.Misc.AIPlugin/Infrastructure/PluginNopStartup.cs +++ b/Nop.Plugin.Misc.AIPlugin/Infrastructure/PluginNopStartup.cs @@ -44,6 +44,7 @@ using System.Net.Http.Headers; using Mango.Nop.Core.Loggers; using AyCode.Services.Nav; using AyCode.Services.Nav.Ekaer; +using AyCode.Services.Nav.Ekaer.Models; using FruitBank.Common.Services.Ekaer; using FruitBank.Common.Server.Services.Ekaer; using System.Security.Authentication; @@ -193,12 +194,14 @@ public class PluginNopStartup : INopStartup BaseUrl = c["BaseUrl"] ?? "https://import-test-b.ekaer.nav.gov.hu", // TEST; PROD: https://import.ekaer.nav.gov.hu }; }); - // EKÁER konfiguráció — egyetlen objektum (cégadat + küszöb + árfolyam), configból (appsettings "Ekaer"). - // A bejelentő cégadata: a NAV-helyes 11-jegyű adószám + telefon/e-mail itt adható meg, a webshop Store-tól függetlenül. - services.AddSingleton(sp => + + // EKÁER konfiguráció (cégadat + telephely + küszöb + árfolyam), configból (appsettings "Ekaer"). + // IEkaerSettings-ként kötjük be (AyCode-kontraktus) — a fogyasztók az interfészt kérik, mint az INavCredentials-t. + services.AddSingleton(sp => { var c = sp.GetRequiredService().GetSection("Ekaer"); var co = c.GetSection("Company"); + var site = co.GetSection("Site"); return new EkaerSettings { Company = new EkaerCompanyInfo @@ -209,13 +212,26 @@ public class PluginNopStartup : INopStartup PostalCode = co["PostalCode"], City = co["City"], Street = co["Street"], - // UnloadLocation (saját telephely): magyar címnél a NAV Name/VatNumber/Phone/Email-t is kér — TODO összeállítani. + // Telephely = fizikai fel-/lerakodási hely (bejövőnél lerakodás, kimenőnél felrakodás). + // Magyar címnél a NAV Name/VatNumber/Phone/Email-t is megköveteli. Ha = székhely, ugyanaz a cím. + Site = new LocationType + { + Name = co["Name"], + VatNumber = co["TaxId"], + Country = co["CountryCode"] ?? "HU", + ZipCode = site["PostalCode"], + City = site["City"], + Street = site["Street"], + Phone = co["Phone"], + Email = co["Email"], + }, }, + // Default ÉRTÉK szándékosan nincs: be nem töltött config → 0. A 0 árfolyam a számításkor hibát dob, // a 0 küszöb „mindent jelentünk" — egyik sem számol elavult, kódba égetett értékkel. EurHufRate = c.GetValue("ExchangeRate:EurHuf"), ThresholdWeightKg = c.GetValue("Thresholds:WeightKg"), - ThresholdValueHuf = c.GetValue("Thresholds:ValueHuf"), + ThresholdValueHuf = c.GetValue("Thresholds:ValueHuf"), }; }); diff --git a/Nop.Plugin.Misc.AIPlugin/docs/EKAER/EKAER_TODO.md b/Nop.Plugin.Misc.AIPlugin/docs/EKAER/EKAER_TODO.md index 4bf7412..67127b0 100644 --- a/Nop.Plugin.Misc.AIPlugin/docs/EKAER/EKAER_TODO.md +++ b/Nop.Plugin.Misc.AIPlugin/docs/EKAER/EKAER_TODO.md @@ -16,12 +16,12 @@ A `ShippingToEkaerMapper` megírása előtt tisztázandó pontok. Minden sor a j | # | Téma | Jelenlegi feltételezés | Nyitott kérdés | |---|------|------------------------|----------------| | 1 | `tradeType` (E/I/D irány) | Bejövő = beszerzés. HU feladó → **D** (belföldi), egyébként → **I** (import). A feladó országát a `ShippingDocument.Partner` / `Country` adja. | Automatikusan az országból dőljön el, vagy kézzel (UI) állítható? A kimenő (**E**, export) egyelőre hatókörön kívül (lásd #7). | -| 2 | Célhely (destination) | Hardcode-olt FruitBank-telephely (cím). | Ne hardcode legyen — konfigból/beállításból jöjjön. Honnan (plugin settings / nopCommerce warehouse)? | +| 2 | Célhely / telephely | ✅ **Megoldva:** configból (`Ekaer:Company` + `Site` al-szekció) → `IEkaerSettings.Company` + `EkaerCompanyInfo.Site` (`LocationType`, fel-/lerakodás). Nincs hardcode. | Több telephely (mint a `PartnerDepot`) — későbbi, ha kell. | | 3 | Érték (`value`, HUF) | ✅ **Megoldva:** `UnitPriceOnDocument × QuantityOnDocument × árfolyam` (`EkaerValueCalculator`). Pénznem a `Partner.Currency`-ből; EUR-HUF árfolyam configból (`Ekaer:ExchangeRate:EurHuf`, MNB középárfolyam). | Árfolyam dinamizálása (jelenleg „drót" config-érték) — későbbi. | | 4 | Tömeg (`weight`) | `ShippingItem.MeasuredGrossWeight` (bruttó). | Az EKÁER **bruttó** tömeget vár — megerősíteni, hogy ez bruttó és nem nettó. | | 5 | Granularitás | 1 `ShippingDocument` → 1 `tradeCard`; 1 `Shipping` → több művelet (több dokumentum). | Megerősíteni: tényleg dokumentumonként egy tradeCard? | | 6 | Eladó (`seller*`) mezők | `ShippingDocument.Partner`-ből: `Name`, `TaxId` (első 8 jegy = adószám-törzs), `CountryCode`, `City`, `Street`, `PostalCode`. | A `Partner` (`PartnerBase`) pontos mezőnevei/forrásai — megerősíteni. | -| 7 | Kimenő irány (`Order` → EKÁER) | Egyelőre nincs. A vevő gyakran maga viszi el (saját fuvar) → nem mi jelentünk. | Mikor kell mégis nekünk export/kimenő (E) tradeCard-ot küldeni? | +| 7 | Kimenő irány (`Order` → EKÁER) | ✅ **Implementálva** (`MapOrder`): belföldi értékesítés (**D**/**S**), mi=eladó, vevő=címzett; tömeg `OrderItemDto.GrossWeight`, érték nettó (UnitPriceExclTax × qty), jelenleg minden HUF (rate 1). | **Nyitott:** a vonó jármű / fuvarozó forrása — az Orderen NINCS; az OrderDto-ba bekötendő (a `MapOrder` `Vehicle`/`CarrierText` TODO-ja). Export (**E**) + külföldi deviza + a `Customer.CountryId` ISO-feloldása: későbbi. | | 8 | `productVtsz` forrás | `ProductDto.Gtin` (átmeneti). | GTIN ≠ VTSZ — lásd [`MGFBANKPLUG-EKAER-I-T3X8`](EKAER_ISSUES.md). Hosszú távon külön `Vtsz` mező. | | 9 | tétel `tradeReason` | `A` (beszerzés) — a mapper ezt használja bejövő árura. | Korábban tévesen `S`-nek feltételezve; az enum valójában `S`=értékesítés, `A`=beszerzés. Üzletileg megerősítendő. | | 10 | `value` mező | ✅ **Megoldva:** a value most töltve (lásd #3); 0 / ismeretlen ár esetén `null` marad. | A NAV 2021-től `value > 0`-t vár — a validátorban a `value > 0` üzleti szabály még hozzáadandó. |