EKAER: add site config, outgoing support, refactor settings
- Added "Site" section to appsettings.json for company location. - Increased EKAER threshold values; updated phone format. - Refactored to use IEkaerSettings DI and registered in startup. - GenerateEkaerXmlDocument now supports both incoming and outgoing (order) documents. - Updated EKAER_TODO.md to reflect config and outgoing mapping changes.
This commit is contained in:
parent
f1db5a9a99
commit
cd49b572ad
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AyCode.Core.Extensions;
|
using AyCode.Core.Extensions;
|
||||||
using AyCode.Core.Loggers;
|
using AyCode.Core.Loggers;
|
||||||
|
using AyCode.Services.Nav.Ekaer;
|
||||||
using AyCode.Services.SignalRs;
|
using AyCode.Services.SignalRs;
|
||||||
using DocumentFormat.OpenXml.Office2010.Excel;
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||||
using FruitBank.Common.Dtos;
|
using FruitBank.Common.Dtos;
|
||||||
|
|
@ -44,7 +45,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||||
ILocalizationService localizationService,
|
ILocalizationService localizationService,
|
||||||
PreOrderConversionService preorderConversionService,
|
PreOrderConversionService preorderConversionService,
|
||||||
IFruitBankEkaerService fruitBankEkaerService,
|
IFruitBankEkaerService fruitBankEkaerService,
|
||||||
EkaerSettings ekaerSettings,
|
IEkaerSettings ekaerSettings,
|
||||||
IEnumerable<IAcLogWriterBase> logWriters)
|
IEnumerable<IAcLogWriterBase> logWriters)
|
||||||
: BasePluginController, IFruitBankDataControllerServer
|
: BasePluginController, IFruitBankDataControllerServer
|
||||||
{
|
{
|
||||||
|
|
@ -313,17 +314,27 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
[SignalR(SignalRTags.GenerateEkaerXmlDocument)]
|
[SignalR(SignalRTags.GenerateEkaerXmlDocument)]
|
||||||
public async Task<EkaerHistory> GenerateEkaerXmlDocument(int shippingDocumentId)
|
public async Task<EkaerHistory> 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ó.
|
// Upsert: (ForeignKey + IsOutgoing) párra EGY rekord — az újragenerálás nem duplikál.
|
||||||
var shippingDocument = await ctx.ShippingDocuments.GetByIdAsync(shippingDocumentId, true)
|
var ekaerHistory = await ctx.EkaerHistories.GetByForeignKey(foreignKey).FirstOrDefaultAsync(eh => eh.IsOutgoing == isOutgoing);
|
||||||
?? throw new ArgumentException($"ShippingDocument not found; id: {shippingDocumentId}", nameof(shippingDocumentId));
|
|
||||||
|
|
||||||
// Upsert: dokumentumonként EGY bejövő rekord (ForeignKey + IsOutgoing) — az újragenerálás nem duplikál.
|
if (!isOutgoing)
|
||||||
var ekaerHistory = await ctx.EkaerHistories.GetByForeignKey(shippingDocumentId).FirstOrDefaultAsync(eh => !eh.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);
|
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);
|
if (ekaerHistory.Id > 0) await ctx.EkaerHistories.UpdateAsync(ekaerHistory);
|
||||||
else await ctx.EkaerHistories.InsertAsync(ekaerHistory);
|
else await ctx.EkaerHistories.InsertAsync(ekaerHistory);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ using System.Net.Http.Headers;
|
||||||
using Mango.Nop.Core.Loggers;
|
using Mango.Nop.Core.Loggers;
|
||||||
using AyCode.Services.Nav;
|
using AyCode.Services.Nav;
|
||||||
using AyCode.Services.Nav.Ekaer;
|
using AyCode.Services.Nav.Ekaer;
|
||||||
|
using AyCode.Services.Nav.Ekaer.Models;
|
||||||
using FruitBank.Common.Services.Ekaer;
|
using FruitBank.Common.Services.Ekaer;
|
||||||
using FruitBank.Common.Server.Services.Ekaer;
|
using FruitBank.Common.Server.Services.Ekaer;
|
||||||
using System.Security.Authentication;
|
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
|
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.
|
// EKÁER konfiguráció (cégadat + telephely + küszöb + árfolyam), configból (appsettings "Ekaer").
|
||||||
services.AddSingleton(sp =>
|
// IEkaerSettings-ként kötjük be (AyCode-kontraktus) — a fogyasztók az interfészt kérik, mint az INavCredentials-t.
|
||||||
|
services.AddSingleton<IEkaerSettings>(sp =>
|
||||||
{
|
{
|
||||||
var c = sp.GetRequiredService<IConfiguration>().GetSection("Ekaer");
|
var c = sp.GetRequiredService<IConfiguration>().GetSection("Ekaer");
|
||||||
var co = c.GetSection("Company");
|
var co = c.GetSection("Company");
|
||||||
|
var site = co.GetSection("Site");
|
||||||
return new EkaerSettings
|
return new EkaerSettings
|
||||||
{
|
{
|
||||||
Company = new EkaerCompanyInfo
|
Company = new EkaerCompanyInfo
|
||||||
|
|
@ -209,13 +212,26 @@ public class PluginNopStartup : INopStartup
|
||||||
PostalCode = co["PostalCode"],
|
PostalCode = co["PostalCode"],
|
||||||
City = co["City"],
|
City = co["City"],
|
||||||
Street = co["Street"],
|
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,
|
// 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.
|
// a 0 küszöb „mindent jelentünk" — egyik sem számol elavult, kódba égetett értékkel.
|
||||||
EurHufRate = c.GetValue<double>("ExchangeRate:EurHuf"),
|
EurHufRate = c.GetValue<double>("ExchangeRate:EurHuf"),
|
||||||
ThresholdWeightKg = c.GetValue<double>("Thresholds:WeightKg"),
|
ThresholdWeightKg = c.GetValue<double>("Thresholds:WeightKg"),
|
||||||
ThresholdValueHuf = c.GetValue<long>("Thresholds:ValueHuf"),
|
ThresholdValueHuf = c.GetValue<int>("Thresholds:ValueHuf"),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 |
|
| # | 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). |
|
| 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. |
|
| 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ó. |
|
| 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? |
|
| 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. |
|
| 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ő. |
|
| 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ő. |
|
| 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ó. |
|
| 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ó. |
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue