Assign serial numbers to purchase order line via extension

Hi,

Trying to find a proper solution for assigning serial numbers to a purchase order line through extension or API method.
BC version is 19.3.0.2 on-prem.

In NAV, you would pass serial number directly into CreateReservEntry.CreateReservEntryFor method, like this:

[External] CreateReservEntryFor(ForType : Option;ForSubtype : Integer;ForID : Code[20];ForBatchName : Code[10];ForProdOrderLine : Integer;ForRefNo : Integer;ForQtyPerUOM : Decimal;Quantity : Decimal;QuantityBase : Decimal;ForSerialNo : Code[20];ForLotNo : Code[20])

InsertReservEntry.SetSource(ForType,ForSubtype,ForID,ForRefNo,ForBatchName,ForProdOrderLine);
Sign := SignFactor(InsertReservEntry);
InsertReservEntry.Quantity := Sign * Quantity;
InsertReservEntry.“Quantity (Base)” := Sign * QuantityBase;
InsertReservEntry.“Qty. per Unit of Measure” := ForQtyPerUOM;
InsertReservEntry.“Serial No.” := ForSerialNo;
InsertReservEntry.“Lot No.” := ForLotNo;

InsertReservEntry.TESTFIELD(“Qty. per Unit of Measure”);

But in BC, CreateReservEntry.CreateReservEntryFor method is changed, so you no longer can pass Serial No., but instead Serial No. is copied from ReservEntry:

Codeunit 99000830 Create Reserv. Entry

procedure CreateReservEntryFor(ForType: Option; ForSubtype: Integer; ForID: Code[20]; ForBatchName: Code[10]; ForProdOrderLine: Integer; ForRefNo: Integer; ForQtyPerUOM: Decimal; Quantity: Decimal; QuantityBase: Decimal; ForReservEntry: Record “Reservation Entry”)

var
    Sign: Integer;
begin
    InsertReservEntry.SetSource(ForType, ForSubtype, ForID, ForRefNo, ForBatchName, ForProdOrderLine);
    Sign := SignFactor(InsertReservEntry);
    InsertReservEntry.Quantity := Sign * Quantity;
    InsertReservEntry."Quantity (Base)" := Sign * QuantityBase;
    InsertReservEntry."Qty. per Unit of Measure" := ForQtyPerUOM;
    **InsertReservEntry.CopyTrackingFromreservEntry(ForReservEntry);**
    InsertReservEntry.TestField("Qty. per Unit of Measure");
    OnAfterCreateReservEntryFor(InsertReservEntry, Sign, ForType, ForSubtype, ForID, ForBatchName, ForProdOrderLine, ForRefNo, ForQtyPerUOM, Quantity, QuantityBase, ForReservEntry);
end;

Table 337 Reservation Entry

procedure CopyTrackingFromReservEntry(ReservationEntry: Record "Reservation Entry")
begin
    "Serial No." := ReservationEntry."Serial No.";
    "Lot No." := ReservationEntry."Lot No.";

    OnAfterCopyTrackingFromReservEntry(Rec, ReservationEntry);
end;

So, the question is what would be the correct way to ‘feed’ Reservation Entry with serial nos. before executing CreateReservEntryFor?

Is there a method in Codeunit 99000830 Create Reserv. Entry or Table 337 Reservation Entry that can be utilized for this?

There is an example that you can follow on this link.

Hi Teddy,

Thank you!

Will give it a try and post back about results.

In case someone was wondering, following code worked for assigning serial numbers to purchase order lines with included sync between sales and purchase orders for drop shipment lines.

procedure AssignSerialNos(DocumentType: Integer; DocumentNumber: Code[20]; LineNo: Integer; SerialNosString: Text) Assigned: Boolean;
    var
        Item: Record Item;
        PurchaseHeader: Record "Purchase Header";
        PurchaseLine: Record "Purchase Line";
        ReservationEntry: Record "Reservation Entry";
        TrackingSpecification: Record "Tracking Specification";
        CreateReservEntry: Codeunit "Create Reserv. Entry";
        ItemTrackingMgt: Codeunit "Item Tracking Management";
        ItemTrackingPage: Page "Item Tracking Lines";
        TrackingLinesInitialized: Boolean;
        i: Integer;
        SerialNosList: List of [Text];
        RunMode: Enum "Item Tracking Run Mode";
    begin
        SerialNosList := SerialNosString.Split(';');
        if SerialNosList.Count = 0 then
            exit(false);

        PurchaseHeader.Get(DocumentType, DocumentNumber); //DocumentType:Order=1,Invoice=2,CreditNote=3        
        case PurchaseHeader."Document Type" of
            PurchaseHeader."Document Type"::Order:
                PurchaseLine.Get(PurchaseHeader."Document Type"::Order, PurchaseHeader."No.", LineNo);
            PurchaseHeader."Document Type"::Invoice:
                PurchaseLine.Get(PurchaseHeader."Document Type"::Invoice, PurchaseHeader."No.", LineNo);
        end;

        PurchaseLine.TestField(Type, 2); //2 = item            
        PurchaseLine.TestField("No.");
        PurchaseLine.TestField("Quantity (Base)");

        Item.Get(PurchaseLine."No.");
        Item.TestField("Item Tracking Code");

        ReservationEntry.Reset();
        ReservationEntry.SetRange("Source Type", DATABASE::"Purchase Line");
        ReservationEntry.SetRange("Source Subtype", PurchaseLine."Document Type");
        ReservationEntry.SetRange("Source ID", PurchaseLine."Document No.");
        ReservationEntry.SetRange("Source Ref. No.", PurchaseLine."Line No.");
        ReservationEntry.SetRange("Source Batch Name", '');
        ReservationEntry.SetRange("Source Prod. Order Line", 0);
        If NOT ReservationEntry.IsEmpty then begin
            ReservationEntry.DeleteAll(true);
        end;

        For i := 1 to SerialNosList.Count do begin
            ReservationEntry."Serial No." := SerialNosList.Get(i);

            if PurchaseLine."Document Type" = PurchaseLine."Document Type"::Order then begin
                CreateReservEntry.CreateReservEntryFor(
                    DATABASE::"Purchase Line",   //ForType
                    1,                           //ForSubtype - Order
                    PurchaseLine."Document No.", //ForID
                    '',                          //ForBatchName
                    0,                           //ForProdOrderLine
                    PurchaseLine."Line No.",     //ForProdOrderLine
                    1,                           //ForQtyPerUOM
                    1,                           //Quantity
                    1,                           //QuantityBase
                    ReservationEntry);           //ForReservEntry            
            end;

            if PurchaseLine."Document Type" = PurchaseLine."Document Type"::Invoice then begin
                CreateReservEntry.CreateReservEntryFor(
                    DATABASE::"Purchase Line",   //ForType
                    2,                           //ForSubtype - Invoice
                    PurchaseLine."Document No.", //ForID
                    '',                          //ForBatchName
                    0,                           //ForProdOrderLine
                    PurchaseLine."Line No.",     //ForProdOrderLine
                    1,                           //ForQtyPerUOM
                    1,                           //Quantity
                    1,                           //QuantityBase
                    ReservationEntry);           //ForReservEntry            
            end;

            CreateReservEntry.CreateEntry(
                PurchaseLine."No.",
                PurchaseLine."Variant Code",
                PurchaseLine."Location Code",
                PurchaseLine.Description,
                PurchaseLine."Expected Receipt Date",
                0D,
                0,
                ReservationEntry."Reservation Status"::Surplus);

            // item tracking lines have to be synchronized between sales and purchase orders, when the purchase order is a drop shipment
            If PurchaseLine."Drop Shipment" then begin
                If not TrackingLinesInitialized then begin
                    //PurchLineReserve.InitTrackingSpecification(PurchaseLineLoc,TrackingSpecification);
                    TrackingSpecification.InitFromPurchLine(PurchaseLine);
                    ItemTrackingPage.SetRunMode(Runmode::"Drop Shipment");
                    IF PurchaseLine."Sales Order No." <> '' THEN
                        ItemTrackingPage.SetSecondSourceRowID(ItemTrackingMgt.ComposeRowID(DATABASE::"Sales Line", 1, PurchaseLine."Sales Order No.", '', 0, PurchaseLine."Sales Order Line No."));
                    ItemTrackingPage.SetSourceSpec(TrackingSpecification, PurchaseLine."Expected Receipt Date");
                    TrackingLinesInitialized := true;
                end;
                ItemTrackingPage.SynchronizeLinkedSources('')
            end;
        end;
    end;