0

Erzeugung von Einträgen über ein Skript.

Hallo zusammen. Ich hoffe auf eure Hilfe bei einem Problem.

Wie sieht das Modell aus: Das Domainmodell besteht aus Produkt, Lieferant, Lieferantenprodukt, Lieferantenbestellung, Lieferantenbestellung (Posten).

Bildschirmfoto 2018-12-21 um 07.42.57

* Produkt: Produkte mit Anzahl der Verkäufen und aktuellem Lagerbestand.
* Lieferantenprodukt: Ein Mapping zwischen unseren Produktdaten und den Daten des Lieferanten (z.B. SKU und Lieferanten SKU)
* Lieferantenbestellung: Ein Bestellung der Produkte bei einem Lieferanten.
* Lieferantenbestellung (Posten): Die Einzelposten einer Lieferantenbestellung mit Produkt und Anzahl.

Was möchte ich erreichen: Bei einem Ereignis (Button Klick / Run in der Console), möchte ich unter bestimmten Umständen eine Lieferantenbestellung und einen Lieferantenbestellung (Posten) erzeugen.

Wie ist der Hintergrund: Ich möchte dem Einkäufer die Möglichkeit geben eine Lieferantenbestellung für ein bestimmtes Produkt zu erstellen. Und zwar unter folgenden Bedingungen:

* Wenn es noch keine Bestellung für diesen Lieferanten im Status Entwurf gibt, dann erzeugen. Sonst: die offene Bestellung verwenden.

* Wenn es noch keinen Posten für dieses Produkt in der Bestellung gibt erzeugen. Sonst: den bereits bestehenden Posten verwenden und die Anzahl anpassen.

 

Wie ist der Kontext: Beim Ereignis befinde ich mich in einem Produkt. Habe also die Zuordnung zu einem Lieferantenprodukt und kenne die Anzahl der Einheiten, die ich bestellen möchte.

 

Wie sieht das Skript aus:

// Berechne fehlende Einheiten
let lGap := Gap * -1;

// Ermittle die erste Lieferantenzuordnung, um an den Lieferanten zu kommen
let lProdukt := first(Lieferantenzuordnung);

// Speichere den Lieferanten zwischen
let lLieferant := lProdukt.Lieferant;

// Ermittle die erste Bestellung des Lieferanten, die im Status "Entwurf" ist.
let lBestellung := first(lLieferant.Bestellungen[Status = 1]);

// Wenn es noch keine offene Bestellung gibt, dann erstelle eine.
if lBestellung = null then
  let lLieferzeit := lLieferant.'Lieferzeit (in Tagen)';
  let lDauer := appointment(now(), now() + lLieferzeit * 86400000);
  var lBestellung := (create Lieferantenbestellung);
  lBestellung.(Lieferant := lLieferant);
  lBestellung.(Lieferzeit := lDauer);
  lBestellung.(Status := 1)
end;

// Ermittle den ersten Posten mit der passenden Produktzuordnung
let lPosten := first(lBestellung.Posten[Lieferantenprodukt = lProdukt]);

// Wenn es noch keinen Posten mit der Produktzuordnung gibt, dann erstelle einen neuen Posten
if lPosten = null then
  var lPosten := (create 'Lieferantenbestellung (Posten)');
  lPosten.(Lieferantenbestellung := lBestellung);
  lPosten.(Lieferantenprodukt := lProdukt)
end;

// Aktualisiere die zu bestellende Anzahl.
lPosten.('Anzahl bestellt' := lGap)

Was ist das Problem?

* Wenn es keine Bestellung im Status "Entwurf" gibt, dann wird sie korrekt erzeugt & dem Lieferanten zugeordnet.

* Wenn es noch keinen passenden Posten in der Bestellung gibt, wird der Posten erzeugt.

* In dem Posten wird die Bestellung nicht gespeichert. Die Referenz ist leer.

* In dem Posten wird die Anzahl nicht gespeichert. Das Feld ist leer.

Bildschirmfoto 2018-12-21 um 08.09.06

Vermutung: Für mich sieht es nach einer Race-Condition aus. Wenn die Bestellung über das Script erzeugt wird (vorher also nicht existiert hat), dann wird sie nicht zugeordnet. Existiert die Bestellung bereits, wird sie korrekt zugeordnet, allerdings die Anzahl nicht gesetzt.

Dass die Anzahl nicht gesetzt wird, macht mich stutzig. Es wirkt so, als ob es im Laufe des Scripts einen Fehler gab und dieser dafür sorgt, dass die nachfolge Anweisungen nicht mehr ausgeführt werden.

Habt ihr da eine Idee?

7 Antworten

null
    • bernd
    • vor 5 Jahren
    • Gemeldet - anzeigen

    die Verknüpfung mit eintragen: BES ist der Datensatz aus der Liefereantenbestellung. Bei welcher Tabelle wird der neue Datensatz erzeugt, Lieferantenbestellung oer Lieferant? Bei Lieferantenbestellung geht es dann so

    let BES := Nr;

    if lPosten = null then
      var lPosten := (create 'Lieferantenbestellung (Posten)');

      lPosten.Lieferantenbestellung := BES;

      lPosten.(Lieferantenbestellung := lBestellung);
      lPosten.(Lieferantenprodukt := lProdukt)
    end;

    • Torsten_Stang.1
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo,

     

    zur Frage "Dass die Anzahl nicht gesetzt wird, macht mich stutzig. Es wirkt so, als ob es im Laufe des Scripts einen Fehler gab und dieser dafür sorgt, dass die nachfolge Anweisungen nicht mehr ausgeführt werden.":

     

    Bin mir nicht sicher, aber ich denke die Variablen-Zuweisung inm then-Bereich der  if-Abfrage überlebt selbigen nicht. Ich würde den letzten Abschnitt wohl so ausführen:

    if lPosten = null then
      var lPosten := (create 'Lieferantenbestellung (Posten)');
      lPosten.(Lieferantenbestellung := lBestellung);
      lPosten.(Lieferantenprodukt := lProdukt);
      lPosten.('Anzahl bestellt' := lGap)
    else

       lPosten.('Anzahl bestellt' := lGap)
    end;

     

    lg, Torsten

    • indigo_boat
    • vor 5 Jahren
    • Gemeldet - anzeigen

    @Torsten Stang Hallo Torsten und Danke! Das hat tatsächlich funktioniert. Aber verstehen tue ich das nicht :/ Verstehe ich dich richtig, dass die erneute Zuweisung der Variable lPosten außerhalb des IF-Statements verloren geht? D.h. Die Anweisung var lPosten := (create 'Lieferantenbestellung (Posten)'); ist innerhalb des IF-Statements gültig und außerhalb nicht? Gruß Sergej

    • indigo_boat
    • vor 5 Jahren
    • Gemeldet - anzeigen

    @bernd@sas53.de Hallo Bernd und Danke für die schnelle Antwort. Hier bin ich leider noch nicht weiter gekommen. Ich hab mehrere Versionen ausprobiert, aber es klappt nicht. Zunächst einmal eine Verständnisfrage:

    1. lPosten.Lieferantenbestellung := BES;

    2. lPosten.(Lieferantenbestellung := lBestellung);

    BES ist eine ID, richtig? Müsste die Zuweisung unter 1. dann vielleicht lauten: lPosten.Lieferantenbestellung.Id := BES; ?

    1 & 2 sehen für mich aus, als ob zwei redundante Zuweisungen sind. Unter 1. wird eine Id zugewiesen / unter 2. ein Objekt. Oder stehe ich auf dem Schlauch.

     

    Könnte es sein, dass sich hier der gleiche Effekt auswirkt wie bei var lPosten := (create 'Lieferantenbestellung (Posten)');? Ich mache eine Zuweisung, diese hat aber außerhalb des IF-Statements scheinbar keine Gültigkeit? Das selbe würde für die Bestellung zutreffen. Wenn das so ist, sieht das für mich nach einem Bug aus.

     

    Gruß Sergej

    • Torsten_Stang.1
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Sergej,

     

    freut mich - und ja. ;-)

     

    Die Zuweisung geht nicht verloren - let lPosten := first(lBestellung.Posten[Lieferantenprodukt = lProdukt]) gilt weiterhin, ist wohl aber leer, weil Deine if-Abfrage ja sonst nicht gegriffen hätte. In meinem Beispiel wird im then-Bereich (create 'Lieferantenbestellung (Posten)') bedient, im else-Bereich eben das noch gültige first(lBestellung.Posten[Lieferantenprodukt = lProdukt]).

     

    lg, Torsten

    • Torsten_Stang.1
    • vor 5 Jahren
    • Gemeldet - anzeigen

    noch eine kurze Anmerkung, Du kannst die Variablen-Zuweisung auch direkt bedingt ausführen, z.B.

     

    let myCNT := count(lBestellung.Posten[Lieferantenprodukt = lProdukt]);
    let lPosten := if myCNT = 0 then (create 'Lieferantenbestellung (Posten)') else first(lBestellung.Posten[Lieferantenprodukt = lProdukt]) end;

     

    bei allen folgenden Zuweisungen bedient er sich dann mit "lposten" der bedingten Datensatz-ID...

     

    lg, Torsten

    • bernd
    • vor 5 Jahren
    • Gemeldet - anzeigen

    die Datensatz-ID werden bei Ninox im Feld Nr gespeichert.

    Die Tabelle 'Lieferantenbestellung (Posten)' ist ja eine Untertabelle von 'Lieferantenbestellung'. Entscheidend ist jetzt, in welcher Tabelle der Skript zur Erzeugung der ...(Posten) steht...

    welche Tabelle ist es?

Content aside

  • vor 5 JahrenZuletzt aktiv
  • 7Antworten
  • 2225Ansichten