Understanding GETRANGEMIN() and GETRANGEMAX() in Business Central

When working with filters and record ranges in AL , two handy functions often come into play: GETRANGEMIN() and GETRANGEMAX(). These functions help you programmatically access the lower and upper bounds of a filter applied to a field in a record. This can be especially useful for creating reports, processing data, or passing filters between records.

What are GETRANGEMIN() and GETRANGEMAX()?

These two functions are part of the Record data type and help retrieve the range boundaries for a specific field filter.

  • GETRANGEMIN(Field): Returns the lowest value in the filter range for the specified field.
  • GETRANGEMAX(Field): Returns the highest value in the filter range for the specified field.

If there is no filter set for the field, both functions return blank.

SalesHeader.SETFILTER("No.", '1000..2000');

MinNo := SalesHeader.GETRANGEMIN("No."); // Returns '1000'
MaxNo := SalesHeader.GETRANGEMAX("No."); // Returns '2000'

Use Cases

1. Transferring Filter Ranges

If you’re applying a filter on one table and want to use the same range on another:

Customer.SETFILTER("No.", 'C00010..C00020');
SalesHeader.SETRANGE("Sell-to Customer No.", Customer.GETRANGEMIN("No."), Customer.GETRANGEMAX("No."));

2. Generating Custom Reports

SalesHeader.SETFILTER("Posting Date", '2024-01-01..2024-01-31');

StartDate := SalesHeader.GETRANGEMIN("Posting Date");
EndDate := SalesHeader.GETRANGEMAX("Posting Date");

MESSAGE('Report for: %1 to %2', StartDate, EndDate);

3. Validating Filtered Data

IF (SalesHeader.GETRANGEMIN("Posting Date") < AllowedStartDate) OR
   (SalesHeader.GETRANGEMAX("Posting Date") > AllowedEndDate) THEN
    ERROR('Filter range is outside allowed period.');

The GETRANGEMIN() and GETRANGEMAX() functions are powerful tools when working with dynamic filters in AL. They enable developers to write cleaner, more adaptable code by directly accessing the boundaries of filter conditions.

Stay Tuned for more updates.

Boosting Performance in Business Central with SetAutoCalcFields

In today’s fast-paced business environments, performance optimization is not a luxury — it’s a necessity. Whether you’re building custom reports, extending pages, or writing integration APIs in Microsoft Dynamics 365 Business Central, slow operations can frustrate users and strain resources.

One simple but powerful technique to improve performance is using the SetAutoCalcFields method.

Why FlowFields Matter for Performance

In Business Central, FlowFields are virtual fields calculated on the fly, not stored physically in the database. Examples include:

  • Inventory on Item
  • Balance on Customer

When you retrieve a record, FlowFields are not calculated automatically unless you explicitly call CalcFields().

Manually calculating FlowFields for every record during loops, leading to multiple SQL queries — one for each record — causing heavy load and slower performance.

SetAutoCalcFields solves this by batch-calculating FlowFields along with the record fetch.
Instead of running one query per record, it combines the calculation in a single optimized query.

Imagine fetching 1,000 customers and displaying their balances without SetAutoCalcfields:

CustomerRec.FindSet();
repeat
    CustomerRec.CalcFields(CustomerRec.Balance); // Triggers a DB call every time!
    DisplayBalance(CustomerRec."No.", CustomerRec.Balance);
until CustomerRec.Next() = 0;

Result:
  • 1 SQL query to get Customers
  • + 1,000 SQL queries for Balances

With SetAutoCalcFields:

CustomerRec.SetAutoCalcFields(CustomerRec.Balance);
CustomerRec.FindSet();
repeat
    DisplayBalance(CustomerRec."No.", CustomerRec.Balance);
until CustomerRec.Next() = 0;

Result:
  • 1 SQL query to get Customers and Balances together

Benefits of Using SetAutoCalcFields

  • Improved Page Load Times: By deferring calculations, pages with numerous records and calculated fields will load significantly faster.
  • Faster Report Generation: Reports that rely on calculated fields will be generated more quickly as the calculations are performed only when the field’s value is actually needed for display or processing.
  • Reduced Database Load: Fewer automatic calculations translate to fewer database queries, reducing the overall load on your Business Central database.
  • Enhanced User Experience: Snappier performance leads to a more responsive and enjoyable user experience.

Best Practices for Performance Gains

To maximize the benefits of SetAutoCalcFields:

  • Only specify necessary FlowFields:
    Don’t auto-calculate every FlowField — focus on what your process needs.
  • Use it before data retrieval:
    Call SetAutoCalcFields before FindSet(), FindFirst(), or FindLast()
  • Avoid unnecessary recalculations:
    Once FlowFields are set to auto-calculate, do not manually call CalcFields() again for the same fields.
  • Monitor heavy FlowFields:
    Some FlowFields (e.g., Inventory) involve complex sums across tables — only auto-calculate when really needed.
  • Profile your code:
    Use Performance Profiler to measure improvements.

Using SetAutoCalcFields properly can lead to dramatic performance improvements in Business Central.
By reducing SQL traffic, simplifying code, and batch-fetching FlowFields intelligently, you can create faster, cleaner, and more scalable applications.

A small change in your coding habits can create a big impact for your users.

Hope this will help..

How to Make a Report Layout Obsolete in Business Central (Wave 1 2025)

With the release of Microsoft Dynamics 365 Business Central Wave 1 2025, it continues to refine the AL development experience — and one of the key improvements is the ability to obsolete report layouts cleanly and officially.

If you’re managing a growing list of custom layouts or updating reports across multiple extensions, this new feature will help you deprecate old layouts safely, keep your solution clean, and guide developers or users toward better alternatives.

Why Obsoleting Layouts Matters

In real-world implementations, layouts evolve:

  • Data fields change.
  • Users request better designs.
  • Old layouts become unsupported.

Without a proper way to deprecate these layouts, organizations risk:

  • Confusion about which layout to use
  • Broken printouts
  • Technical debt piling up over time

Now, with Wave 1 2025, you can mark layouts as obsolete similarly to how you obsolete fields, tables, or procedures.

report 50100 "Sales Invoice Custom"
{
    Caption = 'Sales Invoice Custom';
    UsageCategory = ReportsAndAnalysis;
    ApplicationArea = All;
rendering
{
    layout(CustomLayout)
    {
        Type = RDLC;
        LayoutFile = 'Layouts\CustomSalesInvoice.rdl';
        ObsoleteState = Pending;
        ObsoleteReason = 'Replaced by layout NewCustomLayout in report 50101.';
        ObsoleteTag = 'BC-2025';
    }
}
}

ObsoleteState: Can be Pending (warning) or Removed (error).

ObsoleteReason: Brief explanation for developers/users.

ObsoleteTag: Identifies when/why it was marked obsolete (your own versioning or tag).

What Happens to Users When a Layout is Obsoleted?

  • ObsoleteState = Pending:
    • Users and developers get compiler warnings.
    • The layout is still selectable and usable.
  • ObsoleteState = Removed:
    • The system throws compiler errors if any report layout tries to use it.
    • Users can no longer select it at runtime.

The ability to obsolete report layouts in Business Central Wave 1 2025 is a small but powerful feature that can dramatically improve the quality, maintainability.

Whether you’re cleaning up old customer-specific layouts or modernizing your extensions, using Obsolete State strategically will help future-proof your solutions.

Stay Tuned for more updates!!!

Convert Simple Type Values to Text Using the New ToText Method in Business Central 2025 Wave 1

With the release of Business Central 2025 Wave 1, Business Central continues to simplify AL development by introducing intuitive and developer-friendly features. One such small yet powerful enhancement is the ToText method — designed to streamline how simple type values are converted to text.

In previous versions, we developers often relied on FORMAT() for converting simple types like integers, decimals, booleans, and option values into text. While FORMAT() has been effective, it comes with localization considerations and sometimes produces inconsistent results depending on the environment or the formatting settings.

✨ What’s New: ToText Method

The new ToText method is a type extension method introduced for simple AL types. It provides a clearer, more consistent way to convert values to string representations without the overhead of full formatting logic.

Supported Types

The ToText method supports the following simple types:

  • Integer
  • Decimal
  • Boolean
  • Char
  • Option
  • Date
  • Time
  • DateTime
  • GUID

Let’s look at some examples of how the ToText() method can simplify your code:

var
    myInteger: Integer := 42;
    myDecimal: Decimal := 2.71828;
    myDate: Date := TODAY;
    myTime: Time := TIME(10, 30, 0);
    myBoolean: Boolean := true;
    myOption: Option Alpha,Beta,Gamma := Option::Beta;
    integerAsText: Text;
    decimalAsText: Text;
    dateAsText: Text;
    timeAsText: Text;
    booleanAsText: Text;
    optionAsText: Text;
begin
    integerAsText := myInteger.ToText(); // integerAsText will be '42'
    decimalAsText := myDecimal.ToText(); // decimalAsText will be '2.71828' (or similar based on locale)
    dateAsText := myDate.ToText();       // dateAsText will be the default short date format
    timeAsText := myTime.ToText();       // timeAsText will be the default time format
    booleanAsText := myBoolean.ToText(); // booleanAsText will be 'true'
    optionAsText := myOption.ToText();   // optionAsText will be 'Beta'
    Message('Integer: %1', integerAsText);
    Message('Decimal: %1', decimalAsText);
    Message('Date: %1', dateAsText);
    Message('Time: %1', timeAsText);
    Message('Boolean: %1', booleanAsText);
    Message('Option: %1', optionAsText);
end;

Prefer ToText() when you want predictable results across environments (e.g., when storing values in logs or metadata).

Continue using FORMAT() when you need locale-aware output, such as in printed documents or user-facing formatted messages.

It simplifies the process of converting simple data types to their default text representations, leading to cleaner, more readable, and potentially more efficient code. While FORMAT() remains the go-to for advanced formatting needs, ToText() will undoubtedly become a frequently used tool in your Business Central development.

Stay tuned for more…

Changing the CardPageId in a Page Extension – Business Central Wave 1 2025

With the release of Business Central 2025 Wave 1, Business central continues to refine and empower AL developers with more flexibility when extending standard functionality. One of the subtle but significant features is the ability to change the CardPageId in a PageExtension, giving developers greater control over navigation behavior in the application.

Why Would You Want to Change CardPageID?

Consider these scenarios:

  • Simplified Views: You’ve created a simplified version of a standard card page with only the most relevant fields for a specific user role. Now, you can easily link the standard list page to this streamlined card page for those users.
  • Custom Workflows: Your custom solution requires a specialized card page with unique actions and fields for certain data. You can now seamlessly integrate this custom card page with the existing list of that data.
  • Context-Specific Information: Depending on how a user navigates to a list page, you might want them to land on a different, more contextually relevant card page.

Let’s say you’ve built a custom card page for customers that shows additional analytics or fields. You want to replace the default Customer Card when users open a customer from the list.

page 50101 "Custom Customer Card"
{
    PageType = Card;
    SourceTable = Customer;
    ApplicationArea = All;

    layout
    {
        area(content)
        {
            group("Custom Info")
            {
                field("Customer Name"; Name)
                {
                    ApplicationArea = All;
                }
                // Additional fields and logic...
            }
        }
    }
}

Then, in your page extension:

pageextension 50100 CustomerListExt extends "Customer List"
{
    CardPageId = "Custom Customer Card";
}

Now, your users will be directed to the Custom Customer Card page instead of the standard one.

The ability to change the CardPageID in page extensions in Business Central Wave 1 2025 is a significant step forward in providing developers with more control over the user interface. This seemingly small change unlocks a wealth of possibilities for creating more tailored, efficient, and user-friendly Business Central solutions.

Stay tuned for more updates.

FieldRef.IsOptimizedForTextSearch() Method in Business Central 2025 Wave 1

With the release of Business Central 2025 Wave 1, Microsoft continues to empower developers with more control and insights into the performance and behavior of their extensions. Among the new additions is the method FieldRef.IsOptimizedForTextSearch(), designed to help developers make more performance-conscious decisions when implementing search functionalities.

💡 What is FieldRef.IsOptimizedForTextSearch()?

FieldRef.IsOptimizedForTextSearch() is a method that returns a Boolean value indicating whether a particular field in a table is optimized for text search.

It is a method on the FieldRef data type, which is used in AL code to dynamically refer to fields of records, especially in scenarios involving field iteration, metadata handling, or dynamic filters.

✅ Syntax:

Boolean := FieldRef.IsOptimizedForTextSearch();

⚙️ How to Optimize a Field for Text Search

While IsOptimizedForTextSearch() only checks if a field is optimized, setting it up is done via the table metadata or through the table schema in AL.

To mark a field for text search:

field(10; Description; Text[100])
{
Caption = 'Description';
DataClassification = ToBeClassified;
OptimizeForTextSearch = true;
}

Setting OptimizeForTextSearch = true; enables text search optimization (depending on SQL backend settings as well for on-premise).

Lets see how we can utlize above method to check optimize search

var
    MyRecordRef: RecordRef;
    MyFieldRef: FieldRef;
    IsOptimized: Boolean;
begin
    MyRecordRef.Open(Database::Customer);
    if MyRecordRef.FindSet() then begin
        MyFieldRef := MyRecordRef.Field(Name); // Let's check the "Name" field
        IsOptimized := MyFieldRef.IsOptimizedForTextSearch();

        if IsOptimized then
            Message('The "%1" field in the Customer table is optimized for text search.', MyFieldRef.Name())
        else
            Message('The "%1" field in the Customer table is NOT optimized for text search.', MyFieldRef.Name());
    end;
    MyRecordRef.Close();
end;

To be optimized for full-text search, a field typically needs:

  • A Text or Code data type.
  • An active index that supports full-text search (defined in the table metadata or via table extensions).
  • Proper settings in SQL Server or Azure SQL (if full-text search is enabled).

The FieldRef.IsOptimizedForTextSearch() method is a small but powerful tool in the AL developer’s toolkit. Whether you’re designing smarter search UIs or optimizing performance in large datasets, this method gives you the metadata visibility to make informed choices.

By leveraging this feature, you can:

  • Improve app performance
  • Avoid slow queries
  • Create better user experiences

Stay tuned for more..

AutoFormatExpression Property in Business Central – Wave 1 2025

With the release of Business Central 2025 Wave 1, Microsoft continues enhancing the AL language to make development cleaner, more flexible, and maintainable. One of the updates includes improvements around the AutoFormatExpression property — a property that may seem minor but plays a crucial role in controlling how data is displayed, especially in reports and pages.

In essence, the AutoFormatExpression property allows you to define a specific format for how numeric and date/time values are displayed in your Business Central application. This goes beyond the basic formatting options and provides granular control over aspects like decimal places, thousands separators, date and time patterns, and more.

What is the AutoFormatExpression Property?

The AutoFormatExpression property in AL is used to specify a formatting expression that overrides the default formatting behavior of a control. It works in conjunction with the AutoFormatType property and is typically used in pages and reports to control how numeric or date values are displayed.

For example, you might want to display a date in DD-MM-YYYY format instead of the system default, or format a decimal with specific currency or precision rules.

How Does AutoFormatExpression Work?

The AutoFormatExpression property accepts a string that defines the desired format. The syntax of this string follows specific rules depending on whether you are formatting numeric or date/time data.

For Numeric Data:

The expression can include placeholders for:

  • Decimal Places: Use # for optional digits and 0 for mandatory digits after the decimal point.
  • Thousands Separator: Typically a comma (,), but this can be influenced by regional settings.
  • Currency Symbol: The currency symbol is usually determined by the AutoFormatType and AutoFormatSubType properties.

Example:

  • #,##0.00: Displays numbers with two decimal places and thousands separators (e.g., 1,234.56).
  • 0.0: Displays numbers with one mandatory decimal place (e.g., 123.4).

For Date/Time Data:

The expression uses specific codes to represent different parts of the date and time:

  • Days: d (day of the month), dd (day of the month with leading zero), ddd (abbreviated day name), dddd (full day name).
  • Months: M (month number), MM (month number with leading zero), MMM (abbreviated month name), MMMM (full month name).
  • Years: yy (two-digit year), yyyy (four-digit year).
  • Hours: h (12-hour format), hh (12-hour format with leading zero), H (24-hour format), HH (24-hour format with leading zero).
  • Minutes: m (minutes), mm (minutes with leading zero).
  • Seconds: s (seconds), ss (seconds with leading zero).
  • Milliseconds: f, ff, fff (fractional seconds).
  • AM/PM: tt (AM/PM designator).
  • Time Separator: Typically a colon (:), but this can be influenced by regional settings.
  • Date Separator: Typically a slash (/), hyphen (-), or period (.), but this can be influenced by regional settings.

Examples:

  • MM/dd/yyyy: Displays date as month/day/year (e.g., 12/25/2025).
  • dd-MMM-yy hh:mm tt: Displays date and time with abbreviated month and 12-hour format (e.g., 25-Dec-25 06:36 PM).
  • dddd, MMMM dd, yyyy: Displays the full day, month, and year (e.g., Monday, December 25, 2025).
table AutformatTable
{
    fields
    {
        field(1; "Amount"; Decimal)
        {
            AutoFormatType = 10; // Currency
            AutoFormatExpression = "#,##0.00";
        }
        field(2; "Order Date"; Date)
        {
            AutoFormatExpression = "MM/dd/yyyy";
        }
        field(3; "Order Time"; Time)
        {
            AutoFormatExpression = "hh:mm:ss tt";
        }
    }
}

page AutoFormatPage
{
    layout
    {
        area(content)
        {
            group(GroupName)
            {
                field("Amount"; Rec.Amount)
                {
                    // Inherits AutoFormatExpression from the table field
                }
                field("Formatted Amount"; Rec.Amount)
                {
                    AutoFormatExpression = "0.##"; // Overrides table field format for this instance
                }
                field("Order Date"; Rec."Order Date")
                {
                    // Inherits AutoFormatExpression from the table field
                }
                field("Order Time"; Rec."Order Time")
                {
                    // Inherits AutoFormatExpression from the table field
                }
            }
        }
    }
}

Another example could be as follows

pageextension 50100 CustomerListExt extends "Customer List"
{
    layout
    {
        addlast(content)
        {
            field("Balance LCY"; Rec."Balance (LCY)")
            {
                ApplicationArea = All;
                AutoFormatType = 1;
                AutoFormatExpression = Rec."Currency Code";
            }
        }
    }
}

While AutoFormatExpression gives you precise control, be aware that regional settings can still influence aspects like decimal and thousands separators, as well as date and time formats if not explicitly defined.

The AutoFormatExpression property in Business Central Wave 1 2025 is a significant enhancement for developers looking to control the presentation of numeric and date/time data.

Stay tuned for more !!!

Report.TargetFormat() Method in Business Central 2025 Wave 1

With the release of Microsoft Dynamics 365 Business Central 2025 Wave 1, Microsoft has continued to improve the AL language and reporting capabilities. One notable addition for developers working with reports is the new Report.TargetFormat() method. This small yet powerful enhancement gives developers more control and visibility over how reports are executed, especially in scenarios involving automation, scheduling, or integration.

The Report.TargetFormat() method allows you to set the target output format for a report at runtime. This is particularly useful in scenarios where the desired output format isn’t static or needs to be determined based on user preferences, system configurations, or specific business logic.

Imagine you have a page action that allows users to export a list of customers. Instead of having separate actions for different formats, you can use Report.TargetFormat() to dynamically generate the output in Excel.

pageextension 50100 CustomerListExt extends "Customer List"
{
    actions
    {
        addfirst(Processing)
        {
            action(ExportToExcel)
            {
                Caption = 'Export to Excel';
                Image = ExportExcel;
                trigger OnAction()
                var
                    CustomerListReport: Report "Customer List";
                    ReportSettings: Record "Report Settings";
                begin
                    ReportSettings.TargetFormat := Enum::"Report Format"::Excel;
                    CustomerListReport.Run(ReportSettings);
                end;
            }
        }
    }
}

In this example, before running the “Customer List” report, we set the TargetFormat property of a ReportSettings record to Excel. When the report is executed using Run(ReportSettings), it will automatically be generated as an Excel file.

Consider a scenario where you need to automatically generate and archive a sales order confirmation as a PDF after the order is posted. You can achieve this within a codeunit.

codeunit 50101 SalesOrderProcessing
{
    procedure GenerateConfirmationPDF(SalesHeaderRec: Record "Sales Header")
    var
        SalesConfirmationReport: Report "Sales - Order Conf.";
        ReportSettings: Record "Report Settings";
    begin
        ReportSettings.TargetFormat := Enum::"Report Format"::PDF;
        SalesConfirmationReport.SetTableView(SalesHeaderRec);
        SalesConfirmationReport.Run(ReportSettings);
        // Code to archive the generated PDF can be added here
    end;
}

Here, within the GenerateConfirmationPDF procedure, we explicitly set the TargetFormat to PDF for the “Sales – Order Conf.” report. When the report is run, it will be generated directly as a PDF document.

You can create a more user-friendly experience by presenting users with a choice of output formats before running a report.

pageextension 50102 ItemListExt extends "Item List"
{
    actions
    {
        addfirst(Processing)
        {
            action(ExportItemData)
            {
                Caption = 'Export Item Data';
                Image = Export;
                trigger OnAction()
                var
                    ItemListReport: Report "Item List";
                    ReportSettings: Record "Report Settings";
                    ExportFormat: Option "PDF","Excel","CSV";
                begin
                    ExportFormat := Dialog.Confirm('Choose Export Format:', true, ExportFormat);
                    case ExportFormat of
                        ExportFormat::PDF:
                            ReportSettings.TargetFormat := Enum::"Report Format"::PDF;
                        ExportFormat::Excel:
                            ReportSettings.TargetFormat := Enum::"Report Format"::Excel;
                        ExportFormat::CSV:
                            ReportSettings.TargetFormat := Enum::"Report Format"::CSV;
                    end;
                    ItemListReport.Run(ReportSettings);
                end;
            }
        }
    }
}

The Report.TargetFormat() method is a subtle yet powerful addition to the AL reporting toolbox in Business Central 2025 Wave 1. It unlocks a new level of flexibility for report behavior and presentation, enabling developers to create more intelligent, format-aware reporting solutions.

Stay tuned for more.

Generate launch.json from the Web Client in Business Central – Wave 1 2025

With the 2025 Wave 1 release of Microsoft Dynamics 365 Business Central, developers get a significant productivity boost: the ability to generate a launch.json file directly from the Web Client! 🎉 This is a feature that eliminates the need to manually configure environment settings in Visual Studio Code (VS Code), especially useful when working across multiple environments or containers.

💡 What is launch.json?

In AL development for Business Central, the launch.json file defines how your AL project connects to your Business Central environment. It includes settings like:

{
  "name": "Your Environment",
  "type": "al",
  "request": "launch",
  "server": "https://your-environment-url",
  "serverInstance": "BC",
  "authentication": "UserPassword",
  "tenant": "your-tenant-id"
}

You can now generate the launch.json configuration directly from the Web Client using just a few clicks. No more copying URLs, figuring out authentication types, or guessing server details.

🔧 Steps to Generate:

  1. Log into your Business Central Web Client.
  2. Navigate to the Help & Support page (? page=134).
  3. Scroll down to the Troubleshooting section.
  4. Look for the new Download launch.json button (or similar option).
  5. Click it – a launch.json file will be downloaded, pre-filled with your current environment’s configuration.

Second option will be navigate Installed extensions and download launch.json

The introduction of the launch.json generation feature in the Business Central Wave 1 2025 web client is a welcome addition for AL developers. It promises to streamline the initial setup process, reduce configuration errors, and enhance overall development efficiency.

Stay tuned fore more.

Business Central 2025 Wave 1 (BC26): Check Total Purchase Amounts on Documents

The Business Central 2025 Wave 1 (BC26) release introduces a valuable feature aimed at enhancing the accuracy and efficiency of accounts payable processes: “Check Doc. Total Amounts”. While seemingly simple from a user perspective, but powerful addition that helps users validate purchase documents before posting.

At its heart, “Check Doc. Total Amounts” is designed to prevent posting discrepancies between the manually entered total amounts on purchase document headers and the calculated total amounts based on the individual purchase lines. This helps ensure that the data within Business Central accurately reflects the external vendor invoices, minimizing potential errors and reconciliation issues.

Implementation Details:

Setup: The functionality is controlled via a new option within the Purchases & Payables Setup page. Administrators need to explicitly enable the “Check Doc. Total Amounts” toggle. This opt-in approach ensures that existing environments are not impacted unless the feature is intentionally activated.

New Fields: Upon enabling the feature, two new fields become visible on the Purchase Invoice and Purchase Credit Memo pages:

  • Doc. Amount Incl. VAT: This field is intended for users to enter the total amount, including VAT, as stated on the vendor’s document.
  • Doc. Amount VAT: This field allows users to enter the total VAT amount as per the vendor’s document.

Automatic Calculation: When a user enters a value in the “Doc. Amount Incl. VAT” field, the system automatically calculates and populates the “Doc. Amount VAT” field based on the VAT rates applied to the individual purchase lines. Conversely, if the user enters the “Doc. Amount VAT”, the “Doc. Amount Incl. VAT” is automatically calculated.

Validation on Posting: The crucial technical aspect lies in the posting validation logic. When a user attempts to post a Purchase Invoice or Purchase Credit Memo with the “Check Doc. Total Amounts” feature enabled, Business Central performs the following checks:

  • It calculates the sum of the “Amount Including VAT” for all individual purchase lines.
  • It calculates the total VAT amount based on the VAT entries of the purchase lines.
  • It compares these calculated totals with the values entered in the “Doc. Amount Incl. VAT” and “Doc. Amount VAT” fields on the document header.

Error Handling: If the calculated total amounts from the lines do not match the manually entered amounts on the header, the system will prevent posting and display an error message to the user. This forces a review of the purchase lines and header information to identify and rectify any discrepancies before the document can be posted.

The “Check Doc. Total Amounts” feature in Business Central 2025 Wave 1 (BC26) is a welcome addition for improving the accuracy of purchase document processing.

Stay tuned for more.