Skip to main content

Notifications

Community site session details

Community site session details

Session Id :
Small and medium business | Business Central, N...
Suggested answer

Overriding Table triggers from API pages

(4) ShareShare
ReportReport
Posted on by 51
Hi,
 
We utilise multiple No. Series for products in addition to division, item categories and retail product codes (this maybe an LS addition). When adding a new product from the UI any No Series can be selected:
 
That is fine and functions as intended. However, when you try to replicate this via an API page with the source table as Item (27) it will always default to the No. Series set in the setup page:
 
If this is removed, even for testing purposes and an request is sent via the API it will utilise a trigger found on the Item table - specifically this:
 
trigger OnInsert()
    var
        Item: Record Item;
#if not CLEAN24
        NoSeriesManagement: Codeunit NoSeriesManagement;
#endif
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnBeforeOnInsert(Rec, IsHandled, xRec);
        if not IsHandled then begin
            if "No." = '' then begin
                GetInvtSetup();
                InventorySetup.TestField("Item Nos.");
#if not CLEAN24
                NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(InventorySetup."Item Nos.", xRec."No. Series", 0D, "No.", "No. Series", IsHandled);
                if not IsHandled then begin
                    if NoSeries.AreRelated(InventorySetup."Item Nos.", xRec."No. Series") then
                        "No. Series" := xRec."No. Series"
                    else
                        "No. Series" := InventorySetup."Item Nos.";
                    "No." := NoSeries.GetNextNo("No. Series");
                    Item.ReadIsolation(IsolationLevel::ReadUncommitted);
                    Item.SetLoadFields("No.");
                    while Item.Get("No.") do
                        "No." := NoSeries.GetNextNo("No. Series");
                    NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", InventorySetup."Item Nos.", 0D, "No.");
                end;
#else
                if NoSeries.AreRelated(InventorySetup."Item Nos.", xRec."No. Series") then
                    "No. Series" := xRec."No. Series"
                else
                    "No. Series" := InventorySetup."Item Nos.";
                "No." := NoSeries.GetNextNo("No. Series");
                Item.ReadIsolation(IsolationLevel::ReadUncommitted);
                Item.SetLoadFields("No.");
                while Item.Get("No.") do
                    "No." := NoSeries.GetNextNo("No. Series");
#endif
                "Costing Method" := InventorySetup."Default Costing Method";
            end;

            DimMgt.UpdateDefaultDim(
              DATABASE::Item, "No.",
              "Global Dimension 1 Code", "Global Dimension 2 Code");

            UpdateReferencedIds();
            SetLastDateTimeModified();

            UpdateItemUnitGroup();
        end;

        OnAfterOnInsert(Rec, xRec);
    end;
 
and within the trigger I believe it is the relation check which is pulling the Inventory setup value and because the value used is different (in this case) it is defaulting to the Inventory Setup value. If you remove the Item Nos. from the Inventory Setup this will return an error (even via the API page) as this isn't set and is required.
 
On the API page I have tried to do an OnInsertRecord trigger which contains Rec.Insert() which I believe removes default triggers at the table from firing but this does not appear to be executing. I've also tried OnNewRecord which is firing but this removes any of the values from the Rec. e.g if the payload contains Key1: Value1 inside the OnNewRecord this will become Key1: ''. 
 
If doing this manually via the UI this works successfully and a record is inserted with the differing No Series however this isn't always viable for us as there could be 100s of additions over a monthly basis. Wondering whether anyone has had any success in handling this use case OR has a solution to add items via an API page with a different No Series compared to the Inventory Setup set inside the payload?
 
Thanks!
 
  • Suggested answer
    Khushbu Rajvi. Profile Picture
    16,784 Super User 2025 Season 1 on at
    Overriding Table triggers from API pages
    Hope this helps:
  • Suggested answer
    Khushbu Rajvi. Profile Picture
    16,784 Super User 2025 Season 1 on at
  • Jacob Profile Picture
    51 on at
    Overriding Table triggers from API pages
    Thanks for the detailed reply Saif. Unfortunately this suggestion did not work for me. I have tried both v1.0, v2.0 versions with no luck. 
     
    The trigger for OnInsertRecord is not firing though. I can guarantee it isn't due the below:
     
        trigger OnInsertRecord(BelowxRec: Boolean): Boolean
        var
            NoSeriesRec: Record "No. Series";
            NoSeriesFunc: Codeunit "No. Series";
            NoSeriesLineRec: Record "No. Series Line";
            NoSeriesCode: Code[20];
        begin
            Error('On insert record trigger called....'); // This does not get called.
    
            If Rec."No. Series" = '' then
                Error('No Series must be provided.');
    
            // generate a new no series.
            NoSeriesCode := NoSeriesFunc.GetNextNo(Rec."No. Series");
    
            Rec."No." := NoSeriesCode;
    
            exit(false);
    
        end;
    }
    The error should fire on the insert trigger and it doesn't. Instead I get a successful reply and insertion:

     
    Either the API page triggers are broken or something else is at play. 
     
  • Suggested answer
    Saif Ali Sabri Profile Picture
    2,107 Super User 2025 Season 1 on at
    Overriding Table triggers from API pages
    You're correct in your assessment—when inserting via the API, the OnInsert trigger on table 27 (Item) is executed, and it enforces the default behavior using the Inventory Setup’s "Item Nos." field and NoSeriesManagement. This restricts flexibility in choosing different No. Series unless it's either related or explicitly defined, which isn’t ideal for your use case.
    To address this while still utilizing the API, here's a structured solution approach that preserves the intended No. Series provided in the payload, bypassing the enforced Inventory Setup series:

    Solution: API Page Customization with Manual Series Assignment
    🔧 1. Create a Custom API Page (Based on Page 27 – Item)
    You need to extend the API using a custom API page based on the Item table. This allows you to control behavior using the OnInsertRecord trigger and handle No. Series logic manually.
    al
    CopyEdit
    page 50100 "Custom Item API"
    {
        PageType = API;
        SourceTable = Item;
        APIPublisher = 'yourpublisher';
        APIGroup = 'custom';
        APIVersion = 'v1.0';
        EntityName = 'item';
        EntitySetName = 'items';
        DelayedInsert = true;

        layout
        {
            area(content)
            {
                field(No; Rec."No.") { ApplicationArea = All; }
                field("No. Series"; Rec."No. Series") { ApplicationArea = All; }
                field(Description; Rec.Description) { ApplicationArea = All; }
                // Add other fields as needed
            }
        }

        trigger OnInsertRecord(BelowxRec: Boolean): Boolean
        var
            NoSeriesMgt: Codeunit NoSeriesManagement;
            CustomNo: Code[20];
        begin
            if Rec."No." = '' then begin
                if Rec."No. Series" = '' then
                    Error('No Series must be provided for item creation via API.');

                // Generate the next number from the provided series
                CustomNo := NoSeriesMgt.GetNextNo(Rec."No. Series", WorkDate, true);
                Rec."No." := CustomNo;
            end;

            exit(false); // Ensures default table OnInsert is not executed.
        end;
    }
    📌 Notes:
    • The use of DelayedInsert = true is critical. It delays the record insertion until explicitly triggered via Rec.Insert(), which gives you full control.
    • exit(false) skips the table's OnInsert trigger, avoiding the default behavior in InventorySetup.
    • You must pass both No. Series and optionally No. in the API payload if controlling the number.

    🔁 Example Payload
    Here’s what the JSON payload should look like when posting to your custom API endpoint:
    json
    CopyEdit
    {
        "noSeries": "HO-ITEMS",
        "description": "New Item via API",
        // Include other required fields
    }

    🧪 Testing Tips
    • If you omit "no" in the payload, the OnInsertRecord will generate it based on the provided "noSeries".
    • If "noSeries" is missing, the system will throw an error (custom error from your trigger).
    • Ensure "No. Series" is available and valid; otherwise, GetNextNo() will throw.

    ⚠️ Avoid Using OnNewRecord
    As you've discovered, OnNewRecord clears values and is more for pre-initialization logic in UI contexts. For API-based creation, OnInsertRecord is your correct trigger.

    Result
    Using this approach, your API can accept multiple No. Series values (e.g., HO-ITEMS, RET-ITEM, etc.) without depending on the one defined in Inventory Setup, making your solution scalable and automated.

    Let me know if you need help with publishing the custom API page or handling authentication for external integrations.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Announcing the Engage with the Community forum!

This forum is your space to connect, share, and grow!

🌸 Community Spring Festival 2025 Challenge Winners! 🌸

Congratulations to all our community participants!

Adis Hodzic – Community Spotlight

We are honored to recognize Adis Hodzic as our May 2025 Community…

Leaderboard > Small and medium business | Business Central, NAV, RMS

#1
Sohail Ahmed Profile Picture

Sohail Ahmed 1,382

#2
YUN ZHU Profile Picture

YUN ZHU 1,008 Super User 2025 Season 1

#3
Mansi Soni Profile Picture

Mansi Soni 880

Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans