diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
index e26ff50213..c6e4158b08 100644
--- a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
@@ -48,7 +48,6 @@ codeunit 6117 "E-Doc. Create Purchase Invoice" implements IEDocumentFinishDraft,
if not EDocPOMatching.VerifyEDocumentMatchedLinesAreValidMatches(EDocumentPurchaseHeader) then
Error(YourMatchedLinesAreNotValidErr);
- EDocPOMatching.SuggestReceiptsForMatchedOrderLines(EDocumentPurchaseHeader);
EDocPOMatching.CalculatePOMatchWarnings(EDocumentPurchaseHeader, TempPOMatchWarnings);
TempPOMatchWarnings.SetRange("Warning Type", "E-Doc PO Match Warning"::NotYetReceived);
if not TempPOMatchWarnings.IsEmpty() then
@@ -106,16 +105,11 @@ codeunit 6117 "E-Doc. Create Purchase Invoice" implements IEDocumentFinishDraft,
VendorLedgerEntry: Record "Vendor Ledger Entry";
EDocumentPurchaseHeader: Record "E-Document Purchase Header";
EDocumentPurchaseLine: Record "E-Document Purchase Line";
- PurchaseLine: Record "Purchase Line";
EDocRecordLink: Record "E-Doc. Record Link";
PurchCalcDiscByType: Codeunit "Purch - Calc Disc. By Type";
- EDocLineByReceipt: Query "E-Doc. Line by Receipt";
- LastReceiptNo: Code[20];
PurchaseLineNo: Integer;
StopCreatingPurchaseInvoice: Boolean;
VendorInvoiceNo: Code[35];
- ReceiptNoLbl: Label 'Receipt No. %1:', Comment = '%1 = Receipt No.';
- NullGuid: Guid;
begin
EDocumentPurchaseHeader.GetFromEDocument(EDocument);
if not AllDraftLinesHaveTypeAndNumberSpecificed(EDocumentPurchaseHeader) then begin
@@ -155,39 +149,13 @@ codeunit 6117 "E-Doc. Create Purchase Invoice" implements IEDocumentFinishDraft,
end;
EDocRecordLink.InsertEDocumentHeaderLink(EDocumentPurchaseHeader, PurchaseHeader);
- PurchaseLineNo := GetLastLineNumberOnPurchaseInvoice(PurchaseHeader."No."); // We get the last line number, even if this is a new document since recurrent lines get inserted on the header's creation
- // We create first the lines without any PO matches
- EDocLineByReceipt.SetRange(EDocumentEntryNo, EDocument."Entry No");
- EDocLineByReceipt.SetRange(ReceiptNo, '');
- EDocLineByReceipt.SetRange(PurchaseLineSystemId, NullGuid);
- EDocLineByReceipt.Open();
- while EDocLineByReceipt.Read() do begin
- EDocumentPurchaseLine.GetBySystemId(EDocLineByReceipt.SystemId);
- CreatePurchaseInvoiceLine(PurchaseHeader, EDocumentPurchaseLine, EDocumentPurchaseHeader."Total Discount" > 0, PurchaseLineNo);
- end;
- EDocLineByReceipt.Close();
+ PurchaseLineNo := GetLastLineNumberOnPurchaseInvoice(PurchaseHeader."No.");
+ EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
+ if EDocumentPurchaseLine.FindSet() then
+ repeat
+ CreatePurchaseInvoiceLine(PurchaseHeader, EDocumentPurchaseLine, EDocumentPurchaseHeader."Total Discount" > 0, PurchaseLineNo);
+ until EDocumentPurchaseLine.Next() = 0;
- // Then we create the lines with receipt no., adding comment lines for each receipt no.
- LastReceiptNo := '';
- EDocLineByReceipt.SetFilter(ReceiptNo, '<> %1', '');
- EDocLineByReceipt.SetRange(PurchaseLineSystemId);
- EDocLineByReceipt.Open();
- while EDocLineByReceipt.Read() do begin
- if LastReceiptNo <> EDocLineByReceipt.ReceiptNo then begin // A receipt no. for which we have not created a header comment line yet
- Clear(PurchaseLine);
- PurchaseLine."Document Type" := PurchaseHeader."Document Type";
- PurchaseLine."Document No." := PurchaseHeader."No.";
- PurchaseLineNo += 10000;
- PurchaseLine."Line No." := PurchaseLineNo;
- PurchaseLine.Type := PurchaseLine.Type::" ";
- PurchaseLine.Description := StrSubstNo(ReceiptNoLbl, EDocLineByReceipt.ReceiptNo);
- PurchaseLine.Insert();
- end;
- EDocumentPurchaseLine.GetBySystemId(EDocLineByReceipt.SystemId);
- CreatePurchaseInvoiceLine(PurchaseHeader, EDocumentPurchaseLine, EDocumentPurchaseHeader."Total Discount" > 0, PurchaseLineNo);
- LastReceiptNo := EDocLineByReceipt.ReceiptNo;
- end;
- EDocLineByReceipt.Close();
PurchaseHeader.Modify();
PurchCalcDiscByType.ApplyInvDiscBasedOnAmt(EDocumentPurchaseHeader."Total Discount", PurchaseHeader);
exit(PurchaseHeader);
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/PurchaseOrderMatching/EDocLineByReceipt.Query.al b/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/PurchaseOrderMatching/EDocLineByReceipt.Query.al
deleted file mode 100644
index d3ed8bc1d6..0000000000
--- a/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/PurchaseOrderMatching/EDocLineByReceipt.Query.al
+++ /dev/null
@@ -1,49 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// 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.Purchase;
-
-using Microsoft.Purchases.History;
-
-///
-/// Query to get the e-document lines sorted by the receipt number that they have assigned
-///
-query 6100 "E-Doc. Line by Receipt"
-{
- Access = Internal;
- OrderBy = ascending(ReceiptNo);
- InherentEntitlements = X;
- InherentPermissions = X;
-
- elements
- {
- dataitem(EDocumentPurchaseLine; "E-Document Purchase Line")
- {
- column(SystemId; SystemId)
- {
- }
- column(EDocumentEntryNo; "E-Document Entry No.")
- {
- }
- dataitem(EDocPurchaseLinePOMatch; "E-Doc. Purchase Line PO Match")
- {
- DataItemLink = "E-Doc. Purchase Line SystemId" = EDocumentPurchaseLine.SystemId;
- SqlJoinType = LeftOuterJoin;
- column(PurchaseLineSystemId; "Purchase Line SystemId")
- {
- }
- column(ReceiptLineSystemId; "Receipt Line SystemId")
- {
- }
- dataitem(PurchRcptLine; "Purch. Rcpt. Line")
- {
- DataItemLink = SystemId = EDocPurchaseLinePOMatch."Receipt Line SystemId";
- column(ReceiptNo; "Document No.")
- {
- }
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/PurchaseOrderMatching/EDocPOMatching.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/PurchaseOrderMatching/EDocPOMatching.Codeunit.al
index 250f44236d..6f05b20d71 100644
--- a/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/PurchaseOrderMatching/EDocPOMatching.Codeunit.al
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/PurchaseOrderMatching/EDocPOMatching.Codeunit.al
@@ -6,9 +6,11 @@ namespace Microsoft.eServices.EDocument.Processing.Import.Purchase;
using Microsoft.eServices.EDocument;
using Microsoft.Inventory.Item;
+using Microsoft.Inventory.Tracking;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.History;
using Microsoft.Purchases.Vendor;
+using System.Utilities;
codeunit 6196 "E-Doc. PO Matching"
{
@@ -408,7 +410,6 @@ codeunit 6196 "E-Doc. PO Matching"
Vendor: Record Vendor;
EDocPurchaseLinePOMatch: Record "E-Doc. Purchase Line PO Match";
TempMatchWarnings: Record "E-Doc PO Match Warning" temporary;
- MatchesToMultiplePOLinesNotSupportedErr: Label 'Matching an e-document line to multiple purchase order lines is not currently supported.';
NotLinkedToVendorErr: Label 'The selected purchase order line is not linked to the same vendor as the e-document line.';
AlreadyMatchedErr: Label 'A selected purchase order line is already matched to another e-document line. E-Document: %1, Purchase document: %2 %3.', Comment = '%1 - E-Document No., %2 - Purchase Document Type, %3 - Purchase Document No.';
OrderLineAndEDocFromDifferentVendorsErr: Label 'All selected purchase order lines must belong to orders for the same vendor as the e-document line.';
@@ -421,8 +422,6 @@ codeunit 6196 "E-Doc. PO Matching"
begin
if SelectedPOLines.IsEmpty() then
exit;
- if SelectedPOLines.Count() > 1 then
- Error(MatchesToMultiplePOLinesNotSupportedErr);
RemoveAllMatchesForEDocumentLine(EDocumentPurchaseLine);
FirstOfLinesBeingMatched := true;
MatchedPOLineVendorNo := '';
@@ -483,8 +482,7 @@ codeunit 6196 "E-Doc. PO Matching"
///
/// Matches the specified purchase receipt lines to the specified E-Document line.
/// Each receipt line must be matched to a purchase order line that is matched to the specified E-Document line.
- /// Existing matches are removed.
- /// If the receipt lines can't cover the full quantity of the E-Document line, the procedure raises an error.
+ /// Existing receipt matches are removed before creating new ones.
///
///
///
@@ -494,14 +492,9 @@ codeunit 6196 "E-Doc. PO Matching"
TempMatchedPurchaseLines: Record "Purchase Line" temporary;
NullGuid: Guid;
ReceiptLineNotMatchedErr: Label 'A selected receipt line is not matched to any of the purchase order lines matched to the e-document line.';
- ReceiptLinesDontCoverErr: Label 'The selected receipt lines do not cover the full quantity of the e-document line.';
- MatchesToMultipleReceiptLinesNotSupportedErr: Label 'Matching an e-document line to multiple receipt lines is not currently supported.';
- QuantityCovered: Decimal;
begin
if SelectedReceiptLines.IsEmpty() then
exit;
- if SelectedReceiptLines.Count() > 1 then
- Error(MatchesToMultipleReceiptLinesNotSupportedErr);
// Remove existing receipt line matches
EDocPurchaseLinePOMatch.SetRange("E-Doc. Purchase Line SystemId", EDocumentPurchaseLine.SystemId);
@@ -521,10 +514,7 @@ codeunit 6196 "E-Doc. PO Matching"
EDocPurchaseLinePOMatch."Purchase Line SystemId" := TempMatchedPurchaseLines.SystemId;
EDocPurchaseLinePOMatch."Receipt Line SystemId" := SelectedReceiptLines.SystemId;
EDocPurchaseLinePOMatch.Insert();
- QuantityCovered += SelectedReceiptLines.Quantity;
until SelectedReceiptLines.Next() = 0;
- if QuantityCovered < EDocumentPurchaseLine.Quantity then
- Error(ReceiptLinesDontCoverErr);
end;
procedure ConfigureDefaultPOMatchingSettings()
@@ -587,55 +577,6 @@ codeunit 6196 "E-Doc. PO Matching"
end;
end;
- ///
- /// If the E-Document has been matched to an order line without specifying receipts, we match with receipt lines for that order line that can cover the E-Document line quantity.
- ///
- ///
- procedure SuggestReceiptsForMatchedOrderLines(EDocumentPurchaseHeader: Record "E-Document Purchase Header")
- var
- EDocumentPurchaseLine: Record "E-Document Purchase Line";
- EDocPurchaseLinePOMatch: Record "E-Doc. Purchase Line PO Match";
- PurchaseOrderLine: Record "Purchase Line";
- PurchaseReceiptLine: Record "Purch. Rcpt. Line";
- TempPurchaseReceiptLine: Record "Purch. Rcpt. Line" temporary;
- EDocLineQuantity: Decimal;
- NullGuid: Guid;
- begin
- EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocumentPurchaseHeader."E-Document Entry No.");
- if EDocumentPurchaseLine.FindSet() then
- repeat
- Clear(EDocPurchaseLinePOMatch);
- EDocPurchaseLinePOMatch.SetRange("E-Doc. Purchase Line SystemId", EDocumentPurchaseLine.SystemId);
- EDocPurchaseLinePOMatch.SetRange("Receipt Line SystemId", NullGuid);
- if not EDocPurchaseLinePOMatch.FindFirst() then
- continue; // No PO lines matched, so no receipt can be suggested
- if not PurchaseOrderLine.GetBySystemId(EDocPurchaseLinePOMatch."Purchase Line SystemId") then
- continue; // Should not happen, but we skip in case it does, this procedure doesn't error out
- EDocPurchaseLinePOMatch.SetRange("Purchase Line SystemId", PurchaseOrderLine.SystemId);
- EDocPurchaseLinePOMatch.SetFilter("Receipt Line SystemId", '<> %1', NullGuid);
- if not EDocPurchaseLinePOMatch.IsEmpty() then
- continue; // There's already at least one receipt line matched, so no suggestion is needed
- Session.LogMessage('0000QQI', 'Suggesting receipt line for draft line matched to PO line', Verbosity::Verbose, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', 'E-Document');
- PurchaseReceiptLine.SetRange("Order No.", PurchaseOrderLine."Document No.");
- PurchaseReceiptLine.SetRange("Order Line No.", PurchaseOrderLine."Line No.");
- PurchaseReceiptLine.SetFilter(Quantity, '> 0');
- if PurchaseReceiptLine.FindSet() then
- repeat
- if GetEDocumentLineQuantityInBaseUoM(EDocumentPurchaseLine, EDocLineQuantity) then
- if PurchaseReceiptLine.Quantity >= EDocLineQuantity then begin
- // We suggest the first receipt line that can cover the full quantity of the E-Document line
- Session.LogMessage('0000QQJ', 'Suggested covering receipt line for draft line matched to PO line', Verbosity::Verbose, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', 'E-Document');
- Clear(TempPurchaseReceiptLine);
- TempPurchaseReceiptLine.DeleteAll();
- TempPurchaseReceiptLine.Copy(PurchaseReceiptLine);
- TempPurchaseReceiptLine.Insert();
- MatchReceiptLinesToEDocumentLine(TempPurchaseReceiptLine, EDocumentPurchaseLine);
- break; // We only suggest a single receipt line
- end;
- until PurchaseReceiptLine.Next() = 0;
- until EDocumentPurchaseLine.Next() = 0;
- end;
-
local procedure GetEDocumentLineQuantityInBaseUoM(EDocumentPurchaseLine: Record "E-Document Purchase Line"; var Quantity: Decimal): Boolean
var
Item: Record Item;
@@ -664,21 +605,50 @@ codeunit 6196 "E-Doc. PO Matching"
procedure TransferPOMatchesFromEDocumentToInvoice(EDocument: Record "E-Document")
var
EDocumentPurchaseLine: Record "E-Document Purchase Line";
+ EDocPurchaseLinePOMatch: Record "E-Doc. Purchase Line PO Match";
PurchaseLine: Record "Purchase Line";
- TempPurchaseReceiptLine: Record "Purch. Rcpt. Line" temporary;
+ PurchaseOrderLine: Record "Purchase Line";
+ PurchRcptLine: Record "Purch. Rcpt. Line";
+ Math: Codeunit Math;
+ PurchaseOrderMatching: Codeunit "Purchase Order Matching";
+ NullGuid: Guid;
+ RemainingQty, RemainingQtyBase, AllocatedQty, AllocatedQtyBase : Decimal;
begin
EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
if EDocumentPurchaseLine.FindSet() then
repeat
- LoadReceiptLinesMatchedToEDocumentLine(EDocumentPurchaseLine, TempPurchaseReceiptLine);
- if not TempPurchaseReceiptLine.FindFirst() then // We only support a single receipt line match in BaseApp
- continue;
PurchaseLine := EDocumentPurchaseLine.GetLinkedPurchaseLine();
if IsNullGuid(PurchaseLine.SystemId) then
continue;
- PurchaseLine."Receipt No." := TempPurchaseReceiptLine."Document No.";
- PurchaseLine."Receipt Line No." := TempPurchaseReceiptLine."Line No.";
- PurchaseLine.Modify();
+
+ EDocPurchaseLinePOMatch.SetRange("E-Doc. Purchase Line SystemId", EDocumentPurchaseLine.SystemId);
+ EDocPurchaseLinePOMatch.SetFilter("Receipt Line SystemId", '<>%1', NullGuid);
+ if EDocPurchaseLinePOMatch.IsEmpty() then
+ continue;
+
+ RemainingQty := PurchaseLine.Quantity;
+ RemainingQtyBase := PurchaseLine."Quantity (Base)";
+ EDocPurchaseLinePOMatch.FindSet();
+ repeat
+ if not PurchaseOrderLine.GetBySystemId(EDocPurchaseLinePOMatch."Purchase Line SystemId") then
+ continue;
+ if not PurchRcptLine.GetBySystemId(EDocPurchaseLinePOMatch."Receipt Line SystemId") then
+ continue;
+
+ AllocatedQty := Math.Min(RemainingQty, PurchRcptLine.Quantity);
+ AllocatedQtyBase := Math.Min(RemainingQtyBase, PurchRcptLine."Quantity (Base)");
+ if AllocatedQty <= 0 then
+ continue;
+
+ PurchaseOrderMatching.CreateReceiptMatch(
+ PurchaseLine, PurchaseOrderLine, PurchRcptLine,
+ AllocatedQty, AllocatedQtyBase,
+ not ShouldWarnIfNotYetReceived(EDocumentPurchaseLine.GetBCVendor()."No."));
+
+ RemainingQty -= AllocatedQty;
+ RemainingQtyBase -= AllocatedQtyBase;
+ until EDocPurchaseLinePOMatch.Next() = 0;
+
RemoveAllMatchesForEDocumentLine(EDocumentPurchaseLine);
until EDocumentPurchaseLine.Next() = 0;
end;
@@ -691,39 +661,27 @@ codeunit 6196 "E-Doc. PO Matching"
var
EDocumentPurchaseLine: Record "E-Document Purchase Line";
PurchaseInvoiceLine: Record "Purchase Line";
- PurchaseOrderLine: Record "Purchase Line";
- PurchaseReceiptLine: Record "Purch. Rcpt. Line";
TempPOLineToMatch: Record "Purchase Line" temporary;
TempReceiptLineToMatch: Record "Purch. Rcpt. Line" temporary;
+ PurchaseOrderMatching: Codeunit "Purchase Order Matching";
begin
PurchaseInvoiceLine.SetRange("Document Type", PurchaseHeader."Document Type");
PurchaseInvoiceLine.SetRange("Document No.", PurchaseHeader."No.");
- PurchaseInvoiceLine.SetFilter("Receipt No.", '<>%1', '');
- PurchaseInvoiceLine.SetFilter("Receipt Line No.", '<>%1', 0);
- if PurchaseInvoiceLine.IsEmpty() then
- exit;
- PurchaseInvoiceLine.FindSet();
- repeat
- if not EDocumentPurchaseLine.GetFromLinkedPurchaseLine(PurchaseInvoiceLine) then
- continue;
- if not PurchaseReceiptLine.Get(PurchaseInvoiceLine."Receipt No.", PurchaseInvoiceLine."Receipt Line No.") then
- continue;
- if not PurchaseOrderLine.Get(Enum::"Purchase Document Type"::Order, PurchaseReceiptLine."Order No.", PurchaseReceiptLine."Order Line No.") then
- continue;
- TempPOLineToMatch.DeleteAll();
- TempPOLineToMatch.Copy(PurchaseOrderLine);
- TempPOLineToMatch.Insert();
- MatchPOLinesToEDocumentLine(TempPOLineToMatch, EDocumentPurchaseLine);
-
- TempReceiptLineToMatch.DeleteAll();
- TempReceiptLineToMatch.Copy(PurchaseReceiptLine);
- TempReceiptLineToMatch.Insert();
- MatchReceiptLinesToEDocumentLine(TempReceiptLineToMatch, EDocumentPurchaseLine);
- until PurchaseInvoiceLine.Next() = 0;
- PurchaseInvoiceLine.SetRange("Receipt No.");
- PurchaseInvoiceLine.SetRange("Receipt Line No.");
- PurchaseInvoiceLine.ModifyAll("Receipt No.", '');
- PurchaseInvoiceLine.ModifyAll("Receipt Line No.", 0);
+ if PurchaseInvoiceLine.FindSet() then
+ repeat
+ if not EDocumentPurchaseLine.GetFromLinkedPurchaseLine(PurchaseInvoiceLine) then
+ continue;
+
+ PurchaseOrderMatching.LoadMatchedOrderLines(PurchaseInvoiceLine, TempPOLineToMatch);
+ if not TempPOLineToMatch.IsEmpty() then
+ MatchPOLinesToEDocumentLine(TempPOLineToMatch, EDocumentPurchaseLine);
+
+ PurchaseOrderMatching.LoadMatchedReceiptLines(PurchaseInvoiceLine, TempReceiptLineToMatch);
+ if not TempReceiptLineToMatch.IsEmpty() then
+ MatchReceiptLinesToEDocumentLine(TempReceiptLineToMatch, EDocumentPurchaseLine);
+
+ PurchaseOrderMatching.DeleteMatchesForInvoiceLine(PurchaseInvoiceLine);
+ until PurchaseInvoiceLine.Next() = 0;
end;
///
diff --git a/src/Apps/W1/EDocument/Test/src/Matching/EDocPOMatchingUnitTests.Codeunit.al b/src/Apps/W1/EDocument/Test/src/Matching/EDocPOMatchingUnitTests.Codeunit.al
index 4133a2fb53..6f9db7cb7f 100644
--- a/src/Apps/W1/EDocument/Test/src/Matching/EDocPOMatchingUnitTests.Codeunit.al
+++ b/src/Apps/W1/EDocument/Test/src/Matching/EDocPOMatchingUnitTests.Codeunit.al
@@ -2172,160 +2172,6 @@ codeunit 133508 "E-Doc. PO Matching Unit Tests"
Assert.IsTrue(TempPOMatchWarnings.IsEmpty(), 'Expected no NotYetReceived warning for non-specified vendor');
end;
- [Test]
- procedure SuggestReceiptsForMatchedOrderLinesDoesNotSuggestWhenEDocLineAlreadyHasReceiptMatch()
- var
- EDocument: Record "E-Document";
- EDocumentPurchaseHeader: Record "E-Document Purchase Header";
- EDocumentPurchaseLine: Record "E-Document Purchase Line";
- PurchaseHeader: Record "Purchase Header";
- PurchaseLine: Record "Purchase Line";
- PurchaseReceiptHeader: Record "Purch. Rcpt. Header";
- PurchaseReceiptLine: Record "Purch. Rcpt. Line";
- Item: Record Item;
- begin
- Initialize();
- // [SCENARIO] SuggestReceiptsForMatchedOrderLines suggests no receipts when E-Document line already has a receipt match
- // [GIVEN] An E-Document line matched to a receipt line and an additional receipt line that could be suggested
- CreateMockEDocumentDraftWithLine(EDocument, EDocumentPurchaseHeader, EDocumentPurchaseLine, 10);
- LibraryInventory.CreateItem(Item);
- LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No.");
- LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item."No.", 10);
-
- // Match E-Document line to PO line
- MatchEDocumentLineToPOLine(EDocumentPurchaseLine, PurchaseLine);
-
- // Create receipt with 2 lines that could be suggested, match the last one to an E-Document line
- CreateMockReceiptHeader(PurchaseReceiptHeader, Vendor."No.");
- CreateMockReceiptLine(PurchaseReceiptLine, PurchaseReceiptHeader, Item."No.", 10, PurchaseLine);
- CreateMockReceiptLine(PurchaseReceiptLine, PurchaseReceiptHeader, Item."No.", 10, PurchaseLine);
- MatchEDocumentLineToReceiptLine(EDocumentPurchaseLine, PurchaseReceiptLine);
-
- // [WHEN] SuggestReceiptsForMatchedOrderLines is called
- EDocPOMatching.SuggestReceiptsForMatchedOrderLines(EDocumentPurchaseHeader);
-
- // [THEN] No additional receipt lines are matched (still just the one)
- Assert.IsTrue(EDocPOMatching.IsReceiptLineMatchedToEDocumentLine(PurchaseReceiptLine, EDocumentPurchaseLine), 'Expected the original receipt match to remain');
- Assert.AreEqual(1, CountReceiptMatchesForEDocumentLine(EDocumentPurchaseLine), 'Expected exactly one receipt match');
- end;
-
- [Test]
- procedure SuggestReceiptsForMatchedOrderLinesSuggestsReceiptWhenPOLineHasSingleReceiptCoveringFullQuantity()
- var
- EDocument: Record "E-Document";
- EDocumentPurchaseHeader: Record "E-Document Purchase Header";
- EDocumentPurchaseLine: Record "E-Document Purchase Line";
- PurchaseHeader: Record "Purchase Header";
- PurchaseLine: Record "Purchase Line";
- PurchaseReceiptHeader: Record "Purch. Rcpt. Header";
- PurchaseReceiptLine: Record "Purch. Rcpt. Line";
- Item: Record Item;
- begin
- Initialize();
- // [SCENARIO] SuggestReceiptsForMatchedOrderLines suggests receipt when PO line has a single receipt that covers full quantity
- // [GIVEN] An E-Document line matched to a purchase order line with quantity 10
- CreateMockEDocumentDraftWithLine(EDocument, EDocumentPurchaseHeader, EDocumentPurchaseLine, 10);
-
- // [GIVEN] The purchase order line has one receipt line with quantity 10
- LibraryInventory.CreateItem(Item);
- LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No.");
- LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item."No.", 10);
- EDocumentPurchaseLine."[BC] Unit of Measure" := PurchaseLine."Unit of Measure Code";
- EDocumentPurchaseLine.Modify();
- MatchEDocumentLineToPOLine(EDocumentPurchaseLine, PurchaseLine);
-
- CreateMockReceiptHeader(PurchaseReceiptHeader, Vendor."No.");
- CreateMockReceiptLine(PurchaseReceiptLine, PurchaseReceiptHeader, Item."No.", 10, PurchaseLine);
-
- // [WHEN] SuggestReceiptsForMatchedOrderLines is called
- EDocPOMatching.SuggestReceiptsForMatchedOrderLines(EDocumentPurchaseHeader);
-
- // [THEN] The receipt line is matched to the E-Document line
- Assert.IsTrue(EDocPOMatching.IsReceiptLineMatchedToEDocumentLine(PurchaseReceiptLine, EDocumentPurchaseLine), 'Expected receipt line to be matched to E-Document line');
- end;
-
- [Test]
- procedure SuggestReceiptsForMatchedOrderLinesSuggestsNoReceiptWhenAllReceiptsHaveInsufficientQuantity()
- var
- EDocument: Record "E-Document";
- EDocumentPurchaseHeader: Record "E-Document Purchase Header";
- EDocumentPurchaseLine: Record "E-Document Purchase Line";
- PurchaseHeader: Record "Purchase Header";
- PurchaseLine: Record "Purchase Line";
- PurchaseReceiptHeader: Record "Purch. Rcpt. Header";
- PurchaseReceiptLine1, PurchaseReceiptLine2 : Record "Purch. Rcpt. Line";
- Item: Record Item;
- begin
- Initialize();
- // [SCENARIO] SuggestReceiptsForMatchedOrderLines suggests no receipt when all receipts have insufficient quantity
- // [GIVEN] An E-Document line matched to a purchase order line with quantity 10
- CreateMockEDocumentDraftWithLine(EDocument, EDocumentPurchaseHeader, EDocumentPurchaseLine, 10);
-
- // [GIVEN] The purchase order line has two receipt lines with quantities 5 and 7
- LibraryInventory.CreateItem(Item);
- LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No.");
- LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item."No.", 10);
- MatchEDocumentLineToPOLine(EDocumentPurchaseLine, PurchaseLine);
-
- CreateMockReceiptHeader(PurchaseReceiptHeader, Vendor."No.");
- CreateMockReceiptLine(PurchaseReceiptLine1, PurchaseReceiptHeader, Item."No.", 5, PurchaseLine);
- CreateMockReceiptLine(PurchaseReceiptLine2, PurchaseReceiptHeader, Item."No.", 7, PurchaseLine);
-
- // [WHEN] SuggestReceiptsForMatchedOrderLines is called
- EDocPOMatching.SuggestReceiptsForMatchedOrderLines(EDocumentPurchaseHeader);
-
- // [THEN] No receipt lines are matched to the E-Document line
- Assert.IsFalse(EDocPOMatching.IsEDocumentLineMatchedToAnyReceiptLine(EDocumentPurchaseLine), 'Expected no receipt lines to be matched');
- end;
-
- [Test]
- procedure SuggestReceiptsForMatchedOrderLinesProcessesMultipleEDocumentLinesIndependently()
- var
- EDocument: Record "E-Document";
- EDocumentPurchaseHeader: Record "E-Document Purchase Header";
- EDocumentPurchaseLine1, EDocumentPurchaseLine2 : Record "E-Document Purchase Line";
- PurchaseHeader1, PurchaseHeader2 : Record "Purchase Header";
- PurchaseLine1, PurchaseLine2 : Record "Purchase Line";
- PurchaseReceiptHeader1, PurchaseReceiptHeader2 : Record "Purch. Rcpt. Header";
- PurchaseReceiptLine1, PurchaseReceiptLine2 : Record "Purch. Rcpt. Line";
- Item1, Item2 : Record Item;
- begin
- Initialize();
- // [SCENARIO] SuggestReceiptsForMatchedOrderLines processes multiple E-Document lines independently
- // [GIVEN] An E-Document with two lines matched to different purchase order lines
- CreateMockEDocumentDraftWithLine(EDocument, EDocumentPurchaseHeader, EDocumentPurchaseLine1, 10);
- // Second E-Document line
- EDocumentPurchaseLine2 := LibraryEDocument.InsertPurchaseDraftLine(EDocument);
- EDocumentPurchaseLine2.Quantity := 15;
- EDocumentPurchaseLine2.Modify();
-
- // [GIVEN] Each purchase order line has its own receipt that covers the full quantity
- LibraryInventory.CreateItem(Item1);
- LibraryPurchase.CreatePurchHeader(PurchaseHeader1, PurchaseHeader1."Document Type"::Order, Vendor."No.");
- LibraryPurchase.CreatePurchaseLine(PurchaseLine1, PurchaseHeader1, PurchaseLine1.Type::Item, Item1."No.", 10);
- EDocumentPurchaseLine1."[BC] Unit of Measure" := PurchaseLine1."Unit of Measure Code";
- EDocumentPurchaseLine1.Modify();
- MatchEDocumentLineToPOLine(EDocumentPurchaseLine1, PurchaseLine1);
- CreateMockReceiptHeader(PurchaseReceiptHeader1, Vendor."No.");
- CreateMockReceiptLine(PurchaseReceiptLine1, PurchaseReceiptHeader1, Item1."No.", 10, PurchaseLine1);
-
- LibraryInventory.CreateItem(Item2);
- LibraryPurchase.CreatePurchHeader(PurchaseHeader2, PurchaseHeader2."Document Type"::Order, Vendor."No.");
- LibraryPurchase.CreatePurchaseLine(PurchaseLine2, PurchaseHeader2, PurchaseLine2.Type::Item, Item2."No.", 15);
- EDocumentPurchaseLine2."[BC] Unit of Measure" := PurchaseLine2."Unit of Measure Code";
- EDocumentPurchaseLine2.Modify();
- MatchEDocumentLineToPOLine(EDocumentPurchaseLine2, PurchaseLine2);
- CreateMockReceiptHeader(PurchaseReceiptHeader2, Vendor."No.");
- CreateMockReceiptLine(PurchaseReceiptLine2, PurchaseReceiptHeader2, Item2."No.", 15, PurchaseLine2);
-
- // [WHEN] SuggestReceiptsForMatchedOrderLines is called
- EDocPOMatching.SuggestReceiptsForMatchedOrderLines(EDocumentPurchaseHeader);
-
- // [THEN] Each E-Document line is matched to its corresponding receipt line
- Assert.IsTrue(EDocPOMatching.IsReceiptLineMatchedToEDocumentLine(PurchaseReceiptLine1, EDocumentPurchaseLine1), 'Expected first receipt line to be matched to first E-Document line');
- Assert.IsTrue(EDocPOMatching.IsReceiptLineMatchedToEDocumentLine(PurchaseReceiptLine2, EDocumentPurchaseLine2), 'Expected second receipt line to be matched to second E-Document line');
- end;
-
[Test]
procedure TransferPOMatchesFromEDocumentToInvoiceTransfersReceiptMatchAndRemovesEDocumentMatches()
var