using AyCode.Services.Nav.Ekaer; using AyCode.Services.Nav.Ekaer.Models; using FruitBank.Common.Dtos; using FruitBank.Common.Entities; using FruitBank.Common.Services.Ekaer; using TradeReasonType = AyCode.Services.Nav.Ekaer.Models.Common.TradeReasonType; using TradeType = AyCode.Services.Nav.Ekaer.Models.Common.TradeType; namespace FruitBankHybrid.Shared.Tests.Ekaer; /// /// Unit tesztek a -re — a FruitBank Shipping → NAV EKÁER tradeCard /// leképezésre. Tisztán memóriában felépített entitásokon fut (nincs hálózat/DB), determinisztikus. /// [TestClass] public sealed class ShippingToEkaerMapperTests { // 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 ------------------------------------------------------------ private static Shipping CreateShipping(string sellerCountry = "HU", string plate = "ABC-123", bool withTrailer = true) { var item = new ShippingItem { Id = 1, Name = "Alma", ProductDto = new ProductDto { Gtin = "08081010", Name = "Alma" }, MeasuredGrossWeight = 123.5, MeasuredQuantity = 10, UnitPriceOnDocument = 5.0, }; var document = new ShippingDocument { Country = sellerCountry, Partner = new Partner { Name = "Beszállító Kft", TaxId = "12345678-2-42", CountryCode = sellerCountry, PostalCode = "1011", City = "Budapest", Street = "Fő utca 1", }, ShippingItems = [item], }; var shipping = new Shipping { CargoPartner = new CargoPartner { Name = "Fuvaros Zrt", CountryCode = "HU" }, CargoTruck = new CargoTruck { LicencePlate = plate, CountryCode = "HU", IsTrailer = false }, ShippingDocuments = [document], }; if (withTrailer) shipping.CargoTrailer = new CargoTruck { LicencePlate = "XYZ-789", CountryCode = "HU", IsTrailer = true }; return shipping; } private static EkaerCompanyInfo CreateCompany() => new() { Name = "FruitBank Kft", TaxId = "98765432-2-41", CountryCode = "HU", PostalCode = "1102", City = "Budapest", Street = "Raktar utca 5", 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 = "1239", City = "Budapest", Street = "Nagykőrösi út", StreetNumber = "353", }, }; private static ShippingDocument CreateInboundDocument(int itemId, double weight, string sellerCountry = "HU") => new() { Country = sellerCountry, Partner = new Partner { Name = "Beszállító Kft", TaxId = "12345678-2-42", CountryCode = sellerCountry, PostalCode = "1011", City = "Budapest", Street = "Fő utca 1", }, ShippingItems = [new ShippingItem { Id = itemId, Name = "Alma", ProductDto = new ProductDto { Gtin = "08081010", Name = "Alma" }, MeasuredGrossWeight = weight, UnitPriceOnDocument = 5.0, }], }; // ---- Granularitás / index ---------------------------------------------- [TestMethod] public void MapShipping_ProducesOneOperationPerDocument_WithSequentialIndex() { var shipping = CreateShipping(); shipping.ShippingDocuments!.Add(new ShippingDocument { Country = "HU", Partner = new Partner { Name = "Másik Beszállító", CountryCode = "HU" }, ShippingItems = [], }); var ops = Mapper.MapShipping(shipping, CreateCompany()); Assert.AreEqual(2, ops.Count, "dokumentumonként egy tradeCard"); Assert.AreEqual(1, ops[0].Index); Assert.AreEqual(2, ops[1].Index); Assert.AreEqual(OperationType.Create, ops[0].Operation, "alapértelmezett művelet: Create"); } [TestMethod] public void MapShipping_NullDocuments_ReturnsEmpty() { var ops = Mapper.MapShipping(new Shipping { ShippingDocuments = null }, CreateCompany()); Assert.AreEqual(0, ops.Count); } [TestMethod] public void MapShipping_HonorsExplicitOperation() { var ops = Mapper.MapShipping(CreateShipping(), CreateCompany(), OperationType.Modify); Assert.AreEqual(OperationType.Modify, ops[0].Operation); } // ---- tradeType irány ---------------------------------------------------- [TestMethod] public void MapShipping_DomesticSeller_TradeTypeDomestic() { var ops = Mapper.MapShipping(CreateShipping(sellerCountry: "HU"), CreateCompany()); Assert.AreEqual(TradeType.D, ops[0].TradeCard.TradeType, "belföldi (HU) feladó → D"); } [TestMethod] public void MapShipping_ForeignSeller_TradeTypeImport() { var ops = Mapper.MapShipping(CreateShipping(sellerCountry: "DE"), CreateCompany()); Assert.AreEqual(TradeType.I, ops[0].TradeCard.TradeType, "nem-HU feladó → I (import) — a NAV EKÁER magyar"); } // ---- Tétel-leképezés ---------------------------------------------------- [TestMethod] public void MapShipping_MapsItemFields() { var item = Mapper.MapShipping(CreateShipping(), CreateCompany())[0].TradeCard.Items[0]; Assert.AreEqual("08081010", item.ProductVtsz, "productVtsz = ProductDto.Gtin"); Assert.AreEqual("Alma", item.ProductName); Assert.AreEqual(123.5m, item.Weight, "weight = MeasuredGrossWeight (bruttó)"); Assert.AreEqual(TradeReasonType.A, item.TradeReason, "bejövő áru = beszerzés = A"); Assert.IsNull(item.Value, "a HUF érték a deviza tisztázásáig nincs kitöltve"); } // ---- Eladó (seller*) ---------------------------------------------------- [TestMethod] public void MapShipping_MapsSellerFromPartner() { var tradeCard = Mapper.MapShipping(CreateShipping(), CreateCompany())[0].TradeCard; Assert.AreEqual("Beszállító Kft", tradeCard.SellerName); Assert.AreEqual("12345678-2-42", tradeCard.SellerVatNumber); Assert.AreEqual("HU", tradeCard.SellerCountry); StringAssert.Contains(tradeCard.SellerAddress, "Budapest", "a sellerAddress a Partner FullAddress-éből jön"); } [TestMethod] public void MapShipping_MapsDestinationAndUnloadFromCompany() { var company = CreateCompany(); var tradeCard = Mapper.MapShipping(CreateShipping(), company)[0].TradeCard; 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.Site, tradeCard.UnloadLocation, "a lerakodási hely a cég telephelyéből jön"); } [TestMethod] public void MapShipping_MapsCarrierTextFromCargoPartner() { var tradeCard = Mapper.MapShipping(CreateShipping(), CreateCompany())[0].TradeCard; Assert.AreEqual("Fuvaros Zrt", tradeCard.CarrierText); } // ---- Járművek + rendszám-normalizálás ---------------------------------- [TestMethod] public void MapShipping_NormalizesLicencePlate_RemovesHyphenAndUppercases() { var tradeCard = Mapper.MapShipping(CreateShipping(plate: "abc-123"), CreateCompany())[0].TradeCard; Assert.AreEqual("ABC123", tradeCard.Vehicle!.PlateNumber, "a NAV pattern nem enged kötőjelet, és nagybetűs"); Assert.AreEqual("HU", tradeCard.Vehicle.Country); } [TestMethod] public void MapShipping_WithTrailer_MapsVehicle2() { var tradeCard = Mapper.MapShipping(CreateShipping(withTrailer: true), CreateCompany())[0].TradeCard; Assert.IsNotNull(tradeCard.Vehicle, "vonó jármű"); Assert.IsNotNull(tradeCard.Vehicle2, "vontatmány"); Assert.AreEqual("XYZ789", tradeCard.Vehicle2!.PlateNumber); } [TestMethod] public void MapShipping_NoTrailer_Vehicle2Null() { var tradeCard = Mapper.MapShipping(CreateShipping(withTrailer: false), CreateCompany())[0].TradeCard; Assert.IsNotNull(tradeCard.Vehicle); Assert.IsNull(tradeCard.Vehicle2, "nincs pótkocsi → nincs vehicle2"); } // ---- Védőkorlátok ------------------------------------------------------- [TestMethod] public void MapShipping_NullShipping_Throws() => Assert.ThrowsExactly(() => Mapper.MapShipping(null!, CreateCompany())); [TestMethod] public void MapShipping_NullCompany_Throws() => Assert.ThrowsExactly(() => Mapper.MapShipping(CreateShipping(), null!)); // ---- Köztes modell: ToConsignment (bejövő) ------------------------------ [TestMethod] public void ToConsignment_Inbound_MultipleDocuments_CombinesLinesAndAggregatesWeight() { // Két szállítólevél (azonos partner, azonos Shipping) → egy szállítmány, MINDKÉT tétellel — a küszöb-aggregáláshoz. var consignment = Mapper.ToConsignment( [CreateInboundDocument(itemId: 1, weight: 100), CreateInboundDocument(itemId: 2, weight: 150)], CreateCompany()); Assert.AreEqual(2, consignment.Lines.Count, "a csoport ÖSSZES tétele egy szállítmányban"); Assert.AreEqual(250d, consignment.Lines.Sum(l => l.WeightKg), 0.001, "a tömeg a dokumentumokból összegződik"); Assert.IsFalse(consignment.IsOutgoing); Assert.AreEqual("HU", consignment.Seller.CountryCode, "feladó = a beszállító partner"); Assert.AreEqual("HU", consignment.Buyer.CountryCode, "címzett = a saját cég"); } [TestMethod] public void ToConsignment_Inbound_BuildTradeCard_PreservesCompanySiteAsUnloadLocation() { var company = CreateCompany(); var tradeCard = Mapper.BuildTradeCard(Mapper.ToConsignment([CreateInboundDocument(1, 100)], company)); Assert.AreSame(company.Site, tradeCard.UnloadLocation, "a saját telephely érintetlenül (mezővesztés nélkül) megy át"); } [TestMethod] public void ToConsignment_Inbound_EmptyDocuments_Throws() => Assert.ThrowsExactly(() => Mapper.ToConsignment([], CreateCompany())); [TestMethod] public void ToConsignment_Inbound_NullPartner_DoesNotThrow_SellerCountryNull() { // Hibás adat: nincs Partner a szállítólevélen → az adapter NEM dob; a feladó-ország null (ezt a kötelezettség- // értékelő / generate-validálás kezeli, nem a leképező). var doc = new ShippingDocument { Partner = null, ShippingItems = [new ShippingItem { Id = 1, MeasuredGrossWeight = 50 }] }; var consignment = Mapper.ToConsignment([doc], CreateCompany()); Assert.IsNull(consignment.Seller.CountryCode, "nincs partner → nincs feladó-ország"); Assert.AreEqual(1, consignment.Lines.Count); } [TestMethod] public void ToConsignment_Inbound_NullShippingItems_EmptyLines() { // Hibás/hiányos adat: nincs tétel a szállítólevélen → üres Lines, NEM dob. var doc = new ShippingDocument { Partner = new Partner { CountryCode = "HU" }, ShippingItems = null }; var consignment = Mapper.ToConsignment([doc], CreateCompany()); Assert.AreEqual(0, consignment.Lines.Count); } }