diff --git a/src/Layers/APAC/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al b/src/Layers/APAC/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al index ae160cae3f5..24cf182b161 100644 --- a/src/Layers/APAC/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al +++ b/src/Layers/APAC/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al @@ -1028,6 +1028,7 @@ codeunit 1303 "Correct Posted Sales Invoice" var SalesCrMemoLine: Record "Sales Cr.Memo Line"; SalesInvoiceLine: Record "Sales Invoice Line"; + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; begin SalesCrMemoLine.SetLoadFields("Document No.", "No.", "Appl.-from Item Entry", Quantity, "Variant Code"); SalesCrMemoLine.SetRange("Document No.", SalesCreditMemoNo); @@ -1036,9 +1037,12 @@ codeunit 1303 "Correct Posted Sales Invoice" if SalesCrMemoLine.FindSet() then repeat Clear(SalesInvoiceLine); - SalesCrMemoLine.GetSalesInvoiceLine(SalesInvoiceLine); - if SalesInvoiceLine."Line No." <> 0 then + SalesCrMemoLine.GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + if SalesInvoiceLine."Line No." <> 0 then begin UpdateSalesOrderLinesFromCreditMemo(SalesInvoiceLine, SalesCrMemoLine); + TempUsedSalesInvoiceLine := SalesInvoiceLine; + if TempUsedSalesInvoiceLine.Insert() then; + end; until SalesCrMemoLine.Next() = 0; end; diff --git a/src/Layers/APAC/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/APAC/BaseApp/Sales/History/SalesCrMemoLine.Table.al index feeb29a89b0..f5908ab2981 100644 --- a/src/Layers/APAC/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/APAC/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1247,6 +1247,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1281,14 +1288,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/CH/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/CH/BaseApp/Sales/History/SalesCrMemoLine.Table.al index af18d5148bb..1976982ddf8 100644 --- a/src/Layers/CH/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/CH/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1213,6 +1213,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1247,14 +1254,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/ES/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al b/src/Layers/ES/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al index c34bfa57c32..42c8f3ddb89 100644 --- a/src/Layers/ES/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al +++ b/src/Layers/ES/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al @@ -1027,6 +1027,7 @@ codeunit 1303 "Correct Posted Sales Invoice" var SalesCrMemoLine: Record "Sales Cr.Memo Line"; SalesInvoiceLine: Record "Sales Invoice Line"; + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; begin SalesCrMemoLine.SetLoadFields("Document No.", "No.", "Appl.-from Item Entry", Quantity, "Variant Code"); SalesCrMemoLine.SetRange("Document No.", SalesCreditMemoNo); @@ -1035,9 +1036,12 @@ codeunit 1303 "Correct Posted Sales Invoice" if SalesCrMemoLine.FindSet() then repeat Clear(SalesInvoiceLine); - SalesCrMemoLine.GetSalesInvoiceLine(SalesInvoiceLine); - if SalesInvoiceLine."Line No." <> 0 then + SalesCrMemoLine.GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + if SalesInvoiceLine."Line No." <> 0 then begin UpdateSalesOrderLinesFromCreditMemo(SalesInvoiceLine, SalesCrMemoLine); + TempUsedSalesInvoiceLine := SalesInvoiceLine; + if TempUsedSalesInvoiceLine.Insert() then; + end; until SalesCrMemoLine.Next() = 0; end; diff --git a/src/Layers/ES/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/ES/BaseApp/Sales/History/SalesCrMemoLine.Table.al index 32f27a06bd1..c7fcc0a1784 100644 --- a/src/Layers/ES/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/ES/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1183,6 +1183,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1217,14 +1224,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/FI/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/FI/BaseApp/Sales/History/SalesCrMemoLine.Table.al index 711acf6285a..d604dccb6d4 100644 --- a/src/Layers/FI/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/FI/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1181,6 +1181,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1215,14 +1222,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/GB/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/GB/BaseApp/Sales/History/SalesCrMemoLine.Table.al index 71904b63891..017e46f406a 100644 --- a/src/Layers/GB/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/GB/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1198,6 +1198,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1232,14 +1239,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/IT/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/IT/BaseApp/Sales/History/SalesCrMemoLine.Table.al index 67df98b6bab..02da481cf32 100644 --- a/src/Layers/IT/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/IT/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1204,6 +1204,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1238,14 +1245,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/NA/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/NA/BaseApp/Sales/History/SalesCrMemoLine.Table.al index 03b265d00a6..1b48132036b 100644 --- a/src/Layers/NA/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/NA/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1190,6 +1190,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1224,14 +1231,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/NO/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/NO/BaseApp/Sales/History/SalesCrMemoLine.Table.al index 3d877835c08..4ea298236c9 100644 --- a/src/Layers/NO/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/NO/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1199,6 +1199,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1233,14 +1240,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/RU/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/RU/BaseApp/Sales/History/SalesCrMemoLine.Table.al index edc6b3ef059..939149a16d3 100644 --- a/src/Layers/RU/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/RU/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1300,6 +1300,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1334,14 +1341,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/SE/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/SE/BaseApp/Sales/History/SalesCrMemoLine.Table.al index 711acf6285a..d604dccb6d4 100644 --- a/src/Layers/SE/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/SE/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1181,6 +1181,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1215,14 +1222,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al b/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al index cfb8bc8bd2d..e8eef69d128 100644 --- a/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al +++ b/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al @@ -1027,6 +1027,7 @@ codeunit 1303 "Correct Posted Sales Invoice" var SalesCrMemoLine: Record "Sales Cr.Memo Line"; SalesInvoiceLine: Record "Sales Invoice Line"; + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; begin SalesCrMemoLine.SetLoadFields("Document No.", "No.", "Appl.-from Item Entry", Quantity, "Variant Code"); SalesCrMemoLine.SetRange("Document No.", SalesCreditMemoNo); @@ -1035,9 +1036,12 @@ codeunit 1303 "Correct Posted Sales Invoice" if SalesCrMemoLine.FindSet() then repeat Clear(SalesInvoiceLine); - SalesCrMemoLine.GetSalesInvoiceLine(SalesInvoiceLine); - if SalesInvoiceLine."Line No." <> 0 then + SalesCrMemoLine.GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + if SalesInvoiceLine."Line No." <> 0 then begin UpdateSalesOrderLinesFromCreditMemo(SalesInvoiceLine, SalesCrMemoLine); + TempUsedSalesInvoiceLine := SalesInvoiceLine; + if TempUsedSalesInvoiceLine.Insert() then; + end; until SalesCrMemoLine.Next() = 0; end; diff --git a/src/Layers/W1/BaseApp/Sales/History/SalesCrMemoLine.Table.al b/src/Layers/W1/BaseApp/Sales/History/SalesCrMemoLine.Table.al index c355366c34d..fa12037dbe8 100644 --- a/src/Layers/W1/BaseApp/Sales/History/SalesCrMemoLine.Table.al +++ b/src/Layers/W1/BaseApp/Sales/History/SalesCrMemoLine.Table.al @@ -1170,6 +1170,13 @@ table 115 "Sales Cr.Memo Line" end; internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line") + var + TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; + begin + GetSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine); + end; + + internal procedure GetSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary) var ItemLedgerEntry: Record "Item Ledger Entry"; SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; @@ -1204,14 +1211,32 @@ table 115 "Sales Cr.Memo Line" SalesInvoiceLine.SetRange("Document No.", SalesCreditMemoHeader."Applies-to Doc. No."); SalesInvoiceLine.SetRange(Type, Type); SalesInvoiceLine.SetRange("No.", "No."); + SalesInvoiceLine.SetRange("Variant Code", "Variant Code"); + + SalesInvoiceLine.SetRange(Quantity, Quantity); + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; SalesInvoiceLine.SetFilter(Quantity, '>=%1', Quantity); - if SalesInvoiceLine.FindFirst() then + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then exit; SalesInvoiceLine.SetRange(Quantity); - if SalesInvoiceLine.FindFirst() then; + if FindUnusedSalesInvoiceLine(SalesInvoiceLine, TempUsedSalesInvoiceLine) then + exit; + + Clear(SalesInvoiceLine); end; end; + local procedure FindUnusedSalesInvoiceLine(var SalesInvoiceLine: Record "Sales Invoice Line"; var TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary): Boolean + begin + if SalesInvoiceLine.FindSet() then + repeat + if not TempUsedSalesInvoiceLine.Get(SalesInvoiceLine."Document No.", SalesInvoiceLine."Line No.") then + exit(true); + until SalesInvoiceLine.Next() = 0; + exit(false); + end; + local procedure CheckApplFromItemLedgEntry(var ItemLedgerEntry: Record "Item Ledger Entry") begin if "Appl.-from Item Entry" = 0 then diff --git a/src/Layers/W1/Tests/SCM/SCMCorrectInvoice.Codeunit.al b/src/Layers/W1/Tests/SCM/SCMCorrectInvoice.Codeunit.al index e2f853cdecd..8475e217866 100644 --- a/src/Layers/W1/Tests/SCM/SCMCorrectInvoice.Codeunit.al +++ b/src/Layers/W1/Tests/SCM/SCMCorrectInvoice.Codeunit.al @@ -1333,6 +1333,81 @@ codeunit 137019 "SCM Correct Invoice" StrSubstNo(SalesOrderLineReducedErr, SalesLine[1].FieldCaption("Quantity Shipped"))); end; + [Test] + procedure PostCrMemoCopyDocRevertsCorrectOrderLinesForSameItemAcrossOrders() + var + Item: Record Item; + Customer: Record Customer; + SalesHeaderOrder: array[2] of Record "Sales Header"; + SalesLineOrder: array[2] of Record "Sales Line"; + SalesHeaderInvoice: Record "Sales Header"; + SalesInvoiceHeader: Record "Sales Invoice Header"; + SalesCrMemoHeader: Record "Sales Cr.Memo Header"; + CreditMemoHeader: Record "Sales Header"; + SalesShipmentLine: Record "Sales Shipment Line"; + SalesGetShipment: Codeunit "Sales-Get Shipment"; + CopyDocMgt: Codeunit "Copy Document Mgt."; + OrderQty: array[2] of Decimal; + begin + // [SCENARIO 646375] Negative Shipped and Invoiced quantities no longer appear on Sales Order lines + // when the same item is shipped from several orders, invoiced together, and a Credit Memo is created + // via Copy Document from that Posted Invoice. + Initialize(); + + // [GIVEN] An item with stock. + CreateItemWithPrice(Item, LibraryRandom.RandDecInRange(10, 50, 2)); + PostItemJournalPositiveAdj(Item."No.", '', 100); + + // [GIVEN] Two Sales Orders for the same customer, each with a line for the same item but different quantities. + LibrarySales.CreateCustomer(Customer); + OrderQty[1] := LibraryRandom.RandIntInRange(11, 20); + OrderQty[2] := LibraryRandom.RandIntInRange(5, 10); + CreateAndShipSalesOrderWithItem(SalesHeaderOrder[1], SalesLineOrder[1], Customer."No.", Item."No.", OrderQty[1]); + CreateAndShipSalesOrderWithItem(SalesHeaderOrder[2], SalesLineOrder[2], Customer."No.", Item."No.", OrderQty[2]); + + // [GIVEN] A single Sales Invoice created via Get Shipment Lines from both shipments, then posted. + LibrarySales.CreateSalesHeader(SalesHeaderInvoice, "Sales Document Type"::Invoice, Customer."No."); + SalesShipmentLine.SetFilter("Order No.", '%1|%2', SalesHeaderOrder[1]."No.", SalesHeaderOrder[2]."No."); + SalesGetShipment.SetSalesHeader(SalesHeaderInvoice); + SalesGetShipment.CreateInvLines(SalesShipmentLine); + SalesInvoiceHeader.Get(LibrarySales.PostSalesDocument(SalesHeaderInvoice, true, true)); + + // [GIVEN] A Credit Memo created via Copy Document from the Posted Invoice. + CreditMemoHeader.Init(); + CreditMemoHeader.Validate("Document Type", CreditMemoHeader."Document Type"::"Credit Memo"); + CreditMemoHeader.Insert(true); + CopyDocMgt.SetProperties(true, false, false, false, false, false, false); + CopyDocMgt.CopySalesDoc("Sales Document Type From"::"Posted Invoice", SalesInvoiceHeader."No.", CreditMemoHeader); + + // [WHEN] Post the Credit Memo and update the linked Sales Order lines (as the Sales Credit Memo page does after posting). + SalesCrMemoHeader.Get(LibrarySales.PostSalesDocument(CreditMemoHeader, true, true)); + CreditMemoHeader.UpdateSalesOrderLineIfExist(); + + // [THEN] Each Sales Order line is reverted to its own shipped/invoiced quantity, with no negative values. + SalesLineOrder[1].Find(); + Assert.AreEqual( + 0, SalesLineOrder[1]."Quantity Shipped", + StrSubstNo(SalesOrderLineReducedErr, SalesLineOrder[1].FieldCaption("Quantity Shipped"))); + Assert.AreEqual( + 0, SalesLineOrder[1]."Quantity Invoiced", + StrSubstNo(SalesOrderLineReducedErr, SalesLineOrder[1].FieldCaption("Quantity Invoiced"))); + + SalesLineOrder[2].Find(); + Assert.AreEqual( + 0, SalesLineOrder[2]."Quantity Shipped", + StrSubstNo(SalesOrderLineReducedErr, SalesLineOrder[2].FieldCaption("Quantity Shipped"))); + Assert.AreEqual( + 0, SalesLineOrder[2]."Quantity Invoiced", + StrSubstNo(SalesOrderLineReducedErr, SalesLineOrder[2].FieldCaption("Quantity Invoiced"))); + end; + + local procedure CreateAndShipSalesOrderWithItem(var SalesHeader: Record "Sales Header"; var SalesLine: Record "Sales Line"; CustomerNo: Code[20]; ItemNo: Code[20]; Qty: Decimal) + begin + LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::Order, CustomerNo); + LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, ItemNo, Qty); + LibrarySales.PostSalesDocument(SalesHeader, true, false); + end; + local procedure Initialize() var LibraryERMCountryData: Codeunit "Library - ERM Country Data";