Skip to content

Commit 10199df

Browse files
authored
Bug 620427: [Subcontracting] God object pattern in Subc. Factbox Mgmt. (#7749)
<!-- Thank you for submitting a Pull Request. If you're new to contributing to BCApps please read our pull request guideline below * https://github.com/microsoft/BCApps/Contributing.md --> #### Summary <!-- Provide a general summary of your changes --> The "Subc. Factbox Mgmt." codeunit had procedures related to 4 different factboxes in Subcontracting. This PR is splits the codeunit into 4 codeunits and updates the referances #### Work Item(s) <!-- Add the issue number here after the #. The issue needs to be open and approved. Submitting PRs with no linked issues or unapproved issues is highly discouraged. --> Fixes [AB#620427](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/620427)
1 parent 0172c4d commit 10199df

18 files changed

Lines changed: 1249 additions & 1020 deletions

src/Apps/W1/Subcontracting/App/src/Permissions/SubcPermissionset.PermissionSet.al

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ permissionset 99001500 "Subc. Permissionset"
2323
codeunit "Subc. Create Prod. Rtng. Ext." = X,
2424
codeunit "Subc. CrPurchSubcon(Yes/No)" = X,
2525
codeunit "Subc. DirectTransferLine Ext." = X,
26-
codeunit "Subc. Factbox Mgmt." = X,
26+
codeunit "Subc. Comp. Factbox Mgmt." = X,
27+
codeunit "Subc. ProdO. Factbox Mgmt." = X,
28+
codeunit "Subc. Purch. Factbox Mgmt." = X,
29+
codeunit "Subc. Routing Factbox Mgmt." = X,
2730
codeunit "Subc. ItemChargeAssPurchExt" = X,
2831
codeunit "Subc. Item Extension" = X,
2932
codeunit "Subc. ItemJnlCheckExt" = X,

src/Apps/W1/Subcontracting/App/src/Permissions/SubcontractObjs.PermissionSet.al

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ permissionset 99001501 "Subcontract. - Objs"
2626
codeunit "Subc. Create Prod. Rtng. Ext." = X,
2727
codeunit "Subc. CrPurchSubcon(Yes/No)" = X,
2828
codeunit "Subc. DirectTransferLine Ext." = X,
29-
codeunit "Subc. Factbox Mgmt." = X,
29+
codeunit "Subc. Comp. Factbox Mgmt." = X,
30+
codeunit "Subc. ProdO. Factbox Mgmt." = X,
31+
codeunit "Subc. Purch. Factbox Mgmt." = X,
32+
codeunit "Subc. Routing Factbox Mgmt." = X,
3033
codeunit "Subc. ItemChargeAssPurchExt" = X,
3134
codeunit "Subc. Item Extension" = X,
3235
codeunit "Subc. ItemJnlCheckExt" = X,
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// ------------------------------------------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License. See License.txt in the project root for license information.
4+
// ------------------------------------------------------------------------------------------------
5+
namespace Microsoft.Manufacturing.Subcontracting;
6+
7+
using Microsoft.Inventory.Ledger;
8+
using Microsoft.Manufacturing.Document;
9+
using Microsoft.Purchases.Document;
10+
11+
codeunit 99001562 "Subc. Comp. Factbox Mgmt."
12+
{
13+
/// <summary>
14+
/// Returns the total consumption quantity posted for the given production order component via its linked routing operation.
15+
/// </summary>
16+
/// <param name="ProdOrderComponent">The production order component to sum consumption entries for.</param>
17+
/// <returns>The absolute sum of consumption item ledger entry quantities for the component.</returns>
18+
procedure GetConsumptionQtyFromProdOrderComponent(ProdOrderComponent: Record "Prod. Order Component"): Decimal
19+
var
20+
ItemLedgerEntry: Record "Item Ledger Entry";
21+
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
22+
begin
23+
GetProdOrderRtngLineFromProdOrderComp(ProdOrderRoutingLine, ProdOrderComponent);
24+
25+
ItemLedgerEntry.SetCurrentKey(ItemLedgerEntry."Order Type", ItemLedgerEntry."Order No.", ItemLedgerEntry."Order Line No.", ItemLedgerEntry."Entry Type", ItemLedgerEntry."Prod. Order Comp. Line No.");
26+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Order Type", ItemLedgerEntry."Order Type"::Production);
27+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Order No.", ProdOrderComponent."Prod. Order No.");
28+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Order Line No.", ProdOrderComponent."Prod. Order Line No.");
29+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Entry Type", ItemLedgerEntry."Entry Type"::Consumption);
30+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Prod. Order Comp. Line No.", ProdOrderComponent."Line No.");
31+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Operation No.", ProdOrderRoutingLine."Operation No.");
32+
ItemLedgerEntry.CalcSums(ItemLedgerEntry.Quantity);
33+
34+
exit(Abs(ItemLedgerEntry.Quantity));
35+
end;
36+
37+
/// <summary>
38+
/// Opens the Item Ledger Entries page filtered to consumption entries for the given production order component.
39+
/// </summary>
40+
/// <param name="ProdOrderComponent">The production order component to show consumption entries for.</param>
41+
procedure ShowConsumptionQtyFromProdOrderComponent(ProdOrderComponent: Record "Prod. Order Component")
42+
var
43+
ItemLedgerEntry: Record "Item Ledger Entry";
44+
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
45+
begin
46+
GetProdOrderRtngLineFromProdOrderComp(ProdOrderRoutingLine, ProdOrderComponent);
47+
48+
ItemLedgerEntry.SetCurrentKey(ItemLedgerEntry."Order Type", ItemLedgerEntry."Order No.", ItemLedgerEntry."Order Line No.", ItemLedgerEntry."Entry Type", ItemLedgerEntry."Prod. Order Comp. Line No.");
49+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Order Type", ItemLedgerEntry."Order Type"::Production);
50+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Order No.", ProdOrderComponent."Prod. Order No.");
51+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Order Line No.", ProdOrderComponent."Prod. Order Line No.");
52+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Entry Type", ItemLedgerEntry."Entry Type"::Consumption);
53+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Prod. Order Comp. Line No.", ProdOrderComponent."Line No.");
54+
ItemLedgerEntry.SetRange(ItemLedgerEntry."Operation No.", ProdOrderRoutingLine."Operation No.");
55+
Page.Run(Page::"Item Ledger Entries", ItemLedgerEntry);
56+
end;
57+
58+
/// <summary>
59+
/// Returns the total outstanding base quantity on subcontracting purchase lines for the given production order component.
60+
/// </summary>
61+
/// <param name="ProdOrderComponent">The production order component to calculate outstanding quantity for.</param>
62+
/// <returns>The sum of Outstanding Qty. (Base) on matching purchase lines, or 0 if not a purchase subcontracting component.</returns>
63+
procedure GetPurchOrderOutstandingQtyBaseFromProdOrderComp(ProdOrderComponent: Record "Prod. Order Component"): Decimal
64+
var
65+
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
66+
PurchaseLine: Record "Purchase Line";
67+
begin
68+
if ProdOrderComponent."Routing Link Code" = '' then
69+
exit(0);
70+
if ProdOrderComponent."Subcontracting Type" <> ProdOrderComponent."Subcontracting Type"::Purchase then
71+
exit(0);
72+
73+
GetProdOrderRtngLineFromProdOrderComp(ProdOrderRoutingLine, ProdOrderComponent);
74+
75+
PurchaseLine.SetRange(PurchaseLine."Document Type", PurchaseLine."Document Type"::Order);
76+
PurchaseLine.SetRange(PurchaseLine."Subc. Prod. Order No.", ProdOrderRoutingLine."Prod. Order No.");
77+
PurchaseLine.SetRange(PurchaseLine."Subc. Prod. Order Line No.", ProdOrderRoutingLine."Routing Reference No.");
78+
PurchaseLine.SetRange(PurchaseLine."Subc. Routing No.", ProdOrderRoutingLine."Routing No.");
79+
PurchaseLine.SetRange(PurchaseLine."Subc. Operation No.", ProdOrderRoutingLine."Operation No.");
80+
PurchaseLine.SetRange(PurchaseLine."Subc. Work Center No.", ProdOrderRoutingLine."Work Center No.");
81+
PurchaseLine.SetRange(PurchaseLine."No.", ProdOrderComponent."Item No.");
82+
PurchaseLine.CalcSums(PurchaseLine."Outstanding Qty. (Base)");
83+
exit(PurchaseLine."Outstanding Qty. (Base)");
84+
end;
85+
86+
/// <summary>
87+
/// Opens the Purchase Lines page filtered to outstanding subcontracting purchase lines for the given production order component.
88+
/// </summary>
89+
/// <param name="ProdOrderComponent">The production order component to filter purchase lines by.</param>
90+
procedure ShowPurchOrderOutstandingQtyBaseFromProdOrderComp(ProdOrderComponent: Record "Prod. Order Component")
91+
var
92+
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
93+
PurchaseLine: Record "Purchase Line";
94+
begin
95+
if ProdOrderComponent."Routing Link Code" = '' then
96+
exit;
97+
if ProdOrderComponent."Subcontracting Type" <> ProdOrderComponent."Subcontracting Type"::Purchase then
98+
exit;
99+
100+
GetProdOrderRtngLineFromProdOrderComp(ProdOrderRoutingLine, ProdOrderComponent);
101+
102+
PurchaseLine.SetRange(PurchaseLine."Document Type", PurchaseLine."Document Type"::Order);
103+
PurchaseLine.SetRange(PurchaseLine."Subc. Prod. Order No.", ProdOrderRoutingLine."Prod. Order No.");
104+
PurchaseLine.SetRange(PurchaseLine."Subc. Prod. Order Line No.", ProdOrderRoutingLine."Routing Reference No.");
105+
PurchaseLine.SetRange(PurchaseLine."Subc. Routing No.", ProdOrderRoutingLine."Routing No.");
106+
PurchaseLine.SetRange(PurchaseLine."Subc. Operation No.", ProdOrderRoutingLine."Operation No.");
107+
PurchaseLine.SetRange(PurchaseLine."Subc. Work Center No.", ProdOrderRoutingLine."Work Center No.");
108+
PurchaseLine.SetRange(PurchaseLine."No.", ProdOrderComponent."Item No.");
109+
Page.Run(Page::"Purchase Lines", PurchaseLine);
110+
end;
111+
112+
/// <summary>
113+
/// Returns the total received base quantity on subcontracting purchase lines for the given production order component.
114+
/// </summary>
115+
/// <param name="ProdOrderComponent">The production order component to calculate received quantity for.</param>
116+
/// <returns>The sum of Qty. Received (Base) on matching purchase lines, or 0 if not a purchase subcontracting component.</returns>
117+
procedure GetPurchOrderQtyReceivedBaseFromProdOrderComp(ProdOrderComponent: Record "Prod. Order Component"): Decimal
118+
var
119+
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
120+
PurchaseLine: Record "Purchase Line";
121+
begin
122+
if ProdOrderComponent."Routing Link Code" = '' then
123+
exit(0);
124+
if ProdOrderComponent."Subcontracting Type" <> ProdOrderComponent."Subcontracting Type"::Purchase then
125+
exit(0);
126+
127+
GetProdOrderRtngLineFromProdOrderComp(ProdOrderRoutingLine, ProdOrderComponent);
128+
129+
PurchaseLine.SetRange(PurchaseLine."Document Type", PurchaseLine."Document Type"::Order);
130+
PurchaseLine.SetRange(PurchaseLine."Subc. Prod. Order No.", ProdOrderRoutingLine."Prod. Order No.");
131+
PurchaseLine.SetRange(PurchaseLine."Subc. Prod. Order Line No.", ProdOrderRoutingLine."Routing Reference No.");
132+
PurchaseLine.SetRange(PurchaseLine."Subc. Routing No.", ProdOrderRoutingLine."Routing No.");
133+
PurchaseLine.SetRange(PurchaseLine."Subc. Operation No.", ProdOrderRoutingLine."Operation No.");
134+
PurchaseLine.SetRange(PurchaseLine."Subc. Work Center No.", ProdOrderRoutingLine."Work Center No.");
135+
PurchaseLine.SetRange(PurchaseLine."No.", ProdOrderComponent."Item No.");
136+
PurchaseLine.CalcSums(PurchaseLine."Qty. Received (Base)");
137+
exit(PurchaseLine."Qty. Received (Base)");
138+
end;
139+
140+
/// <summary>
141+
/// Opens the Purchase Lines page filtered to subcontracting purchase lines for the given production order component to show received quantities.
142+
/// </summary>
143+
/// <param name="ProdOrderComponent">The production order component to filter purchase lines by.</param>
144+
procedure ShowPurchOrderQtyReceivedBaseFromProdOrderComp(ProdOrderComponent: Record "Prod. Order Component")
145+
var
146+
ProdOrderRoutingLine: Record "Prod. Order Routing Line";
147+
PurchaseLine: Record "Purchase Line";
148+
begin
149+
if ProdOrderComponent."Routing Link Code" = '' then
150+
exit;
151+
if ProdOrderComponent."Subcontracting Type" <> ProdOrderComponent."Subcontracting Type"::Purchase then
152+
exit;
153+
GetProdOrderRtngLineFromProdOrderComp(ProdOrderRoutingLine, ProdOrderComponent);
154+
155+
PurchaseLine.SetRange(PurchaseLine."Document Type", PurchaseLine."Document Type"::Order);
156+
PurchaseLine.SetRange(PurchaseLine."Subc. Prod. Order No.", ProdOrderRoutingLine."Prod. Order No.");
157+
PurchaseLine.SetRange(PurchaseLine."Subc. Prod. Order Line No.", ProdOrderRoutingLine."Routing Reference No.");
158+
PurchaseLine.SetRange(PurchaseLine."Subc. Routing No.", ProdOrderRoutingLine."Routing No.");
159+
PurchaseLine.SetRange(PurchaseLine."Subc. Operation No.", ProdOrderRoutingLine."Operation No.");
160+
PurchaseLine.SetRange(PurchaseLine."Subc. Work Center No.", ProdOrderRoutingLine."Work Center No.");
161+
PurchaseLine.SetRange(PurchaseLine."No.", ProdOrderComponent."Item No.");
162+
Page.Run(Page::"Purchase Lines", PurchaseLine);
163+
end;
164+
165+
local procedure GetProdOrderRtngLineFromProdOrderComp(var ProdOrderRoutingLine: Record "Prod. Order Routing Line"; ProdOrderComponent: Record "Prod. Order Component")
166+
var
167+
ProdOrderLine: Record "Prod. Order Line";
168+
begin
169+
if not ProdOrderLine.Get(ProdOrderComponent.Status, ProdOrderComponent."Prod. Order No.", ProdOrderComponent."Prod. Order Line No.") then
170+
exit;
171+
172+
ProdOrderRoutingLine.SetRange(Status, ProdOrderLine.Status);
173+
ProdOrderRoutingLine.SetRange("Prod. Order No.", ProdOrderLine."Prod. Order No.");
174+
ProdOrderRoutingLine.SetRange("Routing Reference No.", ProdOrderLine."Routing Reference No.");
175+
ProdOrderRoutingLine.SetRange("Routing Link Code", ProdOrderComponent."Routing Link Code");
176+
if ProdOrderRoutingLine.IsEmpty() then
177+
exit;
178+
179+
ProdOrderRoutingLine.FindFirst();
180+
end;
181+
}

0 commit comments

Comments
 (0)