Skip to content

Commit 3b13063

Browse files
committed
Update from DYCE Version 2025.8.0.0
1 parent 7bbf9cc commit 3b13063

File tree

36 files changed

+992
-237
lines changed

36 files changed

+992
-237
lines changed

src/Apps/W1/Subscription Billing/App/APIs/Pages/SalesServiceCommitmentsAPI.Page.al

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ page 8019 "Sales Service Commitments API"
126126
field(process; Rec.Process)
127127
{
128128
}
129+
field(systemCreatedAt; Rec.SystemCreatedAt)
130+
{
131+
}
132+
field(lastModifiedDateTime; Rec.SystemModifiedAt)
133+
{
134+
}
129135
}
130136
}
131137
}

src/Apps/W1/Subscription Billing/App/APIs/Pages/ServiceCommitmentsAPI.Page.al

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,12 @@ page 8018 "Service Commitments API"
178178
{
179179
}
180180
}
181+
field(systemCreatedAt; Rec.SystemCreatedAt)
182+
{
183+
}
184+
field(lastModifiedDateTime; Rec.SystemModifiedAt)
185+
{
186+
}
181187
}
182188
}
183189
}

src/Apps/W1/Subscription Billing/App/APIs/Pages/ServiceObjectAPI.Page.al

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ page 8020 "Service Object API"
187187
{
188188
}
189189
}
190+
field(systemCreatedAt; Rec.SystemCreatedAt)
191+
{
192+
}
193+
field(lastModifiedDateTime; Rec.SystemModifiedAt)
194+
{
195+
}
190196
}
191197
}
192198
}

src/Apps/W1/Subscription Billing/App/Base/Codeunits/SubBillingInstallation.Codeunit.al

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ codeunit 8051 "Sub. Billing Installation"
1717
UpgradeTag.SetAllUpgradeTags();
1818
end;
1919

20-
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Company-Initialize", 'OnCompanyInitialize', '', false, false)]
20+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Company-Initialize", OnCompanyInitialize, '', false, false)]
2121
local procedure OnCompanyInitialize()
2222
var
2323
ServiceContractSetup: Record "Subscription Contract Setup";

src/Apps/W1/Subscription Billing/App/Base/Codeunits/UpgradeSubscriptionBilling.Codeunit.al

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ using System.Upgrade;
44
#if not CLEANSCHEMA29
55
using Microsoft.Finance.GeneralLedger.Setup;
66
#endif
7+
using Microsoft.Sales.Document;
78

89
codeunit 8032 "Upgrade Subscription Billing"
910
{
@@ -25,6 +26,8 @@ codeunit 8032 "Upgrade Subscription Billing"
2526
MoveCustContrDimensionToServiceContractSetup();
2627
#endif
2728
UpdateCreateContractDeferralsFlag();
29+
DeleteSalesSubscriptionLinesConnectedToDeletedQuote();
30+
RemoveDocumentNoFromBillingLines();
2831
end;
2932

3033
#if not CLEANSCHEMA29
@@ -257,8 +260,68 @@ codeunit 8032 "Upgrade Subscription Billing"
257260
exit('MS-XXXXXX-UpdateCreateContractDeferralsFlag-20250321');
258261
end;
259262

263+
local procedure DeleteSalesSubscriptionLinesConnectedToDeletedQuote()
264+
var
265+
SalesSubscriptionLine: Record "Sales Subscription Line";
266+
SalesHeader: Record "Sales Header";
267+
UpgradeTag: Codeunit "Upgrade Tag";
268+
begin
269+
if UpgradeTag.HasUpgradeTag(DeleteSalesSubscriptionLinesConnectedToDeletedQuoteTag()) then
270+
exit;
271+
272+
SalesSubscriptionLine.SetRange("Document Type", "Sales Document Type"::Quote);
273+
if SalesSubscriptionLine.FindSet() then
274+
repeat
275+
if not SalesHeader.Get(SalesHeader."Document Type"::Quote, SalesSubscriptionLine."Document No.") then
276+
SalesSubscriptionLine.Delete(false);
277+
until SalesSubscriptionLine.Next() = 0;
278+
279+
UpgradeTag.SetUpgradeTag(DeleteSalesSubscriptionLinesConnectedToDeletedQuoteTag());
280+
end;
281+
282+
local procedure DeleteSalesSubscriptionLinesConnectedToDeletedQuoteTag(): Text[250]
283+
begin
284+
exit('MS-XXXXXX-DeleteSalesSubscriptionLinesConnectedToDeletedQuoteTag-20250819');
285+
end;
286+
287+
local procedure RemoveDocumentNoFromBillingLines()
288+
var
289+
BillingLine: Record "Billing Line";
290+
SalesHeader: Record "Sales Header";
291+
UpgradeTag: Codeunit "Upgrade Tag";
292+
begin
293+
if UpgradeTag.HasUpgradeTag(RemoveDocumentNoFromBillingLinesTag()) then
294+
exit;
295+
296+
BillingLine.SetRange(Partner, BillingLine.Partner::Customer);
297+
BillingLine.SetFilter("Document No.", '<>%1', '');
298+
if BillingLine.FindSet() then
299+
repeat
300+
case BillingLine."Document Type" of
301+
BillingLine."Document Type"::Invoice:
302+
if not SalesHeader.Get(SalesHeader."Document Type"::Invoice, BillingLine."Document No.") then begin
303+
BillingLine."Document Type" := BillingLine."Document Type"::None;
304+
BillingLine."Document No." := '';
305+
BillingLine.Modify(false);
306+
end;
307+
BillingLine."Document Type"::"Credit Memo":
308+
if not SalesHeader.Get(SalesHeader."Document Type"::"Credit Memo", BillingLine."Document No.") then begin
309+
BillingLine."Document Type" := BillingLine."Document Type"::None;
310+
BillingLine."Document No." := '';
311+
BillingLine.Modify(false);
312+
end;
313+
end;
314+
until BillingLine.Next() = 0;
315+
316+
UpgradeTag.SetUpgradeTag(RemoveDocumentNoFromBillingLinesTag());
317+
end;
318+
319+
local procedure RemoveDocumentNoFromBillingLinesTag(): Text[250]
320+
begin
321+
exit('MS-XXXXXX-RemoveDocumentNoFromBillingLines-20250819');
322+
end;
260323

261-
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", 'OnGetPerCompanyUpgradeTags', '', false, false)]
324+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", OnGetPerCompanyUpgradeTags, '', false, false)]
262325
local procedure RegisterPerCompanyTags(var PerCompanyUpgradeTags: List of [Code[250]])
263326
begin
264327
#if not CLEANSCHEMA29

src/Apps/W1/Subscription Billing/App/Billing/Codeunits/BillingCorrection.Codeunit.al

Lines changed: 104 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ namespace Microsoft.SubscriptionBilling;
33
using Microsoft.Utilities;
44
using Microsoft.Sales.Document;
55
using Microsoft.Purchases.Document;
6+
using Microsoft.Purchases.History;
7+
using Microsoft.Sales.History;
68

79
codeunit 8061 "Billing Correction"
810
{
@@ -13,56 +15,6 @@ codeunit 8061 "Billing Correction"
1315
RelatedDocumentLineExistErr: Label 'The %1 %2 already exists for the Subscription Line. Please post or delete this %1 first.', Comment = '%1=Document Type, %2=Document No.';
1416
CopyingErr: Label 'Copying documents with a link to a contract is not allowed. To create contract invoices, please use the "Recurring Billing" page. For cancelling a contract invoice, please use the "Create Corrective Credit Memo" function in the posted invoice.';
1517

16-
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnBeforeUpdateSalesLine, '', false, false)]
17-
local procedure TrasnferContractFieldsBeforeUpdateSalesLine(var ToSalesLine: Record "Sales Line"; var FromSalesLine: Record "Sales Line"; FromSalesDocType: Option; var FromSalesHeader: Record "Sales Header")
18-
begin
19-
if not FromSalesHeader."Recurring Billing" then
20-
exit;
21-
if FromSalesDocType <> Enum::"Sales Document Type From"::"Posted Invoice".AsInteger() then
22-
Error(CopyingErr);
23-
if ToSalesLine."Document Type" <> Enum::"Sales Document Type"::"Credit Memo" then
24-
Error(CopyingErr);
25-
ToSalesLine."Recurring Billing from" := FromSalesLine."Recurring Billing from";
26-
ToSalesLine."Recurring Billing to" := FromSalesLine."Recurring Billing to";
27-
ToSalesLine."Discount" := FromSalesLine."Discount";
28-
end;
29-
30-
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnAfterInsertToSalesLine, '', false, false)]
31-
local procedure CreateBillingLineFromBillingLineArchiveAfterInsertToSalesLine(var ToSalesLine: Record "Sales Line"; FromSalesLine: Record "Sales Line"; DocLineNo: Integer; FromSalesHeader: Record "Sales Header")
32-
var
33-
ServiceCommitment: Record "Subscription Line";
34-
BillingLine: Record "Billing Line";
35-
BillingLineArchive: Record "Billing Line Archive";
36-
IsHandled: Boolean;
37-
begin
38-
OnBeforeCreateBillingLineFromBillingLineArchiveAfterInsertToSalesLine(ToSalesLine, IsHandled);
39-
if IsHandled then
40-
exit;
41-
FilterBillingLineArchiveOnSalesLineOrPurchLine(ToSalesLine, BillingLineArchive, FromSalesHeader."No.", DocLineNo);
42-
if BillingLineArchive.IsEmpty() then
43-
exit;
44-
45-
ToSalesLine.TestField("Recurring Billing from");
46-
ToSalesLine.TestField("Recurring Billing to");
47-
48-
if BillingLineArchive.FindFirst() then begin
49-
ServiceCommitment.SetRange("Subscription Contract No.", BillingLineArchive."Subscription Contract No.");
50-
ServiceCommitment.SetRange("Subscription Contract Line No.", BillingLineArchive."Subscription Contract Line No.");
51-
ServiceCommitment.FindFirst();
52-
if ServiceCommitment."Next Billing Date" - 1 > ToSalesLine."Recurring Billing to" then
53-
Error(NewerInvoiceExistErr, ServiceCommitment."Next Billing Date");
54-
end;
55-
56-
BillingLine.SetRange("Document Type", Enum::"Rec. Billing Document Type"::Invoice, Enum::"Rec. Billing Document Type"::"Credit Memo");
57-
BillingLine.SetFilter("Document No.", '<>%1', ToSalesLine."Document No.");
58-
BillingLine.SetRange("Subscription Contract No.", BillingLineArchive."Subscription Contract No.");
59-
BillingLine.SetRange("Subscription Contract Line No.", BillingLineArchive."Subscription Contract Line No.");
60-
61-
if BillingLine.FindFirst() then
62-
Error(RelatedDocumentLineExistErr, BillingLine."Document Type", BillingLine."Document No.");
63-
CreateBillingLineFromBillingLineArchive(ToSalesLine, ServiceCommitment, FromSalesHeader."No.", DocLineNo);
64-
end;
65-
6618
local procedure CreateBillingLineFromBillingLineArchive(RecVariant: Variant; var ServiceCommitment: Record "Subscription Line"; FromDocumentNo: Code[20]; DocLineNo: Integer)
6719
var
6820
BillingLine: Record "Billing Line";
@@ -176,17 +128,11 @@ codeunit 8061 "Billing Correction"
176128
BillingLineArchive.SetRange("Billing to", RRef.Field(8053).Value, RRef.Field(8054).Value);
177129
end;
178130

179-
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnBeforeUpdatePurchLine, '', false, false)]
180-
local procedure TrasnferContractFieldsBeforeUpdatePurchaseLine(var ToPurchLine: Record "Purchase Line"; var FromPurchLine: Record "Purchase Line"; var FromPurchHeader: Record "Purchase Header"; FromPurchDocType: Option)
131+
local procedure GetAndCheckServiceCommitmentIfNewerInvoiceExists(var ServiceCommitment: Record "Subscription Line"; SubscriptionLineEntryNo: Integer; RecurringBillingToDate: Date)
181132
begin
182-
if not FromPurchHeader."Recurring Billing" then
183-
exit;
184-
if FromPurchDocType <> Enum::"Purchase Document Type From"::"Posted Invoice".AsInteger() then
185-
Error(CopyingErr);
186-
if ToPurchLine."Document Type" <> Enum::"Purchase Document Type"::"Credit Memo" then
187-
Error(CopyingErr);
188-
ToPurchLine."Recurring Billing from" := FromPurchLine."Recurring Billing from";
189-
ToPurchLine."Recurring Billing to" := FromPurchLine."Recurring Billing to";
133+
ServiceCommitment.Get(SubscriptionLineEntryNo);
134+
if ServiceCommitment."Next Billing Date" - 1 > RecurringBillingToDate then
135+
Error(NewerInvoiceExistErr, ServiceCommitment."Next Billing Date");
190136
end;
191137

192138
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnAfterInsertToPurchLine, '', false, false)]
@@ -201,13 +147,11 @@ codeunit 8061 "Billing Correction"
201147
exit;
202148
ToPurchLine.TestField("Recurring Billing from");
203149
ToPurchLine.TestField("Recurring Billing to");
204-
if BillingLineArchive.FindFirst() then begin
205-
ServiceCommitment.SetRange("Subscription Contract No.", BillingLineArchive."Subscription Contract No.");
206-
ServiceCommitment.SetRange("Subscription Contract Line No.", BillingLineArchive."Subscription Contract Line No.");
207-
ServiceCommitment.FindFirst();
208-
if ServiceCommitment."Next Billing Date" - 1 > ToPurchLine."Recurring Billing to" then
209-
Error(NewerInvoiceExistErr, ServiceCommitment."Next Billing Date");
210-
end;
150+
if BillingLineArchive.FindFirst() then
151+
GetAndCheckServiceCommitmentIfNewerInvoiceExists(ServiceCommitment, BillingLineArchive."Subscription Line Entry No.", ToPurchLine."Recurring Billing to");
152+
153+
if (BillingLineArchive."Subscription Contract No." = '') or (BillingLineArchive."Subscription Contract Line No." = 0) then
154+
exit;
211155

212156
BillingLine.SetRange("Document Type", Enum::"Rec. Billing Document Type"::Invoice, Enum::"Rec. Billing Document Type"::"Credit Memo");
213157
BillingLine.SetFilter("Document No.", '<>%1', ToPurchLine."Document No.");
@@ -218,6 +162,99 @@ codeunit 8061 "Billing Correction"
218162
CreateBillingLineFromBillingLineArchive(ToPurchLine, ServiceCommitment, FromPurchaseHeader."No.", DocLineNo);
219163
end;
220164

165+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnAfterInsertToSalesLine, '', false, false)]
166+
local procedure CreateBillingLineFromBillingLineArchiveAfterInsertToSalesLine(var ToSalesLine: Record "Sales Line"; DocLineNo: Integer; FromSalesHeader: Record "Sales Header")
167+
var
168+
SubscriptionLine: Record "Subscription Line";
169+
BillingLine: Record "Billing Line";
170+
BillingLineArchive: Record "Billing Line Archive";
171+
IsHandled: Boolean;
172+
begin
173+
OnBeforeCreateBillingLineFromBillingLineArchiveAfterInsertToSalesLine(ToSalesLine, IsHandled);
174+
if IsHandled then
175+
exit;
176+
FilterBillingLineArchiveOnSalesLineOrPurchLine(ToSalesLine, BillingLineArchive, FromSalesHeader."No.", DocLineNo);
177+
if BillingLineArchive.IsEmpty() then
178+
exit;
179+
180+
ToSalesLine.TestField("Recurring Billing from");
181+
ToSalesLine.TestField("Recurring Billing to");
182+
183+
if BillingLineArchive.FindFirst() then
184+
GetAndCheckServiceCommitmentIfNewerInvoiceExists(SubscriptionLine, BillingLineArchive."Subscription Line Entry No.", ToSalesLine."Recurring Billing to");
185+
186+
if (BillingLineArchive."Subscription Contract No." = '') or (BillingLineArchive."Subscription Contract Line No." = 0) then
187+
exit;
188+
189+
BillingLine.SetRange("Document Type", Enum::"Rec. Billing Document Type"::Invoice, Enum::"Rec. Billing Document Type"::"Credit Memo");
190+
BillingLine.SetFilter("Document No.", '<>%1', ToSalesLine."Document No.");
191+
BillingLine.SetRange("Subscription Contract No.", BillingLineArchive."Subscription Contract No.");
192+
BillingLine.SetRange("Subscription Contract Line No.", BillingLineArchive."Subscription Contract Line No.");
193+
194+
if BillingLine.FindFirst() then
195+
Error(RelatedDocumentLineExistErr, BillingLine."Document Type", BillingLine."Document No.");
196+
CreateBillingLineFromBillingLineArchive(ToSalesLine, SubscriptionLine, FromSalesHeader."No.", DocLineNo);
197+
end;
198+
199+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnCopyPurchInvLinesToDocOnAfterTransferFields, '', false, false)]
200+
local procedure FindSubscriptionLineFromBillingLineArchiveForPurchase(var FromPurchaseLine: Record "Purchase Line"; var FromPurchInvLine: Record "Purch. Inv. Line")
201+
var
202+
BillingLineArchive: Record "Billing Line Archive";
203+
SubscriptionLine: Record "Subscription Line";
204+
begin
205+
if FromPurchInvLine."Subscription Contract No." = '' then
206+
exit;
207+
if FromPurchInvLine."Subscription Contract Line No." = 0 then
208+
exit;
209+
BillingLineArchive.FilterBillingLineArchiveOnDocument("Rec. Billing Document Type"::Invoice, FromPurchInvLine."Document No.");
210+
BillingLineArchive.FilterBillingLineArchiveOnContractLine("Service Partner"::Vendor, FromPurchInvLine."Subscription Contract No.", FromPurchInvLine."Subscription Contract Line No.");
211+
if not BillingLineArchive.FindFirst() then
212+
exit;
213+
if not SubscriptionLine.Get(BillingLineArchive."Subscription Line Entry No.") then
214+
exit;
215+
end;
216+
217+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnBeforeCopySalesInvLinesToBuffer, '', false, false)]
218+
local procedure FindSubscriptionLineFromBillingLineArchiveForSales(var FromSalesLine: Record "Sales Line"; var FromSalesInvLine: Record "Sales Invoice Line")
219+
var
220+
BillingLineArchive: Record "Billing Line Archive";
221+
SubscriptionLine: Record "Subscription Line";
222+
begin
223+
if FromSalesInvLine."Subscription Contract No." = '' then
224+
exit;
225+
if FromSalesInvLine."Subscription Contract Line No." = 0 then
226+
exit;
227+
BillingLineArchive.FilterBillingLineArchiveOnDocument("Rec. Billing Document Type"::Invoice, FromSalesInvLine."Document No.");
228+
BillingLineArchive.FilterBillingLineArchiveOnContractLine("Service Partner"::Customer, FromSalesInvLine."Subscription Contract No.", FromSalesInvLine."Subscription Contract Line No.");
229+
if not BillingLineArchive.FindFirst() then
230+
exit;
231+
if not SubscriptionLine.Get(BillingLineArchive."Subscription Line Entry No.") then
232+
exit;
233+
end;
234+
235+
236+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnBeforeUpdatePurchLine, '', false, false)]
237+
local procedure TransferContractFieldsBeforeUpdatePurchaseLine(var ToPurchLine: Record "Purchase Line"; var FromPurchHeader: Record "Purchase Header"; FromPurchDocType: Option)
238+
begin
239+
if not FromPurchHeader."Recurring Billing" then
240+
exit;
241+
if FromPurchDocType <> Enum::"Purchase Document Type From"::"Posted Invoice".AsInteger() then
242+
Error(CopyingErr);
243+
if ToPurchLine."Document Type" <> Enum::"Purchase Document Type"::"Credit Memo" then
244+
Error(CopyingErr);
245+
end;
246+
247+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Copy Document Mgt.", OnBeforeUpdateSalesLine, '', false, false)]
248+
local procedure TransferContractFieldsBeforeUpdateSalesLine(var ToSalesLine: Record "Sales Line"; FromSalesDocType: Option; var FromSalesHeader: Record "Sales Header")
249+
begin
250+
if not FromSalesHeader."Recurring Billing" then
251+
exit;
252+
if FromSalesDocType <> Enum::"Sales Document Type From"::"Posted Invoice".AsInteger() then
253+
Error(CopyingErr);
254+
if ToSalesLine."Document Type" <> Enum::"Sales Document Type"::"Credit Memo" then
255+
Error(CopyingErr);
256+
end;
257+
221258
[IntegrationEvent(false, false)]
222259
local procedure OnAfterCreateBillingLineFromBillingLineArchive(var RRef: RecordRef; BillingLineArchive: Record "Billing Line Archive")
223260
begin

src/Apps/W1/Subscription Billing/App/Billing/Codeunits/CreateBillingDocuments.Codeunit.al

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,20 @@ codeunit 8060 "Create Billing Documents"
1414
trigger OnRun()
1515
var
1616
BillingLine: Record "Billing Line";
17+
PartnerFilter: Text;
18+
ShowNotification: Boolean;
1719
begin
1820
BillingLine.Copy(Rec);
21+
PartnerFilter := BillingLine.GetFilter(Partner);
22+
ShowNotification := PartnerFilter <> BillingLine.GetFilters();
23+
BillingLine.Reset();
24+
BillingLine.SetFilter(Partner, PartnerFilter);
1925
BillingLine.SetRange("Document Type", Enum::"Rec. Billing Document Type"::None);
2026
if CreateContractInvoice then
2127
BillingLine.SetRange("Billing Template Code", '');
2228
CreateBillingDocuments(BillingLine);
29+
if ShowNotification and (not CreateContractInvoice) then
30+
ShowFiltersIgnoredNotification();
2331
end;
2432

2533
local procedure CreateBillingDocuments(var BillingLine: Record "Billing Line")
@@ -1024,6 +1032,17 @@ codeunit 8060 "Create Billing Documents"
10241032
OnAfterIsNewHeaderNeededPerContract(CreateNewHeader, TempBillingLine, PreviousSubContractNo);
10251033
end;
10261034

1035+
local procedure ShowFiltersIgnoredNotification()
1036+
var
1037+
FiltersIgnoredMsg: Label 'You have set filters on the Recurring Billing page. The filters were ignored to maintain data consistency.';
1038+
FiltersIgnoredNotification: Notification;
1039+
begin
1040+
FiltersIgnoredNotification.Message(FiltersIgnoredMsg);
1041+
FiltersIgnoredNotification.Scope := NotificationScope::LocalScope;
1042+
FiltersIgnoredNotification.Send();
1043+
end;
1044+
1045+
10271046
internal procedure ErrorIfItemUnitOfMeasureCodeDoesNotExist(ItemNo: Code[20]; ServiceObject: Record "Subscription Header")
10281047
var
10291048
ItemUnitOfMeasure: Record "Item Unit of Measure";

0 commit comments

Comments
 (0)