diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 3d148c8f..85101802 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -67,7 +67,8 @@
"Bash(grep -c -a \"ConversionRate\" FruitBank.Common.dll)",
"Bash(grep -c -a \"ConversionRate\" FruitBank.Common.Server.dll)",
"Bash(grep -c -a \"EurHufRate\" FruitBank.Common.dll FruitBank.Common.Server.dll)",
- "Bash(ls -la --time-style=+%H:%M FruitBank.Common.dll FruitBank.Common.Server.dll)"
+ "Bash(ls -la --time-style=+%H:%M FruitBank.Common.dll FruitBank.Common.Server.dll)",
+ "Bash(find \"H:\\\\\\\\Applications\\\\\\\\Mango\" -name \"Order.cs\" -path \"*/Domain/Orders/*\" 2>&1 | head -3)"
]
}
}
diff --git a/FruitBank.Common.Server/Services/Ekaer/FruitBankEkaerService.cs b/FruitBank.Common.Server/Services/Ekaer/FruitBankEkaerService.cs
index 9e21f0b8..3c1004e3 100644
--- a/FruitBank.Common.Server/Services/Ekaer/FruitBankEkaerService.cs
+++ b/FruitBank.Common.Server/Services/Ekaer/FruitBankEkaerService.cs
@@ -1,6 +1,7 @@
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;
@@ -17,9 +18,9 @@ public sealed class FruitBankEkaerService : IFruitBankEkaerService
private readonly IShippingToEkaerMapper _mapper;
private readonly IEkaerSubmitService _submitService;
private readonly IEkaerTradeCardValidator _validator;
- private readonly EkaerSettings _settings;
+ private readonly IEkaerSettings _settings;
- public FruitBankEkaerService(IShippingToEkaerMapper mapper, IEkaerSubmitService submitService, IEkaerTradeCardValidator validator, EkaerSettings 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));
@@ -39,35 +40,44 @@ public sealed class FruitBankEkaerService : IFruitBankEkaerService
public EkaerHistory GenerateEkaerXmlDocument(ShippingDocument document, EkaerHistory? ekaerHistory = null)
{
ArgumentNullException.ThrowIfNull(document);
-
ekaerHistory ??= new EkaerHistory { ForeignKey = document.Id, IsOutgoing = false };
- // Config-ellenőrzés a leképezés ELŐTT: külföldi (nem HUF) feladónál az árfolyam kötelező — különben a
- // value csendben 0 lenne. Hibás configgal nem generálunk félrevezető XML-t, hanem jelezzük a hibát.
- if (!EkaerValueCalculator.IsHuf(document.Partner?.Currency) && _settings.EurHufRate <= 0)
- {
- 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;
- }
+ var currency = document.Partner?.Currency;
+ return TryConfigError(ekaerHistory, currency) ?? Finalize(ekaerHistory, _mapper.MapDocument(document, _settings.Company), currency);
+ }
- var operation = new TradeCardOperationType
- {
- Index = 1,
- Operation = OperationType.Create,
- TradeCard = _mapper.MapDocument(document, _settings.Company),
- };
+ 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);
- // Az XML validációs hibánál IS tárolódik — a detail-nézetben így látszik, mi hiányzik.
- ekaerHistory.XmlDoc = NavXmlHelper.Serialize(operation.TradeCard);
- // Audit: a value-számításhoz TÉNYLEGESEN alkalmazott árfolyam (HUF → 1, külföldi → FX-ráta) — pont az,
- // amivel a value készült. A NAV-sémában nincs árfolyam-mező, csak a HUF value; ez az oszlop őrzi meg, hogyan.
- ekaerHistory.ConversionRate = EkaerValueCalculator.ResolveRateToHuf(document.Partner?.Currency, _settings.EurHufRate);
+ 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;
}
}
diff --git a/FruitBank.Common.Server/Services/Ekaer/IFruitBankEkaerService.cs b/FruitBank.Common.Server/Services/Ekaer/IFruitBankEkaerService.cs
index 244bbf3a..22113025 100644
--- a/FruitBank.Common.Server/Services/Ekaer/IFruitBankEkaerService.cs
+++ b/FruitBank.Common.Server/Services/Ekaer/IFruitBankEkaerService.cs
@@ -1,5 +1,6 @@
using AyCode.Services.Nav.Ekaer;
using AyCode.Services.Nav.Ekaer.Models;
+using FruitBank.Common.Dtos;
using FruitBank.Common.Entities;
namespace FruitBank.Common.Server.Services.Ekaer;
@@ -26,4 +27,11 @@ public interface IFruitBankEkaerService
/// A szállítólevél a betöltött gráffal (Partner, Items+ProductDto, Shipping→járművek).
/// A dokumentum meglévő rekordja (újrageneráláskor); null → új rekord készül.
EkaerHistory GenerateEkaerXmlDocument(ShippingDocument document, EkaerHistory? ekaerHistory = null);
+
+ ///
+ /// Egy kimenő rendelésből () legenerálja az EKÁER tradeCard XML-t és validálja —
+ /// a (meglévő vagy új) rekordot tölti (IsOutgoing = true). Mi vagyunk az
+ /// ELADÓ, a vevő a CÍMZETT (belföldi értékesítés). NEM perzisztál és NEM hív NAV-ot — a mentés a hívó dolga.
+ ///
+ EkaerHistory GenerateEkaerXmlDocument(OrderDto order, EkaerHistory? ekaerHistory = null);
}
diff --git a/FruitBank.Common/Interfaces/IFruitBankDataControllerCommon.cs b/FruitBank.Common/Interfaces/IFruitBankDataControllerCommon.cs
index 74463d40..9c7f89bc 100644
--- a/FruitBank.Common/Interfaces/IFruitBankDataControllerCommon.cs
+++ b/FruitBank.Common/Interfaces/IFruitBankDataControllerCommon.cs
@@ -34,7 +34,7 @@ public interface IFruitBankDataControllerCommon
public Task?> GetEkaerHistoriesByForeignKey(int foreignKey);
public Task AddEkaerHistory(EkaerHistory ekaerHistory);
public Task UpdateEkaerHistory(EkaerHistory ekaerHistory);
- public Task GenerateEkaerXmlDocument(int shippingDocumentId);
+ public Task GenerateEkaerXmlDocument(int foreignKey, bool isOutgoing);
public Task CreateEkaerHistory(int foreignKey, bool isOutgoing);
public Task CreateMissingEkaerHistories(DateTime fromDate);
#endregion EkaerHistory
diff --git a/FruitBank.Common/Services/Ekaer/EkaerSettings.cs b/FruitBank.Common/Services/Ekaer/EkaerSettings.cs
index 94d7b5e4..9b04665c 100644
--- a/FruitBank.Common/Services/Ekaer/EkaerSettings.cs
+++ b/FruitBank.Common/Services/Ekaer/EkaerSettings.cs
@@ -7,7 +7,7 @@ namespace FruitBank.Common.Services.Ekaer;
/// cégadata + a küszöbök + az árfolyam. A küszöbök és az árfolyam évente / jogszabály szerint változhatnak,
/// ezért configban élnek — nem a kódban beégetve.
///
-public sealed class EkaerSettings
+public sealed class EkaerSettings : IEkaerSettings
{
/// A bejelentő saját cégadatai (címzett a bejövő relációban) + a lerakodási hely.
public EkaerCompanyInfo Company { get; set; } = new();
@@ -23,6 +23,7 @@ public sealed class EkaerSettings
public double ThresholdWeightKg { get; set; }
/// Érték-küszöb HUF-ban (nettó): e felett (vagy a tömeg-küszöb felett) kell EKÁER. Kockázatos élelmiszer: 250 000 Ft.
- /// Default nélkül: be nem töltött config → 0 → minden szállítmány „átlépi" (mindent jelentünk, a biztonság felé).
- public long ThresholdValueHuf { get; set; }
+ /// Default nélkül: be nem töltött config → 0 → minden szállítmány „átlépi" (mindent jelentünk, a biztonság felé).
+ /// int: a legmagasabb küszöb 5 millió Ft, bőven belefér.
+ public int ThresholdValueHuf { get; set; }
}
diff --git a/FruitBank.Common/Services/Ekaer/EkaerValueCalculator.cs b/FruitBank.Common/Services/Ekaer/EkaerValueCalculator.cs
index d028f688..3a674f9f 100644
--- a/FruitBank.Common/Services/Ekaer/EkaerValueCalculator.cs
+++ b/FruitBank.Common/Services/Ekaer/EkaerValueCalculator.cs
@@ -1,3 +1,4 @@
+using FruitBank.Common.Dtos;
using FruitBank.Common.Entities;
namespace FruitBank.Common.Services.Ekaer;
@@ -37,4 +38,17 @@ public static class EkaerValueCalculator
var huf = Math.Round(ItemLineValue(item) * rateToHuf, MidpointRounding.AwayFromZero);
return huf > 0 ? (long)huf : null;
}
+
+ // ── Kimenő (Order) változatok ────────────────────────────────────────────
+ // Az érték a NETTÓ (ÁFA nélküli) egységár × mennyiség — az EKÁER „nettó érték"-et vár.
+
+ /// Egy rendelés-tétel nettó értéke a számla pénznemében (UnitPriceExclTax × mennyiség), átváltás előtt.
+ public static double ItemLineValue(OrderItemDto item) => (double)item.UnitPriceExclTax * item.Quantity;
+
+ /// Egy rendelés-tétel értéke HUF-ban, egészre kerekítve. 0/ismeretlen → null (lásd a bejövő párját).
+ public static long? ItemValueHuf(OrderItemDto item, double rateToHuf)
+ {
+ var huf = Math.Round(ItemLineValue(item) * rateToHuf, MidpointRounding.AwayFromZero);
+ return huf > 0 ? (long)huf : null;
+ }
}
diff --git a/FruitBank.Common/Services/Ekaer/IShippingToEkaerMapper.cs b/FruitBank.Common/Services/Ekaer/IShippingToEkaerMapper.cs
index 31b2b70b..85b6aacb 100644
--- a/FruitBank.Common/Services/Ekaer/IShippingToEkaerMapper.cs
+++ b/FruitBank.Common/Services/Ekaer/IShippingToEkaerMapper.cs
@@ -1,5 +1,6 @@
using AyCode.Services.Nav.Ekaer;
using AyCode.Services.Nav.Ekaer.Models;
+using FruitBank.Common.Dtos;
using FruitBank.Common.Entities;
namespace FruitBank.Common.Services.Ekaer;
@@ -29,4 +30,11 @@ public interface IShippingToEkaerMapper
/// document.Shipping-ből jönnek; ha az nincs betöltve, ezek üresen maradnak (a validátor jelzi).
///
TradeCardType MapDocument(ShippingDocument document, EkaerCompanyInfo company);
+
+ ///
+ /// EGY kimenő rendelést () képez le egy tradeCard-dá: a bejelentő
+ /// (mi) az ELADÓ, a vevő a CÍMZETT, az irány belföldi értékesítés (D/S). A vonó jármű forrása
+ /// a kimenő fuvar-adat (OrderDto) — amíg az nincs bekötve, üresen marad (a validátor jelzi).
+ ///
+ TradeCardType MapOrder(OrderDto order, EkaerCompanyInfo company);
}
diff --git a/FruitBank.Common/Services/Ekaer/ShippingToEkaerMapper.cs b/FruitBank.Common/Services/Ekaer/ShippingToEkaerMapper.cs
index f2230597..6fbaa96c 100644
--- a/FruitBank.Common/Services/Ekaer/ShippingToEkaerMapper.cs
+++ b/FruitBank.Common/Services/Ekaer/ShippingToEkaerMapper.cs
@@ -2,7 +2,9 @@ using AyCode.Core.Interfaces;
using AyCode.Entities;
using AyCode.Services.Nav.Ekaer;
using AyCode.Services.Nav.Ekaer.Models;
+using FruitBank.Common.Dtos;
using FruitBank.Common.Entities;
+using Nop.Core.Domain.Customers;
using TradeReasonType = AyCode.Services.Nav.Ekaer.Models.Common.TradeReasonType;
using TradeType = AyCode.Services.Nav.Ekaer.Models.Common.TradeType;
@@ -19,9 +21,13 @@ public sealed class ShippingToEkaerMapper : IShippingToEkaerMapper
/// A NAV EKÁER magyar rendszer — a „belföld" mindig HU; minden más feladó-ország import.
private const string HomeCountry = "HU";
- private readonly EkaerSettings _settings;
+ /// Kimenő pénznem — jelenleg minden HUF (a vevő/rendelés devizája az OrderDto-ban még nincs leképezve;
+ /// bekötéskor innen jön). HUF → nincs átváltás (rate 1).
+ private const string OutboundCurrency = "HUF";
- public ShippingToEkaerMapper(EkaerSettings settings)
+ private readonly IEkaerSettings _settings;
+
+ public ShippingToEkaerMapper(IEkaerSettings settings)
=> _settings = settings ?? throw new ArgumentNullException(nameof(settings));
public IReadOnlyList MapShipping(Shipping shipping, EkaerCompanyInfo company, OperationType operation = OperationType.Create)
@@ -57,6 +63,45 @@ public sealed class ShippingToEkaerMapper : IShippingToEkaerMapper
return BuildTradeCard(document.Shipping, document, company, rateToHuf);
}
+ ///
+ public TradeCardType MapOrder(OrderDto order, EkaerCompanyInfo company)
+ {
+ ArgumentNullException.ThrowIfNull(order);
+ ArgumentNullException.ThrowIfNull(company);
+
+ var customer = order.Customer;
+ var rateToHuf = EkaerValueCalculator.ResolveRateToHuf(OutboundCurrency, _settings.EurHufRate);
+
+ var tradeCard = new TradeCardType
+ {
+ // Kimenő belföldi értékesítés. (Export `E` + külföldi deviza: későbbi — jelenleg minden HUF/belföld.)
+ TradeType = TradeType.D,
+ ModByCarrierEnabled = false,
+
+ // Eladó = mi (kimenő relációban)
+ SellerName = company.Name,
+ SellerVatNumber = NormalizeVatNumber(company.TaxId),
+ SellerCountry = NormalizeCountryCode(company.CountryCode, 2),
+ SellerAddress = Truncate(company.FullAddress, 200),
+
+ // Címzett = a vevő. Ország jelenleg HU (belföld); a Customer.CountryId-feloldás + export: későbbi.
+ DestinationName = customer?.Company,
+ DestinationVatNumber = NormalizeVatNumber(customer?.VatNumber),
+ DestinationCountry = HomeCountry,
+ DestinationAddress = Truncate(ComposeCustomerAddress(customer), 200),
+
+ // Felrakodás = a mi telephelyünk; lerakodás = a vevő.
+ LoadLocation = company.Site,
+ UnloadLocation = BuildCustomerLocation(customer),
+
+ // Vonó jármű / fuvarozó: a kimenő fuvar-adat (OrderDto) bekötéséig nincs forrás — üresen marad,
+ // a validátor jelzi (mint a bejövőnél kezdetben). TODO: order. → Vehicle / CarrierText.
+ };
+
+ foreach (var item in order.OrderItemDtos ?? []) tradeCard.Items.Add(BuildOutboundItem(item, rateToHuf));
+ return tradeCard;
+ }
+
private static TradeCardType BuildTradeCard(Shipping? shipping, ShippingDocument document, EkaerCompanyInfo company, double rateToHuf)
{
var seller = document.Partner; // a beszállító (feladó) — ICompanyInfoBase
@@ -82,7 +127,7 @@ public sealed class ShippingToEkaerMapper : IShippingToEkaerMapper
CarrierText = shipping?.CargoPartner?.Name,
// Lerakodás = saját telephely (a cégadatból); felrakodás = a beszállító telephelye.
- UnloadLocation = company.UnloadLocation,
+ UnloadLocation = company.Site,
LoadLocation = BuildLoadLocation(seller),
};
@@ -114,6 +159,18 @@ public sealed class ShippingToEkaerMapper : IShippingToEkaerMapper
Value = EkaerValueCalculator.ItemValueHuf(item, rateToHuf), // beszerzési érték HUF-ban (Partner.Currency → árfolyam); 0/ismeretlen → null
};
+ /// Kimenő (Order) tétel → tradeCardItem. Értékesítés (S); bruttó tömeg a palettákból; nettó érték HUF-ban.
+ private static TradeCardItemType BuildOutboundItem(OrderItemDto item, double rateToHuf) => new()
+ {
+ ItemExternalId = item.Id.ToString(),
+ // Kimenő áru = értékesítés → S. (Enum: S=értékesítés, A=beszerzés, W=bérmunka, O=egyéb.)
+ TradeReason = TradeReasonType.S,
+ ProductVtsz = NormalizeVtsz(item.ProductDto?.Gtin), // VTSZ — átmenetileg a Gtin oszlopban (FBANKAPP-DMODEL-I-P6X4)
+ ProductName = item.ProductDto?.Name,
+ Weight = (decimal)item.GrossWeight, // bruttó tömeg kg-ban (OrderItemPallets összegéből)
+ Value = EkaerValueCalculator.ItemValueHuf(item, rateToHuf), // nettó értékesítési érték HUF-ban; 0/ismeretlen → null
+ };
+
private static BasicVehicleDetailType BuildVehicle(CargoTruck truck) => new()
{
PlateNumber = NormalizePlateNumber(truck.LicencePlate),
@@ -138,6 +195,30 @@ public sealed class ShippingToEkaerMapper : IShippingToEkaerMapper
};
}
+ /// A vevő egysoros címe (irsz + város + utca) a NAV destinationAddress-hez.
+ private static string? ComposeCustomerAddress(Customer? customer)
+ {
+ if (customer is null) return null;
+ var parts = new[] { customer.ZipPostalCode, customer.City, customer.StreetAddress, customer.StreetAddress2 }
+ .Where(p => !string.IsNullOrWhiteSpace(p));
+ return EmptyToNull(string.Join(" ", parts).Trim());
+ }
+
+ /// Lerakodási hely a vevő adataiból (kimenő reláció). Ország jelenleg HU (belföld).
+ private static LocationType? BuildCustomerLocation(Customer? customer)
+ {
+ if (customer is null) return null;
+ return new LocationType
+ {
+ Name = customer.Company,
+ VatNumber = NormalizeVatNumber(customer.VatNumber),
+ Country = HomeCountry,
+ ZipCode = NormalizeZipCode(customer.ZipPostalCode),
+ City = customer.City,
+ Street = customer.StreetAddress,
+ };
+ }
+
/// Adószám normalizálása. Pattern: [0-9A-Z-]{1,15}.
private static string? NormalizeVatNumber(string? value)
{
diff --git a/FruitBankHybrid.Shared.Tests/Ekaer/ShippingToEkaerMapperTests.cs b/FruitBankHybrid.Shared.Tests/Ekaer/ShippingToEkaerMapperTests.cs
index 461ab4c9..be7ac26c 100644
--- a/FruitBankHybrid.Shared.Tests/Ekaer/ShippingToEkaerMapperTests.cs
+++ b/FruitBankHybrid.Shared.Tests/Ekaer/ShippingToEkaerMapperTests.cs
@@ -15,7 +15,9 @@ namespace FruitBankHybrid.Shared.Tests.Ekaer;
[TestClass]
public sealed class ShippingToEkaerMapperTests
{
- private static readonly ShippingToEkaerMapper Mapper = new(new EkaerSettings());
+ // EurHufRate > 0 kell: a teszt-partnernek nincs Currency-je (null → külföldiként kezelt), és árfolyam nélkül
+ // a value-számítás ResolveRateToHuf-ja dobna. A value-t a tesztek nem ellenőrzik; ez csak az átváltáshoz kell.
+ private static readonly ShippingToEkaerMapper Mapper = new(new EkaerSettings { EurHufRate = 356 });
// ---- Helpers ------------------------------------------------------------
@@ -67,15 +69,17 @@ public sealed class ShippingToEkaerMapperTests
PostalCode = "1102",
City = "Budapest",
Street = "Raktar utca 5",
- UnloadLocation = new LocationType
+ Site = new LocationType
{
Name = "FruitBank Raktár",
VatNumber = "98765432-2-41",
+ Phone = "+36301234567", // NAV-formátum: + / 06 prefix kötelező
+ Email = "raktar@fruitbank.hu",
Country = "HU",
- ZipCode = "1102",
+ ZipCode = "1239",
City = "Budapest",
- Street = "Raktar utca",
- StreetNumber = "5",
+ Street = "Nagykőrösi út",
+ StreetNumber = "353",
},
};
@@ -166,7 +170,7 @@ public sealed class ShippingToEkaerMapperTests
Assert.AreEqual("FruitBank Kft", tradeCard.DestinationName);
Assert.AreEqual("HU", tradeCard.DestinationCountry);
StringAssert.Contains(tradeCard.DestinationAddress, "Budapest", "a destinationAddress a company FullAddress-éből jön");
- Assert.AreSame(company.UnloadLocation, tradeCard.UnloadLocation, "a lerakodási hely a cégadatból jön");
+ Assert.AreSame(company.Site, tradeCard.UnloadLocation, "a lerakodási hely a cég telephelyéből jön");
}
[TestMethod]
diff --git a/FruitBankHybrid.Shared.Tests/FruitBankEkaerTests.cs b/FruitBankHybrid.Shared.Tests/FruitBankEkaerTests.cs
index 12bbe5e9..c8e8c716 100644
--- a/FruitBankHybrid.Shared.Tests/FruitBankEkaerTests.cs
+++ b/FruitBankHybrid.Shared.Tests/FruitBankEkaerTests.cs
@@ -73,7 +73,7 @@ namespace FruitBankHybrid.Shared.Tests
foreach (var shippingDocument in shippingDocuments)
{
- var ekaerHistory = await _signalRClient.GenerateEkaerXmlDocument(shippingDocument.Id);
+ var ekaerHistory = await _signalRClient.GenerateEkaerXmlDocument(shippingDocument.Id, false);
// A szerver által visszaadott állapot/hibalista logolása — az assertek ELŐTT, hogy hibánál is látsszon.
Console.WriteLine($"doc#{shippingDocument.Id}: Status: {(ekaerHistory == null ? "NULL VÁLASZ!" : ekaerHistory.Status.ToString())}");
@@ -105,8 +105,8 @@ namespace FruitBankHybrid.Shared.Tests
var shippingDocumentId = shippingDocuments[0].Id;
- var first = await _signalRClient.GenerateEkaerXmlDocument(shippingDocumentId);
- var second = await _signalRClient.GenerateEkaerXmlDocument(shippingDocumentId);
+ var first = await _signalRClient.GenerateEkaerXmlDocument(shippingDocumentId, false);
+ var second = await _signalRClient.GenerateEkaerXmlDocument(shippingDocumentId, false);
Assert.IsNotNull(first);
Assert.IsNotNull(second);
diff --git a/FruitBankHybrid.Shared/Components/Grids/Ekaers/GridEkaerHistory.razor b/FruitBankHybrid.Shared/Components/Grids/Ekaers/GridEkaerHistory.razor
index de00d48b..0d67a925 100644
--- a/FruitBankHybrid.Shared/Components/Grids/Ekaers/GridEkaerHistory.razor
+++ b/FruitBankHybrid.Shared/Components/Grids/Ekaers/GridEkaerHistory.razor
@@ -172,10 +172,10 @@
private readonly HashSet _generatingIds = [];
- // Elküldött bejelentést nem generálunk újra némán (az már a NAV-nál van — módosítás külön művelet lesz);
- // kimenő (Order) generálás még nincs implementálva.
+ // Elküldött bejelentést nem generálunk újra némán (az már a NAV-nál van — módosítás külön művelet lesz).
+ // Bejövő és kimenő (Order) is generálható; a kimenőnél a fuvar-adat bekötéséig a validátor jelzi a hiányt.
private bool CanGenerate(EkaerHistory ekaerHistory)
- => ekaerHistory.Status != EkaerStatus.Sent && !ekaerHistory.IsOutgoing && !_generatingIds.Contains(ekaerHistory.Id);
+ => ekaerHistory.Status != EkaerStatus.Sent && !_generatingIds.Contains(ekaerHistory.Id);
// Hibás (validációs hibás) bejelentés XML-jét nem adjuk a user kezébe — ne kerülhessen kézzel a NAV-hoz.
private static bool CanCopy(EkaerHistory ekaerHistory)
@@ -187,7 +187,7 @@
try
{
- var updated = await FruitBankSignalRClient.GenerateEkaerXmlDocument(ekaerHistory.ForeignKey);
+ var updated = await FruitBankSignalRClient.GenerateEkaerXmlDocument(ekaerHistory.ForeignKey, ekaerHistory.IsOutgoing);
if (updated == null)
{
diff --git a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs
index 7bad3074..2f85f620 100644
--- a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs
+++ b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs
@@ -79,7 +79,7 @@ namespace FruitBankHybrid.Shared.Services.SignalRs
public Task?> GetEkaerHistoriesByForeignKey(int foreignKey) => GetAllAsync>(SignalRTags.GetEkaerHistoriesByForeignKey, [foreignKey]);
public Task AddEkaerHistory(EkaerHistory ekaerHistory) => PostDataAsync(SignalRTags.AddEkaerHistory, ekaerHistory);
public Task UpdateEkaerHistory(EkaerHistory ekaerHistory) => PostDataAsync(SignalRTags.UpdateEkaerHistory, ekaerHistory);
- public Task GenerateEkaerXmlDocument(int shippingDocumentId) => GetByIdAsync(SignalRTags.GenerateEkaerXmlDocument, shippingDocumentId);
+ public Task GenerateEkaerXmlDocument(int foreignKey, bool isOutgoing) => GetByIdAsync(SignalRTags.GenerateEkaerXmlDocument, [foreignKey, isOutgoing]);
public Task CreateEkaerHistory(int foreignKey, bool isOutgoing) => GetByIdAsync(SignalRTags.CreateEkaerHistory, [foreignKey, isOutgoing]);
public Task CreateMissingEkaerHistories(DateTime fromDate) => GetByIdAsync(SignalRTags.CreateMissingEkaerHistories, fromDate);
#endregion EkaerHistory