web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

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

Sales Order - Reserve Always Setting

(11) ShareShare
ReportReport
Posted on by 760
We are looking to enable to the Item Card Reserve = Always setting.  We want to be able to have BC auto create the Sales Order Reservation Entries when:
  • A Purchase Order is created from a Sales Order for Drop Shipment orders
  • Sufficient OnHand & Available Qty exists for orders shipping from a warehouse location.
There are 2 exceptions to the latter scenario:
  • If the available inventory is in a Bin defined as "INTRANSIT" (or in any Bin not deemed available to Ship from)
  • If the Order Qty exceeds the available Inventory Qty (we don't want Reservation Entries that are less than the Sales Order Qty)
Trying to determine if there are any BC configurations for these scenarios (I can't find any), or if I have to develop some custom code to handle deletion of the automated "non-qualified" Reservation Entries after BC creates them.
 
Any thoughts on how to handle this?
I have the same question (0)
  • Suggested answer
    Sumit Singh Profile Picture
    11,795 Super User 2026 Season 1 on at
     Out-of-the-Box Capabilities
     What Business Central Supports Natively:
    • Item Card → Reserve = Always: Automatically reserves inventory for outbound documents (Sales Orders, etc.).
    • Drop Shipment: Automatically links PO to SO and reserves the PO line to the SO line.
    • Reservation Worksheet: Allows bulk reservation with allocation policies like:
      • Basic (No Conflicts): Only reserves if full quantity is available.
      • By Customer Priority: Reserves based on customer ranking.
    What Business Central Does Not Support Natively:
    • Bin-level filtering (e.g., exclude INTRANSIT bins from reservation logic).
    • Blocking partial reservations (e.g., only reserve if full Sales Order Qty is available).
    • Auto-deletion of invalid reservations based on bin or quantity logic.
     Recommended Customization Strategy
    To meet your exact needs, you’ll need custom code in AL. Here's a breakdown:
    1. Custom Codeunit to Monitor Reservation Entries
    • Trigger: On insert of Reservation Entry (Table 337).
    • Logic:
      • Check if the source document is a Sales Order.
      • Evaluate:
        • Is the reserved quantity < Sales Line quantity?
        • Is the Bin Code in a list of non-shippable bins (e.g., INTRANSIT)?
      • If either condition is true → delete the reservation entry.
    2. Custom Setup Table
    • Maintain a list of non-shippable bin codes.
    • Allow flexibility for future changes without code modification.
    3. Optional: Modify Reservation Logic
    • Override standard reservation behavior using event subscribers to:
      • Prevent reservation creation if conditions are not met.
      • Or, allow creation but clean up immediately after.

    Pseudocode (AL)
    [EventSubscriber(ObjectType::Table, Database::"Reservation Entry", 'OnAfterInsertEvent', '', true, true)]
    local procedure OnAfterInsertReservationEntry(var Rec: Record "Reservation Entry")
    var
        SalesLine: Record "Sales Line";
        BinContent: Record "Bin Content";
        CustomSetup: Record "My Custom Setup";
    begin
        if Rec."Source Type" = DATABASE::"Sales Line" then begin
            SalesLine.Get(Rec."Source Subtype", Rec."Source ID", Rec."Source Ref. No.");
            if Rec.Quantity < SalesLine.Quantity then
                Rec.Delete();

            if BinContent.Get(Rec."Location Code", Rec."Bin Code", Rec."Item No.") then
                if CustomSetup.IsNonShippableBin(BinContent."Bin Code") then
                    Rec.Delete();
        end;
    end;
    Custom AL solution broken into two parts:
    Part 1: Custom Setup Table for Non-Shippable Bins
    This table allows you to define bins like "INTRANSIT" that should be excluded from reservation logic.
    Table: NonShippableBinSetup
    table 50100 "NonShippable Bin Setup"
    {
        DataClassification = CustomerContent;

        fields
        {
            field(1; "Bin Code"; Code[20])
            {
                DataClassification = CustomerContent;
            }
        }

        keys
        {
            key(PK; "Bin Code") { Clustered = true; }
        }
    }

    Part 2: Codeunit to Monitor and Delete Invalid Reservations
    This codeunit listens for new reservation entries and deletes them if:
    • The reserved quantity < Sales Line quantity, or
    • The Bin Code is in the NonShippable Bin Setup.
    Codeunit: ReservationValidator
    codeunit 50101 "Reservation Validator"
    {
        [EventSubscriber(ObjectType::Table, Database::"Reservation Entry", 'OnAfterInsertEvent', '', true, true)]
        local procedure OnAfterInsertReservationEntry(var Rec: Record "Reservation Entry")
        var
            SalesLine: Record "Sales Line";
            BinContent: Record "Bin Content";
            NonShippableBin: Record "NonShippable Bin Setup";
        begin
            if Rec."Source Type" = DATABASE::"Sales Line" then begin
                if SalesLine.Get(Rec."Source ID", Rec."Source Ref. No.") then begin
                    if Rec.Quantity < SalesLine.Quantity then begin
                        Rec.Delete();
                        exit;
                    end;

                    if BinContent.Get(Rec."Location Code", Rec."Bin Code", Rec."Item No.") then
                        if NonShippableBin.Get(BinContent."Bin Code") then begin
                            Rec.Delete();
                            exit;
                        end;
                end;
            end;
        end;
    }

    Optional: Page for Maintaining Non-Shippable Bins
    page 50100 "NonShippable Bin List"
    {
        PageType = List;
        SourceTable = "NonShippable Bin Setup";
        ApplicationArea = All;

        layout
        {
            area(content)
            {
                repeater(Group)
                {
                    field("Bin Code"; "Bin Code") { ApplicationArea = All; }
                }
            }
        }
    }
    References
    [1] How to reserve items - Business Central | Microsoft Learn

    Note: This response was created in collaboration with Microsoft Copilot to ensure clarity and completeness. I hope it helps to some extent.
    Mark the Answer as Verified if this is Helpful.
     
  • Suggested answer
    Jainam M. Kothari Profile Picture
    16,520 Super User 2026 Season 1 on at
    Hello,
     
    Business Central’s “Reserve = Always” setting on the Item Card automatically creates reservation entries for sales orders, including drop shipments and warehouse inventory, but it doesn’t support excluding specific bins (like “INTRANSIT”) or blocking partial reservations natively.
     
    To meet these exceptions, Custom AL Development is needed—typically via event subscribers that monitor reservation entries and delete or prevent those that don’t meet criteria like full quantity availability or valid bin codes. 
  • Suggested answer
    Mansi Soni Profile Picture
    9,353 Super User 2026 Season 1 on at
    Hello @ME-31032107-0,

    Business Central does not provide out-of-the-box configuration to fully control automatic reservation creation with the level of granularity you describe such as excluding reservations from INTRANSIT bins or preventing partial reservations when available quantity is insufficient. The standard Item Card Reserve = Always setting will create reservations automatically whenever possible, including partial reservations and from any available bins.

    To enforce your specific rules like excluding certain bins or requiring full quantity reservations you will need to implement custom code or extensions to adjust or delete undesired reservation entries after BC’s automated process runs. This can be done by subscribing to reservation events or creating a batch job that reviews and corrects reservations based on your criteria.

    Hope this answer will help you!

    Regards,
    Mansi Soni
  • Suggested answer
    YUN ZHU Profile Picture
    100,974 Super User 2026 Season 1 on at
    It seems that this can only be achieved through customization. It is recommended that you discuss your specific needs with local partners.
     
    Thanks.
    ZHU
  • Suggested answer
    Jeffrey Bulanadi Profile Picture
    9,121 Super User 2026 Season 1 on at

    Hi,

    The “Reserve = Always” setting on the Item Card does trigger automatic reservation entries, but it doesn’t account for bin-level exclusions or partial quantity logic out of the box.

    BC will attempt to reserve inventory as long as any quantity is available, regardless of bin type or whether the full order quantity can be fulfilled. That means reservations may be created from bins like “INTRANSIT” or for quantities less than the sales line — which doesn’t align with your operational intent.

    To handle this, you’ll need a small customization. The cleanest approach is to subscribe to the OnAfterInsertEvent of the Reservation Entry table and evaluate each reservation as it’s created. If the reserved quantity is less than the sales line quantity, or if the bin code is in a list of excluded bins, you can delete the reservation entry immediately.

    You can also create a setup table to maintain your list of non-shippable bins, which gives you flexibility without hardcoding values. If you prefer to block the reservation before it’s created, you can intercept the logic earlier using event subscribers tied to the reservation flow.

    This pattern gives you full control while preserving the native reservation behavior for qualified inventory.

    Helpful references:
    How to reserve items – Microsoft Learn
    Understanding the ALWAYS Reservation Policy
    Reservation Entry table – Microsoft Learn
    Mastering Item Reservation – BC Insight


    If you find this helpful, feel free to mark this as the suggested or verified answer.

    Cheers
    Jeffrey

  • ME-31032107-0 Profile Picture
    760 on at
    Thanks all for the guidance and direction.  I am working on coding for the Reservation Entry deletion.  One other related item I am trying to accomplish this is to modify the "Item Availability" and "Available Inventory" values in the "Sales Line Fact Box" Page.  I've traced the calculations to CodeUnit "Sales Info-Pane Management".  I have developed a Query that summarizes all Qtys in Bins that are excluded from my custom Availability calculation, and would like to subtract them from the standard results in those two fields (and use it as a basis for the Reservation Entry coding).
     
    Not sure if I can modify the fields directly in the Page by subtracting my query results, or if I need to modify what is getting returned from the CodeUnit.  Or, do I need to hide those fields from the FactBox and add new fields with my updated calculations?
  • ME-31032107-0 Profile Picture
    760 on at
    Part of the challenge with deleting the Reservation Entries is that when they are auto created, there could be more than one Reservation Entry added to the table, based on the size of the Order Qty and the available Item Ledger Entries.
     
    So I don't think I can just delete the Reservation Entries after they are Inserted.  I need to be able to evaluate the sum of all related Reservation Entries that have been created, and if the total is less than the Sales Order Quantity, delete ALL the Reservation Entries.
     
    Any thoughts on modifying existing sample code provided, or another approach based on this scenario is appreciated.
  • Suggested answer
    YUN ZHU Profile Picture
    100,974 Super User 2026 Season 1 on at
    Hi, You can also try solutions provided by partners on AppSource directly.
     
    Thanks
    ZHU
  • Verified answer
    ME-31032107-0 Profile Picture
    760 on at
    I decided to take a different approach to solve this issue.  Instead of trying to figure out how to delete the auto created Reservation Entries we do not want, I added an OnBeforeValidate trigger on the Quantity field that evaluates the calculations and scenarios that disqualify the Sales Line from keeping the Reserve = "Always" setting and changing it to "Optional". This prevents the Reservation Entry from being auto created, and allows the user to add the Reservation Entry manually if needed.
     
    Much easier to control the desired functionality this way.
  • ME-31032107-0 Profile Picture
    760 on at
    I wanted to do a follow up to this.  Setting the Reserve field to "Optional" (as I documented below) addressed the majority of my issues in this situation.
     
    But I also found that if Reservation Entries were made against a Sales Order, and then the Order Qty was increased to exceed the Available Inventory calculation for the item, it made (or kept) a partial Reservation (which we do not want).  Only 100% of the Order Qty can be Reserved, or nothing should be Reserved.
     
    So I needed to come up with a way to Cancel the Reservations that were partial.  Simply deleting the Reservation Entry (demand) records for the Sales Order line was not working, since it was orphaning the related Supply entries (e.g., Item Ledger Entries).  This was causing OnHand availability issues, as the supply record still existed when the demand record was deleted.
     
    What I found was there is a CodeUnit "Reservation Engine Mgt." (99000831) that handles the "Cancel Reservation" functionality in the Reservation Worksheet.  More specifically, the procedure "CancelReservation" does all the work.
     
    All I had to do in my SalesOrderSubForm page was to add the following code, which calls the CodeUnit & procedure:
     
        procedure CancelReservationEntries()
        var
            SOReservEntry: Record "Reservation Entry";
            ReservEntry: Record "Reservation Entry";
            EntryNo: Integer;
        begin
            SOReservEntry.SetRange("Source ID", Rec."Document No.");
            SOReservEntry.SetRange("Source Ref. No.", Rec."Line No.");
            if SOReservEntry.FindSet() then
                repeat
                    EntryNo := SOReservEntry."Entry No.";
                    ReservEntry.SetRange("Entry No.", SOReservEntry."Entry No.");
                    if ReservEntry.Find('-') then
                        repeat
                            ReservEntry.TestField("Reservation Status", ReservEntry."Reservation Status"::Reservation);
                            ReservEntry.TestField("Disallow Cancellation", false);
                            begin
                                ReservEngineMgt.CancelReservation(ReservEntry);
                                Commit();
                            end;
                        until ReservEntry.Next() = 0;
                until SOReservEntry.Next() = 0;
        end;
        protected var
            ReservEngineMgt: Codeunit "Reservation Engine Mgt.";
     
    I call this procedure when the Order Line encounters a partial Reservation, and both the supply and demand reservations get cancelled.  This approach seems to work for me.
     

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

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Meet the Microsoft Dynamics 365 Contact Center Champions

We are thrilled to have these Champions in our Community!

Congratulations to the April Top 10 Community Leaders

These are the community rock stars!

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

#1
OussamaSabbouh Profile Picture

OussamaSabbouh 2,086 Super User 2026 Season 1

#2
YUN ZHU Profile Picture

YUN ZHU 1,290 Super User 2026 Season 1

#3
AndrewThomas81 Profile Picture

AndrewThomas81 1,218

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans