diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/History/EDocPurchaseHistMapping.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/History/EDocPurchaseHistMapping.Codeunit.al index 32c26f0673..accdcc87b2 100644 --- a/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/History/EDocPurchaseHistMapping.Codeunit.al +++ b/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/History/EDocPurchaseHistMapping.Codeunit.al @@ -214,6 +214,7 @@ codeunit 6120 "E-Doc. Purchase Hist. Mapping" EDocPurchLineField: Record "E-Document Line - Field"; NewPurchLineRecordRef: RecordRef; NewPurchLineFieldRef: FieldRef; + FieldValue: Variant; begin if not EDocPurchLineFieldSetup.FindSet() then exit; @@ -223,11 +224,25 @@ codeunit 6120 "E-Doc. Purchase Hist. Mapping" continue; EDocPurchLineField.Get(EDocumentPurchaseLine, EDocPurchLineFieldSetup); NewPurchLineFieldRef := NewPurchLineRecordRef.Field(EDocPurchLineFieldSetup."Field No."); - NewPurchLineFieldRef.Validate(EDocPurchLineField.GetValue()); + FieldValue := EDocPurchLineField.GetValue(); + CheckFieldValueLength(NewPurchLineFieldRef, FieldValue); + NewPurchLineFieldRef.Validate(FieldValue); until EDocPurchLineFieldSetup.Next() = 0; NewPurchLineRecordRef.SetTable(PurchaseLine); end; + local procedure CheckFieldValueLength(PurchLineFieldRef: FieldRef; FieldValue: Variant) + var + ValueAsText: Text; + ValueTooLongErr: Label 'value ''%1'' exceeds the maximum length of %2 characters (actual: %3). Review the additional field %4 (ID %5) under Configure additional fields on the E-Document Service page.', Comment = '%1 = Value, %2 = Max Length, %3 = Actual Length, %4 = Field Name, %5 = Field Number'; + begin + if not (PurchLineFieldRef.Type() in [FieldType::Text, FieldType::Code]) then + exit; + ValueAsText := Format(FieldValue); + if StrLen(ValueAsText) > PurchLineFieldRef.Length() then + PurchLineFieldRef.FieldError(StrSubstNo(ValueTooLongErr, ValueAsText, PurchLineFieldRef.Length(), StrLen(ValueAsText), PurchLineFieldRef.Name(), PurchLineFieldRef.Number())); + end; + procedure OpenPageWithHistoricMatch(EDocumentPurchaseLine: Record "E-Document Purchase Line"): Boolean var EDocPurchaseLineHistory: Record "E-Doc. Purchase Line History"; diff --git a/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al b/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al index c6700ea65f..7fc099a410 100644 --- a/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al +++ b/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al @@ -24,6 +24,7 @@ using Microsoft.Purchases.Vendor; using Microsoft.Sales.Customer; using System.IO; using System.TestLibraries.Utilities; +using System.Utilities; codeunit 139883 "E-Doc Process Test" { @@ -580,6 +581,67 @@ codeunit 139883 "E-Doc Process Test" Assert.AreNotEqual(Location.Code, PurchaseLine."Location Code", 'The location code should not be set on the purchase line.'); end; + [Test] + procedure AdditionalFieldValueExceedingFieldLengthShouldError() + var + EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup"; + PurchaseInvoiceLine: Record "Purch. Inv. Line"; + EDocument: Record "E-Document"; + EDocImportParams: Record "E-Doc. Import Parameters"; + PurchaseHeader: Record "Purchase Header"; + EDocPurchLineField: Record "E-Document Line - Field"; + EDocPurchaseLine: Record "E-Document Purchase Line"; + ErrorMessage: Record "Error Message"; + EDocImport: Codeunit "E-Doc. Import"; + EDocumentErrorHelper: Codeunit "E-Document Error Helper"; + FieldValue: Text; + begin + // [SCENARIO] An additional field is configured, and the stored value exceeds the target field's maximum length. + // When finalizing the draft, the system should report an error identifying the problematic field. + Initialize(Enum::"Service Integration"::"Mock"); + EDocumentService."Read into Draft Impl." := "E-Doc. Read into Draft"::PEPPOL; + EDocumentService.Modify(); + + // [GIVEN] An additional field is configured for Location Code (Code[10]) + EDocPurchLineFieldSetup."Field No." := PurchaseInvoiceLine.FieldNo("Location Code"); + EDocPurchLineFieldSetup.Insert(); + + // [GIVEN] An inbound e-document is received and a draft created + EDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft"; + WorkDate(DMY2Date(1, 1, 2027)); + Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', EDocImportParams), 'The draft for the e-document should be created'); + + // [GIVEN] A custom value that exceeds the target field length is stored for the additional field + FieldValue := 'LONGLOCCODE1'; // 12 characters, exceeds Code[10] + EDocPurchLineField."E-Document Entry No." := EDocument."Entry No"; + EDocPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No"); + EDocPurchaseLine.FindFirst(); + EDocPurchLineField."Line No." := EDocPurchaseLine."Line No."; + EDocPurchLineField."Field No." := PurchaseInvoiceLine.FieldNo("Location Code"); + EDocPurchLineField."Code Value" := FieldValue; + EDocPurchLineField.Insert(); + + // [WHEN] Finalizing the draft + EDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft"; + Assert.IsFalse(EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParams), 'The finalization should fail due to field length exceeded'); + + // [THEN] The e-document should have errors + EDocument.Get(EDocument."Entry No"); + Assert.IsTrue(EDocumentErrorHelper.HasErrors(EDocument), 'The e-document should have an error logged for the field length violation'); + + // [THEN] The error message should reference the field name, value, and lengths + ErrorMessage.SetRange("Context Record ID", EDocument.RecordId()); + ErrorMessage.SetRange("Message Type", ErrorMessage."Message Type"::Error); + ErrorMessage.FindFirst(); + Assert.ExpectedMessage(FieldValue, ErrorMessage."Message"); + Assert.ExpectedMessage('exceeds the maximum length', ErrorMessage."Message"); + Assert.ExpectedMessage('Location Code', ErrorMessage."Message"); + + // [THEN] No purchase invoice should have been created + PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId); + Assert.RecordIsEmpty(PurchaseHeader); + end; + [Test] procedure PreparingPurchaseDraftFindsItemReference() var