In BC 2024 wave 1, Microsoft will introduce a new Business Central Foundation Layer with the first app – redesigned No. Series. A few weeks back, Microsoft merged their changes into the BCApps repository (see the pull request here: Introducing new Business Foundation layer – No. Series by AndreasMoth · Pull Request #319 · microsoft/BCApps (github.com).
Since then, Microsoft has been working on uptaking the changes to the core base app. Let’s have a look at how it’s implemented in the base app. You can use the same approach in your apps to redesign your custom modules to use the BC foundation layer.
No. field OnValidate()
There is only a small change in the No. OnValidate trigger. Instead of calling TestManual(…) from the NoSeriesManagement codeunit, the new implementation calls the same procedure TestManual(…) from the new BC foundation layer app “No. Series” codeunit.
Old implementation
field(3; "No."; Code[20])
{
Caption = 'No.';
trigger OnValidate()
begin
if "No." <> xRec."No." then begin
GetSalesSetup();
NoSeriesMgt.TestManual(GetNoSeriesCode());
"No. Series" := '';
end;
end;
}
New implementation
field(3; "No."; Code[20])
{
Caption = 'No.';
trigger OnValidate()
begin
if "No." <> xRec."No." then begin
GetSalesSetup();
NoSeries.TestManual(GetNoSeriesCode());
"No. Series" := '';
end;
end;
}
InitInsert()
The changes in the InitInsert(…) procedure are larger. The changes are done in a non-breaking way, so it should be safe to use the old implementation for at least the next two major releases.
The new implementation calls the existing events OnBeforeInitSeries() and OnAfterInitSeries() from the NoSeriesManagement indirectly. If you want to follow the same principle for your apps (which is especially important if you are an ISV publisher and there may be external customizations to your ISV solution), use the new procedures RaiseObsoleteOnBeforeInitSeries(…) and RaiseObsoleteOnAfterInitSeries(…) from the NoSeriesManagement codeunit.
Apart from the events, the implementation is similar. Instead of using InitSeries(…), there is a different procedure called AreRelated(…).
Old implementation
if "No." = '' then begin
TestNoSeries();
NoSeriesMgt.InitSeries(GetNoSeriesCode(), xRec."No. Series", "Posting Date", "No.", "No. Series");
SalesHeader2.ReadIsolation(IsolationLevel::ReadUncommitted);
SalesHeader2.SetLoadFields("No.");
while SalesHeader2.Get("Document Type", "No.") do
"No." := NoSeriesMgt.GetNextNo("No. Series", "Posting Date", true);
end;
New implementation
if "No." = '' then begin
TestNoSeries();
NoSeriesCode := GetNoSeriesCode();
#if not CLEAN24
NoSeriesMgt.RaiseObsoleteOnBeforeInitSeries(NoSeriesCode, xRec."No. Series", "Posting Date", "No.", "No. Series", IsHandled);
if not IsHandled then begin
#endif
"No. Series" := NoSeriesCode;
if NoSeries.AreRelated("No. Series", xRec."No. Series") then
"No. Series" := xRec."No. Series";
"No." := NoSeries.GetNextNo("No. Series", "Posting Date");
SalesHeader2.ReadIsolation(IsolationLevel::ReadUncommitted);
SalesHeader2.SetLoadFields("No.");
while SalesHeader2.Get("Document Type", "No.") do
"No." := NoSeries.GetNextNo("No. Series", "Posting Date");
#if not CLEAN24
NoSeriesMgt.RaiseObsoleteOnAfterInitSeries("No. Series", NoSeriesCode, "Posting Date", "No.");
end;
#endif
It’s important to note that the update has not been completed yet! There will be further changes required, for example, to procedures TestNoSeries() and TestNoSeriesDate().
The update for these procedures will be done in the upcoming weeks and I’ll create another blog post to summarize the rest of required changes.