[gelöst] Artikelverfolgungsinfo via C/AL hinterlegen

5. Dezember 2017 19:59

Hallo Community,
Ich möchte an einer Verkaufszeile via C/AL Artikelverfolgungsinfo's hinterlegen. Ich habe etwas im Netz gestöbert und bin dabei auf die CU's 99000830 Create Reserv. Entry und 99000845 Reservation Management gestoßen die mir die dafür notwendigen Funktionen bieten. Andere schrieben auch, man solle die Reservierungsposten einfach selbst schreiben.

Da ich aber immer die älteste Charge nehmen möchte und der Standard das ja prinzipiell auch kann wollte ich das Rad nicht neu erfinden und habe mit den gegebenen Mittel rumprobiert.

Aktuell stehe ich an folgendem Punkt:
Code:
lcuReservationManagement.SetSalesLine(lSalesLine);
DoFullReserve := FALSE;
lcuReservationManagement.AutoReserve(DoFullReserve,'TEST',WORKDATE,lSalesLine."Quantity (Base)",lSalesLine."Quantity (Base)");


Dieser Aufruf erzeugt aber 2 Reservierungsposten:
Reservierungsposten.JPG


Wieso wurden 2 Einträge erstellt?
Der zweite Eintrag hat die Chargennummer aber keinen Bezug zu meinem Auftrag und Mengenmäßig heben sich die Reservierungen auch auf.
Ist mein Code noch unvollständig oder sollte ich die Reservierungsposten lieber selbst schreiben (bspw. wie hier: https://community.dynamics.com/nav/f/34/t/186214)? Wobei ich eigentlich gern die Logik von NAV zur Auswahl der Charge nutzen möchte und dies ungern manuell programmieren will.

Vielen Dank für eure Vorschläge!
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von ThomasM am 11. Dezember 2017 16:23, insgesamt 1-mal geändert.

Re: Artikelverfolgungsinfo via C/AL hinterlegen

5. Dezember 2017 20:17

Hallo Thomas,

das ist völlig korrekt, dass 2 Posten erstellt warden. Posten der Art Reservierung haben geben immer die Quelle und das Ziel an. In deinem Fall auso Quelle Tabelle 37, Belegart Auftrag (1) und Ziel Tabelle 32 (Reservierung auf Artikelposten).

Die Posten haben auch die selbe Lfd. Nr., einmal Positiv, einmal nicht Positiv. Deshalb auch der zusammengesetzte Primärschlüssel.

Re: Artikelverfolgungsinfo via C/AL hinterlegen

6. Dezember 2017 22:18

Hallo Carsten,
Danke für die Info. Das macht Sinn. Aber wieso kann ich dann keine Reservierung in der Artikelverfolgung sehen?
*edit*
ich bin ein wenig weiter: trage ich die Chargennr. manuell in die Reservierungsposten die zum Auftag gehören ein, ist alles wie es sein soll. D.h. die automatische Reservierung sucht nur nach den Quellposten aber setz nicht die entsprechenden Info's in den Zielposten. Aber wieso? Die Spalte "Artikelverfolgung" der Auftrags-Reservierungsposten hat auch als Wert "ohne" - wieso?
Es freut mich ja, dass es so scheinbar klappt - aber ich wüsste gern wieso o.O

Ich war bisher nicht erfolgreich auf meiner Suche nach einer Beschreibung/Dokumentation der Codeunit Reservation Management.
Kannst du mir einen Tipp geben wo ich entsprechende Ressourcen finden kann? (ggf. Bücher o.ä.)

Bisher bin ich in der MSDN nur hier (Design Details: Reservation, Order Tracking, and Action Messaging https://msdn.microsoft.com/en-us/library/jj552492(v=nav.90).aspx) oder hier (Walkthrough: Tracing Serial/Lot Numbers https://msdn.microsoft.com/en-us/library/hh174273(v=nav.90).aspx) gelandet. Aber das ist meist eher aus Anwendungssicht und nicht aus der Entwicklungssicht im Sinne von welche Objekte in welcher Reihenfolge beteiligt sind.

Re: Artikelverfolgungsinfo via C/AL hinterlegen

11. Dezember 2017 16:22

Ich habe es jetzt für meine Verkaufsaufträge gelöst:
Code:
LOCAL PROCEDURE SalesOrderLineReserve@1000000012(VAR pioSalesLine@1000000000 : Record 37;piItem@1000000001 : Record 27);
    VAR
      lReservationEntry@1000000010 : Record 337;
      lReservEntryILE@1000000009 : Record 337;
      lReservEntryEdit@1000000008 : Record 337;
      lSalesLine@1000000006 : Record 37;
      lcuReservationManagement@1000000004 : Codeunit 99000845;
      DoFullReserve@1000000003 : Boolean;
      lcuSalesLineReserve@1000000002 : Codeunit 99000832;
    BEGIN
      lcuReservationManagement.SetSalesLine(pioSalesLine);
      lcuReservationManagement.AutoReserve(DoFullReserve, pioSalesLine.Description, WORKDATE, pioSalesLine."Outstanding Quantity", pioSalesLine."Outstanding Qty. (Base)");
      lcuSalesLineReserve.FilterReservFor(lReservationEntry,pioSalesLine);

      IF lReservationEntry.FINDSET THEN
        REPEAT
          lReservEntryILE.GET(lReservationEntry."Entry No.", NOT lReservationEntry.Positive);
          lReservEntryEdit.GET(lReservationEntry."Entry No.", lReservationEntry.Positive);
          lReservEntryEdit."Lot No." := lReservEntryILE."Lot No.";
          lReservEntryEdit.MODIFY;
        UNTIL lReservationEntry.NEXT = 0;
    END;


Die Funktion AutoReserve der CU Reservation Management erledigt alles für mich.

Da ich auch über Verkaufsreklamationen chargengeführte Artikel zurücknehme habe ich mich dafür entschieden, die zurückgenommene Menge immer zur ältesten Chargen zugehen zu lassen da ich nicht weiß von welcher Charge die Menge tatsächlich abgegangen ist. Die Informationen kommen über eine Schnittstelle von einem externen System ins NAV.

Code:
    LOCAL PROCEDURE SalesReturnOrderLineReserve@1000000015(VAR pioSalesLine@1000000001 : Record 37);
    VAR
      lcuSalesLineReserve@1000000000 : Codeunit 99000832;
      lTempTrackSpec@1000000002 : TEMPORARY Record 336;
      lTempTrackingSpecification@1000000008 : TEMPORARY Record 336;
      lItemTrackingInformation@1000000004 : Record 6505;
      lRemainingLifeDate@1000000005 : Date;
      lExpirationDate@1000000009 : Date;
      loldestLotNo@1000000006 : Code[20];
      lNextLineNo@1000000007 : Integer;
      lcuReservationManagement@1000000010 : Codeunit 99000845;
      lcuCreateReservEntry@1000000011 : Codeunit 99000830;
      lpgItemTrkgLines@1000000003 : Page 6510;
    BEGIN
      lcuSalesLineReserve.InitTrackingSpecification(pioSalesLine, lTempTrackSpec);
      IF lTempTrackSpec.FINDLAST THEN
        lNextLineNo := lTempTrackSpec."Entry No." + 1
      ELSE
        lNextLineNo := 1;

      lItemTrackingInformation.SETRANGE("Item No.", pioSalesLine."No.");
      lItemTrackingInformation.SETFILTER("Location Filter", pioSalesLine."Location Code");
      lItemTrackingInformation.SETFILTER(Inventory, '>0');
      IF lItemTrackingInformation.FINDSET THEN BEGIN
        lRemainingLifeDate := lItemTrackingInformation."Remaining Life Date";
        loldestLotNo := lItemTrackingInformation."Lot No.";
        lExpirationDate := lItemTrackingInformation."Expiration Date";
        REPEAT
          IF lItemTrackingInformation."Remaining Life Date" < lRemainingLifeDate THEN BEGIN
            lRemainingLifeDate := lItemTrackingInformation."Remaining Life Date";
            loldestLotNo := lItemTrackingInformation."Lot No.";
            lExpirationDate := lItemTrackingInformation."Expiration Date";
          END;
        UNTIL lItemTrackingInformation.NEXT = 0;
      END;
      lTempTrackingSpecification := lTempTrackSpec;
      lTempTrackingSpecification."Entry No." := lNextLineNo;
      lTempTrackingSpecification.VALIDATE("Lot No.", loldestLotNo);
      lTempTrackingSpecification.VALIDATE("Remaining Life Date", lRemainingLifeDate);
      lTempTrackingSpecification.VALIDATE("Expiration Date", lExpirationDate);
      lTempTrackingSpecification.INSERT;

      lpgItemTrkgLines.SetSource(lTempTrackSpec, pioSalesLine."Shipment Date");
      lpgItemTrkgLines.AdjustItemTrkgLines(lTempTrackSpec, pioSalesLine."Shipment Date", lTempTrackingSpecification);
    END;