Zu/Abschläge ...Lieferschein stornieren?

1. Juni 2007 08:28

Hallo,

wir arbeiten mit Zu und Abschlägen. Hat einer von euch eine Lösung für das
stornieren von Lieferscheinen? Weil der Artikel dem der Zuschlag zugewiesen ist, lässt sich zwar stornieren, NICHT aber der Zuschlag....

Weiß jemand Rat?

1. Juni 2007 10:26

Hallo Pegasus,

ich habe dies für einen Kunden gelöst, der Zu-/Abschläge exzessiv für Rohstoffzuschläge nutzt. Dieser Kunde hatte zusätzlich die Anforderung Lieferscheine nur teilweise zu stornieren. Daher habe ich in die Lieferscheinzeile ein Feld "zu stornieren" und ein Feld "Menge storniert" eingefügt (mit jeweils dazu gehörendem Basismengen-Feld). Dann habe ich in die Tabelle 110 die folgende Funktion eingefügt:

Code:
eMStornoMengen()
----------------------------------------------------------------
// Zeilen stornieren
WITH ShipLine DO BEGIN
  SETRANGE("Document No.", Rec."No.");
  SETFILTER("zu Stornieren", '<>%1', 0);
  IF NOT FIND('-') THEN
    ERROR('Es gibt nichts zu stornieren.');
  IF NOT CONFIRM('Wollen Sie die erfassten Mengen wirklich stornieren?', FALSE) THEN
    ERROR('Die Verarbeitung wurde abgebrochen.');
  REPEAT
    IF (ABS("zu Stornieren") > ABS("Qty. Shipped Not Invoiced")) THEN
      ERROR('Sie können in Zeile %1 nicht mehr als %2 Einheiten stornieren.', "Line No.", "Qty. Shipped Not Invoiced");
    IF (("zu Stornieren" * Quantity) < 0) THEN
      ERROR('%1 muss das gleiche Vorzeichen wie %2 haben.', FIELDCAPTION("zu Stornieren"), FIELDCAPTION(Quantity));

    //Verkaufszeile aktuallisieren
    SalesLine.GET(SalesLine."Document Type"::Order, "Order No.", "Order Line No.");
    SalesLine."Quantity Shipped" -= "zu Stornieren";
    SalesLine."Qty. Shipped (Base)" -= "zu Stornieren (Basis)";
    SalesLine.InitOutstanding();
    SalesLine.InitQtyToInvoice();
    SalesLine.Rückstandsmenge :=
      SalesLine."Outstanding Quantity" - SalesLine."Reservierte Menge";
    SalesLine."Rückstandsmenge (Basis)" :=
      SalesLine."Outstanding Qty. (Base)" - SalesLine."Reservierte Menge (Basis)";
    SalesLine.Rückstand := (SalesLine."Rückstandsmenge (Basis)" <> 0);
    SalesLine.MODIFY;

    //Artikelbuchung
    IF (Type = Type::Item) THEN
      UndoSalesShipmentLine.eMPostItemJnlLine(ShipLine);

    //Lieferzeile aktuallisieren
    Quantity -= "zu Stornieren";
    "Quantity (Base)" -= "zu Stornieren (Basis)";
    "Qty. Shipped Not Invoiced" -= "zu Stornieren";
    "Menge storniert" += "zu Stornieren";
    "Menge storniert (Basis)" += "zu Stornieren (Basis)";
    "Back Order Quanity" += "zu Stornieren";
    "zu Stornieren" := 0;
    "zu Stornieren (Basis)" := 0;
    MODIFY;
  UNTIL(NEXT = 0);
END;


Die darin angesprochene Funktion eMPostItemJnlLine in Codeunit "Undo Sales Shipment Line" sieht wie folgt aus:

Code:
eMPostItemJnlLine(SalesShptLine : Record "Sales Shipment Line") : Integer
----------------------------------------------------------------------------------
SourceCodeSetup.GET;
TempTrackingSpecification.DELETEALL;

WITH SalesShptLine DO BEGIN
  ItemJnlLine.INIT;
  ItemJnlLine."Entry Type" := ItemJnlLine."Entry Type"::Sale;
  ItemJnlLine."Item No." := "No.";
  ItemJnlLine."Posting Date" := WORKDATE;
  ItemJnlLine."Document No." := "Document No.";
  ItemJnlLine."Gen. Prod. Posting Group" := "Gen. Prod. Posting Group";
  ItemJnlLine."Location Code":= "Location Code";
  ItemJnlLine."Source Code" := SourceCodeSetup.Sales;
  ItemJnlLine."Variant Code" := "Variant Code";
  ItemJnlLine."Bin Code" := "Bin Code";
  ItemJnlLine.Quantity := -"zu Stornieren (Basis)";
  ItemJnlLine."Quantity (Base)" := -"zu Stornieren (Basis)";
  IF LedgEntry.GET("Item Shpt. Entry No.") THEN BEGIN
    ItemJnlLine."Unit of Measure Code" := LedgEntry."Unit of Measure Code";
    ItemJnlLine."Source No." := LedgEntry."Source No.";
    ItemJnlLine."Document No." := LedgEntry."Document No.";
    ItemJnlLine.Description := LedgEntry.Description;
    ItemJnlLine."Source Type" := LedgEntry."Source Type";
    ItemJnlLine."Drop Shipment" := LedgEntry."Drop Shipment";
    ItemJnlLine."Transaction Type" := LedgEntry."Transaction Type";
    ItemJnlLine."Transport Method" := LedgEntry."Transport Method";
    ItemJnlLine."Country Code" := LedgEntry."Country Code";
    ItemJnlLine."Entry/Exit Point" := LedgEntry."Entry/Exit Point";
    ItemJnlLine."External Document No." := LedgEntry."External Document No.";
    ItemJnlLine.Area := LedgEntry.Area;
    ItemJnlLine."Transaction Specification" := LedgEntry."Transaction Specification";
    ItemJnlLine."Posting No. Series" := LedgEntry."No. Series";
    ItemJnlLine."Qty. per Unit of Measure" := LedgEntry."Qty. per Unit of Measure";
    ItemJnlLine.Quantity := ItemJnlLine.Quantity * ItemJnlLine."Qty. per Unit of Measure";
    ItemJnlLine."Derived from Blanket Order" := LedgEntry."Derived from Blanket Order";
    ItemJnlLine."Cross-Reference No." := LedgEntry."Cross-Reference No.";
    ItemJnlLine."Item Category Code" := LedgEntry."Item Category Code";
    ItemJnlLine.Nonstock := LedgEntry.Nonstock;
    ItemJnlLine."Purchasing Code" := LedgEntry."Purchasing Code";
    ItemJnlLine."Product Group Code" := LedgEntry."Product Group Code";
    ItemJnlLine."Unit Amount" := "Unit Price";
    ItemJnlLine."Unit Cost" := "Unit Cost (LCY)";
  END;
END;

IF FindTrackingSpecification(OldTrackingSpecification,FALSE) THEN BEGIN
  OldTrackingSpecification.FIND('-');
  SourceSpecification.INIT;
  SourceSpecification := OldTrackingSpecification;
  SourceSpecification."Source Type" := DATABASE::"Item Journal Line";
  SourceSpecification."Source Subtype" := ItemJnlLine."Entry Type";
  SourceSpecification."Source ID" := ItemJnlLine."Journal Template Name";
  SourceSpecification."Source Batch Name" := ItemJnlLine."Journal Batch Name";
  SourceSpecification."Source Ref. No." := ItemJnlLine."Line No.";
  SourceSpecification."Quantity (Base)" := -SalesShptLine."zu Stornieren (Basis)";
  SourceSpecification."Qty. to Handle (Base)" := -SalesShptLine."zu Stornieren (Basis)";
  SourceSpecification."Qty. to Invoice (Base)" := 0;
  SourceSpecification."Quantity Handled (Base)" := 0;
  SourceSpecification."Quantity Invoiced (Base)" := 0;
  REPEAT
    TempTrackingSpecification.INIT;
    TempTrackingSpecification := OldTrackingSpecification;
    TempTrackingSpecification."Source Type" := DATABASE::"Item Journal Line";
    TempTrackingSpecification."Source Subtype" := ItemJnlLine."Entry Type";
    TempTrackingSpecification."Source ID" := ItemJnlLine."Journal Template Name";
    TempTrackingSpecification."Source Batch Name" := ItemJnlLine."Journal Batch Name";
    TempTrackingSpecification."Source Ref. No." := ItemJnlLine."Line No.";
    TempTrackingSpecification."Quantity (Base)" := OldTrackingSpecification."Quantity (Base)";
    TempTrackingSpecification.Positive := (TempTrackingSpecification."Quantity (Base)" > 0);
    TempTrackingSpecification."Qty. to Handle (Base)" := OldTrackingSpecification."Quantity (Base)";
    TempTrackingSpecification."Qty. to Invoice (Base)" := 0;
    TempTrackingSpecification."Quantity Handled (Base)" := 0;
    TempTrackingSpecification."Quantity Invoiced (Base)" := 0;
    TempTrackingSpecification.INSERT;
  UNTIL OldTrackingSpecification.NEXT = 0;

  ItemTrackingForm.RegisterItemTrackingLines
    (SourceSpecification,SalesShptLine."Shipment Date",TempTrackingSpecification);

  NewReservEntry.SETCURRENTKEY("Source Type","Source Subtype");
  NewReservEntry.SETRANGE("Source Type",DATABASE::"Item Journal Line");
  NewReservEntry.SETRANGE("Source Subtype",ItemJnlLine."Entry Type");
  NewReservEntry.SETRANGE("Source ID",ItemJnlLine."Journal Template Name");
  NewReservEntry.SETRANGE("Source Batch Name",ItemJnlLine."Journal Batch Name");
  NewReservEntry.SETRANGE("Source Prod. Order Line",0);
  NewReservEntry.SETRANGE("Source Ref. No.",ItemJnlLine."Line No.");
  NewReservEntry.SETFILTER("Qty. to Handle (Base)",'<>0');
  IF NewReservEntry.FIND('-') THEN
    REPEAT
      NewReservEntry.Correction := TRUE;
      NewReservEntry.MODIFY;
    UNTIL NewReservEntry.NEXT = 0;
END;
ItemJnlPostLine.RUN(ItemJnlLine);

TempTrackingSpecification.DELETEALL;
IF ItemJnlPostLine.CollectTrackingSpecification(TempHandlingSpecification) THEN
  IF TempHandlingSpecification.FIND('-') THEN REPEAT
    TempTrackingSpecification := TempHandlingSpecification;
      TempTrackingSpecification."Source Type" := DATABASE::"Sales Line";
      TempTrackingSpecification."Source Subtype" := 1;
      TempTrackingSpecification."Source ID" := SalesShptLine."Order No.";
      TempTrackingSpecification."Source Batch Name" := '';
      TempTrackingSpecification."Source Prod. Order Line" := 0;
      TempTrackingSpecification."Source Ref. No." := SalesShptLine."Order Line No.";
      IF TempTrackingSpecification.INSERT THEN; //***
    UNTIL TempHandlingSpecification.NEXT = 0;

EXIT(ItemJnlLine."Item Shpt. Entry No.");


An den Menü-Eintrag "Warenausgang stornieren" habe ich dann den Aufruf der Funktion eMStornoMengen gehängt. Nur bei Artikelzeilen findet tatsächlich eine Buchung statt, in Sachkonto- und Zu-/Abschlagszeilen werden nur die Mengenfelder in den Belegen korrigiert, da auch bei der Lieferscheinbuchung hier nichts stattfindet.

Bei meinem Kunden läuft das seit Jahren gut. Wenn du den Code ganz oder teilweise benutzen willst mach das ruhig - aber auf eigene Gefahr!

Gruß
Frank

1. Juni 2007 11:27

Also wir stornieren ja die Lieferscheine auch schon...(mit negativen Zeilen)

würde das bedeuten das ich im Lieferschein einfach nur die Mengen bei Zu und Abschlägen auf NULL setzen darf? (wie auch immer?) und ich kann dann den Auftrag beenden und berechnen?

1. Juni 2007 11:34

Wenn Du die Mengen im Lieferschein änderst musst Du (meiner Meinung nach) auch dafür sorgen, dass im Auftrag die richtigen Werte stehen("Menge geliefert", "Lief. nicht fakt. Menge", "Lief. nicht fakt. Betrag" und dazugehörige Basismengen-Felder). Buchen müsst ihr aber für Zu-/Abschlagszeilen nach meinem Wissen nichts.

Ich verstehe aber nich ganz deinen Hinweis, dass ihr bisher mit "negativen Zeilen" storniert. Wie habe ich mir das denn vorzustellen? Habt ihr auch eine angepasste Stornierungs-Funktion, die zusätzliche Zeilen mit negativer Menge in den Lieferschein einfügt und den Auftrag korrigiert?

Gruß
Frank

1. Juni 2007 13:39

So ist es...wenn wir auf Stornieren drücken, dann wird ein zusätzlicher Eintrag
eines Artikels erzeugt....allerdings mit negativer Menge und normalerweise wird nach der Rechnungsstellung auch der Auftrag dann richtig beendet.

Nur mit Zu und Abschlägen wird das nicht gemacht. und alleine für diese Zeilen benötigen wir dann eine Lösung.

Soweit ich das gesehen habe hast du mir die "komplettlösung" geliefert
(vielen Dank) aus deinem Code würde ich also ausschliesslich die "Nullstellung" des Zu/Abschlages benötigen.....
Also kurz gesagt.... Nullen der Menge und der Basismenge
und im Auftrag müssten ebenfalls alle Mengenwerte genullt werden?

1. Juni 2007 13:46

Im Auftrag müssten die Mengenwerte um die Mengen des Lieferscheins korrigiert werden. Es ist ja möglich, dass ihr mehrere Teillieferungen habt. Eine davon soll jetzt storniert werden. Dann darf natürlich nur die Menge des "Teil-"Lieferscheins korrigiert werden.

Zur kontrolle dessen was passiert ist, sollte dann aber analog zu den Artikelzeilen noch eine Minuszeile für die Zuschlagsposition im Lieferschein eingetragen werden.

1. Juni 2007 14:58

Wenn, dann wird immer eine ganze Lieferscheinzeile storniert..demzufolge auch eine ganze Abschlagszeile, die dieser Zeile im Auftrag zugewiesen ist...

Nach der "richtigen" Stornierung des Lieferscheinbeleges ist diese Zeile aus
dem Auftrag verschwunden.

Jetzt ist es bei Abschlägen ja nur so das diese Zeile im Auftrag in der "Luft" hängt, weil die Zuweisungszeile nicht mehr da ist...aber die Lieferung ist erfolgt und somit ist der Auftrag momentan kaputt...

Die Abschlagszeile muss ebenfalls komplett storniert werden und ebenfalls aus dem Auftrag genommen werden...dieser Teil fehlt uns.....
Kann ich denn ebenfalls eine Negative Lieferzeile (Abschlag) erzeugen?????
Oder sollte iih die Werte der ersten Zeile nullen?