Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ page 6183 "E-Doc. Purchase Draft Subform"
local procedure OpenMatchedPurchaseOrder(SelectedEDocumentPurchaseLine: Record "E-Document Purchase Line")
var
TempPurchaseOrders: Record "Purchase Header" temporary;
PurchaseOrder: Record "Purchase Header";
CountPOs: Integer;
begin
EDocPOMatching.LoadPOsMatchedToEDocumentLine(SelectedEDocumentPurchaseLine, TempPurchaseOrders);
Expand All @@ -459,7 +460,8 @@ page 6183 "E-Doc. Purchase Draft Subform"
exit;
if CountPOs = 1 then begin
TempPurchaseOrders.FindFirst();
Page.Run(Page::"Purchase Order", TempPurchaseOrders);
PurchaseOrder.Get(TempPurchaseOrders."Document Type", TempPurchaseOrders."No.");
Page.Run(Page::"Purchase Order", PurchaseOrder);
exit;
end;
Page.Run(Page::"Purchase Orders", TempPurchaseOrders);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ codeunit 6196 "E-Doc. PO Matching"
exit;
PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order);
PurchaseLine.SetRange("Pay-to Vendor No.", Vendor."No.");
if EDocumentPurchaseLine."[BC] Unit of Measure" <> '' then
PurchaseLine.SetRange("Unit of Measure Code", EDocumentPurchaseLine."[BC] Unit of Measure");
PurchaseLine.SetLoadFields("Document No.", "Line No.", Description, Quantity, "Qty. Invoiced (Base)", "Qty. Received (Base)", Type, "No.", "Quantity Received", "Quantity Invoiced");
if PurchaseLine.FindSet() then
repeat
Expand Down Expand Up @@ -412,17 +414,20 @@ codeunit 6196 "E-Doc. PO Matching"
OrderLineAndEDocFromDifferentVendorsErr: Label 'All selected purchase order lines must belong to orders for the same vendor as the e-document line.';
OrderLinesMustBeOfSameTypeAndNoErr: Label 'All selected purchase order lines must be of the same type and number.';
NotYetReceivedErr: Label 'The selected purchase order lines are not yet received with the quantity of the invoice. You must first receive them before matching them.';
OrderLinesMustHaveSameUoMErr: Label 'All selected purchase order lines must have the same unit of measure.';
MatchedPOLineType: Enum "Purchase Line Type";
MatchedPOLineVendorNo, MatchedPOLineTypeNo : Code[20];
POLineTypeCollected: Boolean;
MatchedPOLineVendorNo, MatchedPOLineTypeNo, MatchedUnitOfMeasure : Code[20];
FirstOfLinesBeingMatched: Boolean;
begin
if SelectedPOLines.IsEmpty() then
exit;
if SelectedPOLines.Count() > 1 then
Error(MatchesToMultiplePOLinesNotSupportedErr);
RemoveAllMatchesForEDocumentLine(EDocumentPurchaseLine);
FirstOfLinesBeingMatched := true;
MatchedPOLineVendorNo := '';
MatchedPOLineTypeNo := '';
MatchedUnitOfMeasure := '';
if SelectedPOLines.FindSet() then
repeat
// Create new matches, if each line being matched is valid
Expand All @@ -438,28 +443,26 @@ codeunit 6196 "E-Doc. PO Matching"
EDocPurchaseLinePOMatch.SetRange("Purchase Line SystemId", PurchaseLine.SystemId); // The PO Line must not already be matched to another E-Document line
if not EDocPurchaseLinePOMatch.IsEmpty() then
Error(AlreadyMatchedErr, EDocumentPurchaseLine."E-Document Entry No.", SelectedPOLines."Document Type", SelectedPOLines."Document No.");
if EDocumentPurchaseLine."[BC] Unit of Measure" <> '' then
PurchaseLine.TestField("Unit of Measure Code", EDocumentPurchaseLine."[BC] Unit of Measure");

// We ensure that all matched lines have the same Vendor, Type and No.
if MatchedPOLineVendorNo = '' then
MatchedPOLineVendorNo := PurchaseLine."Pay-to Vendor No."
else
if PurchaseLine."Pay-to Vendor No." <> MatchedPOLineVendorNo then
Error(OrderLineAndEDocFromDifferentVendorsErr);

if MatchedPOLineTypeNo = '' then
MatchedPOLineTypeNo := PurchaseLine."No."
else
if PurchaseLine."No." <> MatchedPOLineTypeNo then
Error(OrderLinesMustBeOfSameTypeAndNoErr);

if not POLineTypeCollected then begin
POLineTypeCollected := true;
// We ensure that all matched lines have the same Vendor, Type, No. and Unit of Measure
if FirstOfLinesBeingMatched then begin
MatchedPOLineType := PurchaseLine.Type;
end
else
MatchedPOLineTypeNo := PurchaseLine."No.";
MatchedPOLineVendorNo := PurchaseLine."Pay-to Vendor No.";
MatchedUnitOfMeasure := PurchaseLine."Unit of Measure Code";
FirstOfLinesBeingMatched := false;
end else begin
if PurchaseLine.Type <> MatchedPOLineType then
Error(OrderLinesMustBeOfSameTypeAndNoErr);

if PurchaseLine."No." <> MatchedPOLineTypeNo then
Error(OrderLinesMustBeOfSameTypeAndNoErr);
if PurchaseLine."Pay-to Vendor No." <> MatchedPOLineVendorNo then
Error(OrderLineAndEDocFromDifferentVendorsErr);
if PurchaseLine."Unit of Measure Code" <> MatchedUnitOfMeasure then
Error(OrderLinesMustHaveSameUoMErr);
end;
Clear(EDocPurchaseLinePOMatch);
EDocPurchaseLinePOMatch."E-Doc. Purchase Line SystemId" := EDocumentPurchaseLine.SystemId;
EDocPurchaseLinePOMatch."Purchase Line SystemId" := PurchaseLine.SystemId;
Expand All @@ -469,6 +472,7 @@ codeunit 6196 "E-Doc. PO Matching"
// Set the E-Document Purchase Line properties to match the matched Purchase Line properties
EDocumentPurchaseLine."[BC] Purchase Line Type" := MatchedPOLineType;
EDocumentPurchaseLine."[BC] Purchase Type No." := MatchedPOLineTypeNo;
EDocumentPurchaseLine."[BC] Unit of Measure" := MatchedUnitOfMeasure;
EDocumentPurchaseLine.Modify();
AppendPOMatchWarnings(EDocumentPurchaseLine, TempMatchWarnings);
TempMatchWarnings.SetRange("Warning Type", "E-Doc PO Match Warning"::NotYetReceived);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,161 @@ codeunit 133508 "E-Doc. PO Matching Unit Tests"
Assert.IsFalse(TempPurchaseLine.IsEmpty(), 'Unmatched purchase line should be included');
end;

[Test]
procedure LoadAvailablePOLinesFiltersByUoMWhenEDocLineHasUoMSpecified()
var
EDocument: Record "E-Document";
EDocumentPurchaseHeader: Record "E-Document Purchase Header";
EDocumentPurchaseLine: Record "E-Document Purchase Line";
PurchaseHeader: Record "Purchase Header";
PurchaseLine1, PurchaseLine2 : Record "Purchase Line";
TempPurchaseLine: Record "Purchase Line" temporary;
Item: Record Item;
UnitOfMeasure1, UnitOfMeasure2 : Record "Unit of Measure";
ItemUnitOfMeasure1, ItemUnitOfMeasure2 : Record "Item Unit of Measure";
begin
// [SCENARIO 619582] Loading available PO lines filters by UoM when E-Document line has UoM specified
Initialize();
ClearPurchaseDocumentsForVendor();

// [GIVEN] Item "I" with two units of measure "UOM1" and "UOM2"
LibraryEDocument.GetGenericItem(Item);
LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure1);
LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure2);
LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure1, Item."No.", UnitOfMeasure1.Code, 1);
LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure2, Item."No.", UnitOfMeasure2.Code, 1);

// [GIVEN] Purchase order with line "PL1" having UoM "UOM1" and line "PL2" having UoM "UOM2"
LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No.");
LibraryPurchase.CreatePurchaseLine(PurchaseLine1, PurchaseHeader, PurchaseLine1.Type::Item, Item."No.", 10);
PurchaseLine1.Validate("Unit of Measure Code", UnitOfMeasure1.Code);
PurchaseLine1.Modify(true);
LibraryPurchase.CreatePurchaseLine(PurchaseLine2, PurchaseHeader, PurchaseLine2.Type::Item, Item."No.", 10);
PurchaseLine2.Validate("Unit of Measure Code", UnitOfMeasure2.Code);
PurchaseLine2.Modify(true);

// [GIVEN] E-Document line with UoM "UOM1" specified
LibraryEDocument.CreateInboundEDocument(EDocument, EDocumentService);
EDocumentPurchaseHeader := LibraryEDocument.MockPurchaseDraftPrepared(EDocument);
EDocumentPurchaseHeader."[BC] Vendor No." := Vendor."No.";
EDocumentPurchaseHeader.Modify();
EDocumentPurchaseLine := LibraryEDocument.InsertPurchaseDraftLine(EDocument);
EDocumentPurchaseLine."[BC] Unit of Measure" := UnitOfMeasure1.Code;
EDocumentPurchaseLine.Modify();

// [WHEN] LoadAvailablePOLinesForEDocumentLine is called
EDocPOMatching.LoadAvailablePOLinesForEDocumentLine(EDocumentPurchaseLine, TempPurchaseLine);

// [THEN] Only PO line "PL1" with matching UoM "UOM1" is returned
Assert.AreEqual(1, TempPurchaseLine.Count(), 'Expected only 1 purchase line with matching UoM');
TempPurchaseLine.FindFirst();
Assert.AreEqual(PurchaseLine1.SystemId, TempPurchaseLine.SystemId, 'Expected purchase line with matching UoM to be returned');
end;

[Test]
procedure LoadAvailablePOLinesReturnsAllLinesWhenEDocLineHasNoUoMSpecified()
var
EDocument: Record "E-Document";
EDocumentPurchaseHeader: Record "E-Document Purchase Header";
EDocumentPurchaseLine: Record "E-Document Purchase Line";
PurchaseHeader: Record "Purchase Header";
PurchaseLine1, PurchaseLine2 : Record "Purchase Line";
TempPurchaseLine: Record "Purchase Line" temporary;
Item: Record Item;
UnitOfMeasure1, UnitOfMeasure2 : Record "Unit of Measure";
ItemUnitOfMeasure1, ItemUnitOfMeasure2 : Record "Item Unit of Measure";
begin
// [SCENARIO 619582] Loading available PO lines returns all lines when E-Document line has no UoM specified
Initialize();
ClearPurchaseDocumentsForVendor();

// [GIVEN] Item "I" with two units of measure "UOM1" and "UOM2"
LibraryEDocument.GetGenericItem(Item);
LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure1);
LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure2);
LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure1, Item."No.", UnitOfMeasure1.Code, 1);
LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure2, Item."No.", UnitOfMeasure2.Code, 1);

// [GIVEN] Purchase order with line "PL1" having UoM "UOM1" and line "PL2" having UoM "UOM2"
LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No.");
LibraryPurchase.CreatePurchaseLine(PurchaseLine1, PurchaseHeader, PurchaseLine1.Type::Item, Item."No.", 10);
PurchaseLine1.Validate("Unit of Measure Code", UnitOfMeasure1.Code);
PurchaseLine1.Modify(true);
LibraryPurchase.CreatePurchaseLine(PurchaseLine2, PurchaseHeader, PurchaseLine2.Type::Item, Item."No.", 10);
PurchaseLine2.Validate("Unit of Measure Code", UnitOfMeasure2.Code);
PurchaseLine2.Modify(true);

// [GIVEN] E-Document line with no UoM specified
LibraryEDocument.CreateInboundEDocument(EDocument, EDocumentService);
EDocumentPurchaseHeader := LibraryEDocument.MockPurchaseDraftPrepared(EDocument);
EDocumentPurchaseHeader."[BC] Vendor No." := Vendor."No.";
EDocumentPurchaseHeader.Modify();
EDocumentPurchaseLine := LibraryEDocument.InsertPurchaseDraftLine(EDocument);
EDocumentPurchaseLine."[BC] Unit of Measure" := '';
EDocumentPurchaseLine.Modify();

// [WHEN] LoadAvailablePOLinesForEDocumentLine is called
EDocPOMatching.LoadAvailablePOLinesForEDocumentLine(EDocumentPurchaseLine, TempPurchaseLine);

// [THEN] Both PO lines "PL1" and "PL2" are returned
Assert.AreEqual(2, TempPurchaseLine.Count(), 'Expected 2 purchase lines when E-Document line has no UoM specified');
TempPurchaseLine.SetRange(SystemId, PurchaseLine1.SystemId);
Assert.IsFalse(TempPurchaseLine.IsEmpty(), 'First purchase line should be included');
TempPurchaseLine.SetRange(SystemId, PurchaseLine2.SystemId);
Assert.IsFalse(TempPurchaseLine.IsEmpty(), 'Second purchase line should be included');
end;

[Test]
procedure LoadAvailablePOLinesReturnsNoLinesWhenNoMatchingUoMExists()
var
EDocument: Record "E-Document";
EDocumentPurchaseHeader: Record "E-Document Purchase Header";
EDocumentPurchaseLine: Record "E-Document Purchase Line";
PurchaseHeader: Record "Purchase Header";
PurchaseLine1, PurchaseLine2 : Record "Purchase Line";
TempPurchaseLine: Record "Purchase Line" temporary;
Item: Record Item;
UnitOfMeasure1, UnitOfMeasure2, UnitOfMeasure3 : Record "Unit of Measure";
ItemUnitOfMeasure1, ItemUnitOfMeasure2, ItemUnitOfMeasure3 : Record "Item Unit of Measure";
begin
// [SCENARIO 619582] Loading available PO lines returns no lines when E-Document line has UoM specified but no PO lines have matching UoM
Initialize();
ClearPurchaseDocumentsForVendor();

// [GIVEN] Item "I" with three units of measure "UOM1", "UOM2", and "UOM3"
LibraryEDocument.GetGenericItem(Item);
LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure1);
LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure2);
LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure3);
LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure1, Item."No.", UnitOfMeasure1.Code, 1);
LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure2, Item."No.", UnitOfMeasure2.Code, 1);
LibraryInventory.CreateItemUnitOfMeasure(ItemUnitOfMeasure3, Item."No.", UnitOfMeasure3.Code, 1);

// [GIVEN] Purchase order with line "PL1" having UoM "UOM1" and line "PL2" having UoM "UOM2"
LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No.");
LibraryPurchase.CreatePurchaseLine(PurchaseLine1, PurchaseHeader, PurchaseLine1.Type::Item, Item."No.", 10);
PurchaseLine1.Validate("Unit of Measure Code", UnitOfMeasure1.Code);
PurchaseLine1.Modify(true);
LibraryPurchase.CreatePurchaseLine(PurchaseLine2, PurchaseHeader, PurchaseLine2.Type::Item, Item."No.", 10);
PurchaseLine2.Validate("Unit of Measure Code", UnitOfMeasure2.Code);
PurchaseLine2.Modify(true);

// [GIVEN] E-Document line with UoM "UOM3" specified (not matching any PO line)
LibraryEDocument.CreateInboundEDocument(EDocument, EDocumentService);
EDocumentPurchaseHeader := LibraryEDocument.MockPurchaseDraftPrepared(EDocument);
EDocumentPurchaseHeader."[BC] Vendor No." := Vendor."No.";
EDocumentPurchaseHeader.Modify();
EDocumentPurchaseLine := LibraryEDocument.InsertPurchaseDraftLine(EDocument);
EDocumentPurchaseLine."[BC] Unit of Measure" := UnitOfMeasure3.Code;
EDocumentPurchaseLine.Modify();

// [WHEN] LoadAvailablePOLinesForEDocumentLine is called
EDocPOMatching.LoadAvailablePOLinesForEDocumentLine(EDocumentPurchaseLine, TempPurchaseLine);

// [THEN] No PO lines are returned
Assert.IsTrue(TempPurchaseLine.IsEmpty(), 'Expected no purchase lines when no PO lines have matching UoM');
end;

[Test]
procedure LoadPOLinesMatchedToEDocLineWithNoMatches()
var
Expand Down Expand Up @@ -377,6 +532,10 @@ codeunit 133508 "E-Doc. PO Matching Unit Tests"
LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No.");
LibraryPurchase.CreatePurchaseLine(PurchaseLine1, PurchaseHeader, PurchaseLine1.Type::Item, Item."No.", 5);
LibraryPurchase.CreatePurchaseLine(PurchaseLine2, PurchaseHeader, PurchaseLine2.Type::Item, Item."No.", 10);
PurchaseLine1."Unit of Measure Code" := ItemUnitOfMeasure.Code;
PurchaseLine1.Modify();
PurchaseLine2."Unit of Measure Code" := ItemUnitOfMeasure.Code;
PurchaseLine2.Modify();

// Match E-Document lines to purchase order lines
MatchEDocumentLineToPOLine(EDocumentPurchaseLine1, PurchaseLine1);
Expand Down Expand Up @@ -411,7 +570,6 @@ codeunit 133508 "E-Doc. PO Matching Unit Tests"
PurchaseHeader: Record "Purchase Header";
PurchaseLine: Record "Purchase Line";
Item: Record Item;
ItemUnitOfMeasure: Record "Item Unit of Measure";
TempPOMatchWarnings: Record "E-Doc PO Match Warning" temporary;
begin
Initialize();
Expand All @@ -424,27 +582,18 @@ codeunit 133508 "E-Doc. PO Matching Unit Tests"
LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No.");
LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item."No.", 10);

// Create item with UOM that has different qty per unit of measure
ItemUnitOfMeasure.Init();
ItemUnitOfMeasure."Item No." := Item."No.";
ItemUnitOfMeasure.Code := 'BIGBOX';
ItemUnitOfMeasure."Qty. per Unit of Measure" := 10;
ItemUnitOfMeasure.Insert();

// Create E-Document Purchase Header
EDocumentPurchaseHeader := LibraryEDocument.MockPurchaseDraftPrepared(EDocument);
EDocumentPurchaseHeader."[BC] Vendor No." := Vendor."No.";
EDocumentPurchaseHeader.Modify();

// Set up E-Document line to create quantity mismatch also with 10 units but different UOM
// Set up E-Document line to create quantity mismatch
EDocumentPurchaseLine := LibraryEDocument.InsertPurchaseDraftLine(EDocument);
EDocumentPurchaseLine."[BC] Purchase Line Type" := Enum::"Purchase Line Type"::Item;
EDocumentPurchaseLine."[BC] Purchase Type No." := Item."No.";
EDocumentPurchaseLine."[BC] Unit of Measure" := 'BIGBOX';
EDocumentPurchaseLine.Quantity := 10;
EDocumentPurchaseLine.Quantity := 100;
EDocumentPurchaseLine.Modify();


MatchEDocumentLineToPOLine(EDocumentPurchaseLine, PurchaseLine);

// [WHEN] CalculatePOMatchWarnings is called
Expand Down
Loading