-
Notifications
You must be signed in to change notification settings - Fork 696
[E-Documents Core] - Migrate electronic formats to new purchase draft concept for e-invoicing (e-invoice preview) (PEPPOL) #28983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
+990
−294
Closed
Changes from 16 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
dbc9b7d
feat: Add support for Purchase Credit Memo in E-Document processing
AndriusAndrulevicius 6207947
refactor: Simplify Purchase Credit Memo creation and enhance XML proc…
AndriusAndrulevicius a3f2ad7
Fixes purchase line numbering by using FindLast
AndriusAndrulevicius 8fd6e5f
Adds XML documentation to E-Document helper methods
AndriusAndrulevicius 45d806b
Update EDocumentXMLHelper.Codeunit.al
AndriusAndrulevicius e99adee
merge main into dev/aan/PEPPOL-v2
AndriusAndrulevicius 6bac7c4
Reorganizes imports and updates codeunit ID
AndriusAndrulevicius 9235e05
Adds whitespace for code readability
AndriusAndrulevicius 23d1e89
Improves unit of measure handling in purchase documents
AndriusAndrulevicius 78c5796
Apply suggestion from @GMatuleviciute
GMatuleviciute e13670c
Apply suggestion from @GMatuleviciute
GMatuleviciute 5ad28aa
Enhances PEPPOL e-document testing with comprehensive validation
AndriusAndrulevicius 9184777
Refactors purchase document creation logic
AndriusAndrulevicius 7f48abd
Adds XML node value retrieval helper method
AndriusAndrulevicius bf2dabe
Refactors draft reset logic into reusable method
AndriusAndrulevicius c04a089
Fixes field mapping in PEPPOL credit note XML generation
AndriusAndrulevicius 6a96f3e
Prevents errors when deleting empty record sets
AndriusAndrulevicius 24fae99
Update Apps/W1/EDocument/test/src/Processing/PEPPOLStructuredValidati…
AndriusAndrulevicius f34e79e
Update Apps/W1/EDocument/test/src/Processing/EDocumentStructuredTests…
AndriusAndrulevicius 5f300e0
Update Apps/W1/EDocument/test/src/Processing/EDocumentStructuredTests…
AndriusAndrulevicius 6435c88
Update Apps/W1/EDocument/test/src/Processing/EDocumentStructuredTests…
AndriusAndrulevicius 345a48c
Update Apps/W1/EDocument/test/src/Processing/EDocumentStructuredTests…
AndriusAndrulevicius ae9ff0e
Update Apps/W1/EDocument/test/src/Processing/EDocumentStructuredTests…
AndriusAndrulevicius 1ed84e8
Update Apps/W1/EDocument/test/src/Processing/EDocumentStructuredTests…
AndriusAndrulevicius bc16422
Update Apps/W1/EDocument/test/src/Processing/EDocumentStructuredTests…
AndriusAndrulevicius 1dbdc15
Makes PEPPOL validations stateless and consistent
AndriusAndrulevicius 83ebedf
Merge branch 'main' into dev/aan/PEPPOL-v2
AndriusAndrulevicius 7080ef0
Centralizes draft reset on purchase header
AndriusAndrulevicius acc02ab
Enhances PEPPOL validations with stateless and consistent testing fra…
AndriusAndrulevicius 4071f21
Centralizes draft cleanup; adds invoice retrieval
AndriusAndrulevicius f5c9349
Merge branch 'main' into dev/aan/PEPPOL-v2
AndriusAndrulevicius f958008
Respects vendor target: order vs invoice in drafts
AndriusAndrulevicius File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
126 changes: 126 additions & 0 deletions
126
Apps/W1/EDocument/app/src/Helpers/EDocumentXMLHelper.Codeunit.al
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| // ------------------------------------------------------------------------------------------------ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. See License.txt in the project root for license information. | ||
| // ------------------------------------------------------------------------------------------------ | ||
| namespace Microsoft.eServices.EDocument.Helpers; | ||
|
|
||
| using Microsoft.Finance.GeneralLedger.Setup; | ||
|
|
||
| codeunit 6177 "EDocument XML Helper" | ||
| { | ||
| Access = Internal; | ||
|
|
||
| /// <summary> | ||
| /// Extracts currency value from XML document and sets it in the currency field if it differs from LCY. | ||
| /// </summary> | ||
| /// <param name="XMLDocument">The XML document to search in.</param> | ||
| /// <param name="XMLNamespaces">The XML namespace manager for XPath queries.</param> | ||
| /// <param name="Path">The XPath expression to locate the currency value.</param> | ||
| /// <param name="MaxLength">The maximum length of the currency code.</param> | ||
| /// <param name="CurrencyField">The currency field to update with the extracted value.</param> | ||
| internal procedure SetCurrencyValueInField(XMLDocument: XmlDocument; XMLNamespaces: XmlNamespaceManager; Path: Text; MaxLength: Integer; var CurrencyField: Code[10]) | ||
| var | ||
| GLSetup: Record "General Ledger Setup"; | ||
| XMLNode: XmlNode; | ||
| CurrencyCode: Code[10]; | ||
| begin | ||
| if not XMLDocument.SelectSingleNode(Path, XMLNamespaces, XMLNode) then | ||
| exit; | ||
|
|
||
| GLSetup.Get(); | ||
|
|
||
| #pragma warning disable AA0139 // false positive | ||
| if XMLNode.IsXmlElement() then begin | ||
| CurrencyCode := CopyStr(XMLNode.AsXmlElement().InnerText(), 1, MaxLength); | ||
| if GLSetup."LCY Code" <> CurrencyCode then | ||
| CurrencyField := CurrencyCode; | ||
| exit; | ||
| end; | ||
|
|
||
| if XMLNode.IsXmlAttribute() then begin | ||
| CurrencyCode := CopyStr(XMLNode.AsXmlAttribute().Value, 1, MaxLength); | ||
| if GLSetup."LCY Code" <> CurrencyCode then | ||
| CurrencyField := CurrencyCode; | ||
| exit; | ||
| end; | ||
| #pragma warning restore AA0139 | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Extracts string value from XML document and sets it in the specified field. | ||
| /// </summary> | ||
| /// <param name="XMLDocument">The XML document to search in.</param> | ||
| /// <param name="XMLNamespaces">The XML namespace manager for XPath queries.</param> | ||
| /// <param name="Path">The XPath expression to locate the string value.</param> | ||
| /// <param name="MaxLength">The maximum length of the string value.</param> | ||
| /// <param name="Field">The text field to update with the extracted value.</param> | ||
| internal procedure SetStringValueInField(XMLDocument: XmlDocument; XMLNamespaces: XmlNamespaceManager; Path: Text; MaxLength: Integer; var Field: Text) | ||
| var | ||
| XMLNode: XmlNode; | ||
| begin | ||
| if not XMLDocument.SelectSingleNode(Path, XMLNamespaces, XMLNode) then | ||
| exit; | ||
|
|
||
| if XMLNode.IsXmlElement() then begin | ||
| Field := CopyStr(XMLNode.AsXmlElement().InnerText(), 1, MaxLength); | ||
| exit; | ||
| end; | ||
|
|
||
| if XMLNode.IsXmlAttribute() then begin | ||
| Field := CopyStr(XMLNode.AsXmlAttribute().Value(), 1, MaxLength); | ||
| exit; | ||
| end; | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Extracts numeric value from XML document and sets it in the specified decimal field. | ||
| /// </summary> | ||
| /// <param name="XMLDocument">The XML document to search in.</param> | ||
| /// <param name="XMLNamespaces">The XML namespace manager for XPath queries.</param> | ||
| /// <param name="Path">The XPath expression to locate the numeric value.</param> | ||
| /// <param name="DecimalValue">The decimal field to update with the extracted value.</param> | ||
| internal procedure SetNumberValueInField(XMLDocument: XmlDocument; XMLNamespaces: XmlNamespaceManager; Path: Text; var DecimalValue: Decimal) | ||
| var | ||
| XMLNode: XmlNode; | ||
| begin | ||
| if not XMLDocument.SelectSingleNode(Path, XMLNamespaces, XMLNode) then | ||
| exit; | ||
|
|
||
| if XMLNode.AsXmlElement().InnerText() <> '' then | ||
| Evaluate(DecimalValue, XMLNode.AsXmlElement().InnerText(), 9); | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Extracts date value from XML document and sets it in the specified date field. | ||
| /// </summary> | ||
| /// <param name="XMLDocument">The XML document to search in.</param> | ||
| /// <param name="XMLNamespaces">The XML namespace manager for XPath queries.</param> | ||
| /// <param name="Path">The XPath expression to locate the date value.</param> | ||
| /// <param name="DateValue">The date field to update with the extracted value.</param> | ||
| internal procedure SetDateValueInField(XMLDocument: XmlDocument; XMLNamespaces: XmlNamespaceManager; Path: Text; var DateValue: Date) | ||
| var | ||
| XMLNode: XmlNode; | ||
| begin | ||
| if not XMLDocument.SelectSingleNode(Path, XMLNamespaces, XMLNode) then | ||
| exit; | ||
|
|
||
| if XMLNode.AsXmlElement().InnerText() <> '' then | ||
| Evaluate(DateValue, XMLNode.AsXmlElement().InnerText(), 9); | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Retrieves the inner text value of an XML node using XPath expression. | ||
| /// </summary> | ||
| /// <param name="XmlDoc">The XML document to search in.</param> | ||
| /// <param name="XmlNamespaces">The XML namespace manager for XPath queries.</param> | ||
| /// <param name="XPath">The XPath expression to locate the node.</param> | ||
| /// <returns>The inner text value of the found node, or empty string if node not found.</returns> | ||
| internal procedure GetNodeValue(XmlDoc: XmlDocument; XmlNamespaces: XmlNamespaceManager; XPath: Text): Text | ||
| var | ||
| XMLNode: XmlNode; | ||
| begin | ||
| if XmlDoc.SelectSingleNode(XPath, XmlNamespaces, XMLNode) then | ||
| exit(XMLNode.AsXmlElement().InnerText()); | ||
| exit(''); | ||
| end; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
Apps/W1/EDocument/app/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| // ------------------------------------------------------------------------------------------------ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. See License.txt in the project root for license information. | ||
| // ------------------------------------------------------------------------------------------------ | ||
| namespace Microsoft.eServices.EDocument.Processing.Import; | ||
|
|
||
| using Microsoft.eServices.EDocument; | ||
| using Microsoft.eServices.EDocument.Processing.Import.Purchase; | ||
| using Microsoft.eServices.EDocument.Processing.Interfaces; | ||
| using Microsoft.Finance.Dimension; | ||
| using Microsoft.Purchases.Document; | ||
|
|
||
| /// <summary> | ||
| /// Dealing with the creation of the purchase credit memo after the draft has been populated. | ||
| /// </summary> | ||
| codeunit 6105 "E-Doc. Create Purch. Cr. Memo" implements IEDocumentFinishDraft, IEDocumentCreatePurchaseCreditMemo | ||
| { | ||
| Access = Internal; | ||
| Permissions = tabledata "Dimension Set Tree Node" = im, | ||
| tabledata "Dimension Set Entry" = im; | ||
|
|
||
| var | ||
| EDocImpSessionTelemetry: Codeunit "E-Doc. Imp. Session Telemetry"; | ||
|
|
||
| /// <summary> | ||
| /// Applies the draft E-Document to Business Central by creating a purchase credit memo from the draft data. | ||
| /// </summary> | ||
| /// <param name="EDocument">The E-Document record containing the draft data to be applied.</param> | ||
| /// <param name="EDocImportParameters">The import parameters containing processing customizations.</param> | ||
| /// <returns>The RecordId of the created purchase credit memo.</returns> | ||
| internal procedure ApplyDraftToBC(EDocument: Record "E-Document"; EDocImportParameters: Record "E-Doc. Import Parameters"): RecordId | ||
| var | ||
| EDocumentPurchaseHeader: Record "E-Document Purchase Header"; | ||
| PurchaseHeader: Record "Purchase Header"; | ||
| EDocPurchaseDocumentHelper: Codeunit "E-Doc Purchase Document Helper"; | ||
| IEDocumentFinishPurchaseDraft: Interface IEDocumentCreatePurchaseCreditMemo; | ||
| begin | ||
| EDocumentPurchaseHeader.GetFromEDocument(EDocument); | ||
| IEDocumentFinishPurchaseDraft := EDocImportParameters."Processing Customizations"; | ||
| PurchaseHeader := IEDocumentFinishPurchaseDraft.CreatePurchaseCreditMemo(EDocument); | ||
|
|
||
| // Post document validation - Silently emit telemetry | ||
| if not EDocPurchaseDocumentHelper.TryValidateDocumentTotals(PurchaseHeader) then | ||
| EDocImpSessionTelemetry.SetBool('Totals Validation Failed', true); | ||
|
|
||
| exit(PurchaseHeader.RecordId); | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Reverts the draft actions by deleting the associated purchase credit memo document. | ||
| /// </summary> | ||
| /// <param name="EDocument">The E-Document record whose draft actions should be reverted.</param> | ||
| internal procedure RevertDraftActions(EDocument: Record "E-Document") | ||
| var | ||
| PurchaseHeader: Record "Purchase Header"; | ||
| begin | ||
| PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId); | ||
| if not PurchaseHeader.FindFirst() then | ||
| exit; | ||
|
|
||
| PurchaseHeader.TestField("Document Type", "Purchase Document Type"::"Credit Memo"); | ||
| Clear(PurchaseHeader."E-Document Link"); | ||
| PurchaseHeader.Delete(true); | ||
| end; | ||
|
|
||
| /// <summary> | ||
| /// Creates a purchase credit memo from E-Document draft data, including header and line information. | ||
| /// </summary> | ||
| /// <param name="EDocument">The E-Document record containing the draft data to create the credit memo from.</param> | ||
| /// <returns>The created purchase header record for the credit memo.</returns> | ||
| internal procedure CreatePurchaseCreditMemo(EDocument: Record "E-Document") PurchaseHeader: Record "Purchase Header" | ||
| var | ||
| EDocPurchaseDocumentHelper: Codeunit "E-Doc Purchase Document Helper"; | ||
| begin | ||
| PurchaseHeader := EDocPurchaseDocumentHelper.CreatePurchaseDocumentHeader(EDocument, "Purchase Document Type"::"Credit Memo"); | ||
| exit(PurchaseHeader); | ||
| end; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.