item tracking. importing serial nos from external system

Hi,

Not an expert on item tracking here :-)

External system assigns serial numbers to Purchase Order Lines via BC extension method (see code below)
Sometimes, purchase order line already has the serial numbers assigned and they could be the same as those in external system.

External system does not know about it and still tries to assign serial numbers.

As a result, quantities in the tracking lines are wrong:

ehewcy5z8e3c.png

Instead it should be without undefined quantity:

2gic8tao19ky.png

How can you find if serial number already exists in the item tracking to skip it during the process of importing serial nos from external system?
Where is this information stored?

ba15saynii50.png

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);
        end;

        // 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;

Best Answer

  • DmitriySozinovDmitriySozinov Member Posts: 23
    Answer ✓
    Solution that worked for me was just to check if incoming serial number is already assigned to a purchase line and skip the whole reservation line update process.
    ...
              For i := 1 to SerialNosList.Count do begin
                ExistingSerialFound := false;
    
                ItemTrackingEntries.reset;
                ItemTrackingEntries.SetRange("Source Type", DATABASE::"Purchase Line");
                ItemTrackingEntries.SetRange("Source Subtype", PurchaseLine."Document Type");
                ItemTrackingEntries.SetRange("Source ID", PurchaseLine."Document No.");
                ItemTrackingEntries.SetRange("Source Ref. No.", PurchaseLine."Line No.");
                ItemTrackingEntries.SetRange("Serial No.", SerialNosList.Get(i));
                if ItemTrackingEntries.FindFirst() then
                    ExistingSerialFound := true;            
    
                if NOT ExistingSerialFound then begin
                  ReservationEntry."Serial No." := SerialNosList.Get(i);
                  ...
                  CreateReservEntry.CreateReservEntryFor
                  ...
                  CreateReservEntry.CreateEntry
                  ...
                end;
    ...
    

Answers

  • AlexDenAlexDen Member Posts: 86
    Hello,

    Try instead of
    If NOT ReservationEntry.IsEmpty then begin
      ReservationEntry.DeleteAll(true);
    end;
    

    use something like this:
    ReservationEntry.SetRange("Reservation Status", ReservationEntry."Reservation Status"::Reservation);
    If ReservationEntry.FindSet(true) then
      Repeat
        ReservationEntry2 := ReservationEntry;
        ReservEngineMgt.CancelReservation(ReservationEntry2);
      Until ReservationEntry.Next = 0;
    end;
    
    ReservationEntry.SetRange("Reservation Status");
    If NOT ReservationEntry.IsEmpty then
      ReservationEntry.DeleteAll(true);
    
  • DmitriySozinovDmitriySozinov Member Posts: 23
    Answer ✓
    Solution that worked for me was just to check if incoming serial number is already assigned to a purchase line and skip the whole reservation line update process.
    ...
              For i := 1 to SerialNosList.Count do begin
                ExistingSerialFound := false;
    
                ItemTrackingEntries.reset;
                ItemTrackingEntries.SetRange("Source Type", DATABASE::"Purchase Line");
                ItemTrackingEntries.SetRange("Source Subtype", PurchaseLine."Document Type");
                ItemTrackingEntries.SetRange("Source ID", PurchaseLine."Document No.");
                ItemTrackingEntries.SetRange("Source Ref. No.", PurchaseLine."Line No.");
                ItemTrackingEntries.SetRange("Serial No.", SerialNosList.Get(i));
                if ItemTrackingEntries.FindFirst() then
                    ExistingSerialFound := true;            
    
                if NOT ExistingSerialFound then begin
                  ReservationEntry."Serial No." := SerialNosList.Get(i);
                  ...
                  CreateReservEntry.CreateReservEntryFor
                  ...
                  CreateReservEntry.CreateEntry
                  ...
                end;
    ...
    
Sign In or Register to comment.