Anpassung Auftragsformular

4. Mai 2012 10:58

Hallo,
Ich bin noch relativ neu im Fach, und soll für die Kasse das Auftragsformular anpassen und enorm vereinfachen.
Da es in der SalesTable wohl mit die meisten Verknüpfungen gibt, werde ich eine Copy des Forms SalesTable erstellen.

In der "RUN()" habe ich gleich als erstes
Code:
salesTable_ds.create
eingetragen, damit gleich beim öffnen ein neuer Datensatz erstellt wird. Jetzt habe habe ich aber überhaupt keinen Plan, wie ich das SalesCreateOrder-Form umgehen kann. Da die hier erforderlichen Eingaben, bis auf Bestandskunden mit eigenem Kundenkonto und die Zahlungsart immer gleich sind, werde ich die übrigen Felder hart eintragen. Die Wechselfelder werden dann im Kopf des Auftragsformulares mit angezeigt.
Die Positionen werden danach dann auch angepasst und mit einer Suchmaske versehen.

Das eigentliche Problem ist halt, wo kann ich das eintragen, wenn das Formular von der Copy aus gestartet wird (das Original muss selbstverständlich funktionsfähig bleiben) ?

Re: Anpassung Auftragsformular

4. Mai 2012 21:19

Hallo!

Ersteinmal schön zu sehen, dass es in LG noch andere Dynamics AX Programmierer gibt. :-)

Ich wollte auch gerne weiterhelfen, aber ich habe leider gerade keine AX Instanz im Zugriff, da ich im Urlaub bin. Wenn
Montag in einer Woche noch Fragen offen sind, kann ich gern versuchen ein paar Tipps zu geben.

Viele Grüße,
Claas Heinrich

Re: Anpassung Auftragsformular

7. Mai 2012 09:50

Hallo,

AndreasLG hat geschrieben:...soll für die Kasse das Auftragsformular anpassen und enorm vereinfachen....

ich würde heir eine neue Form erstellen und nicht mit einer Kopie der originalen Form zu arbeiten. Die SalesTable Form im Standard ist doch schon recht komplex.

Nimm doch einfach eine neue Maske und füge die benötigten DataSources (Tabellen) hinzu.
Welche das genau sind, kannst du ja bei der SalesTable Form sehen. Wenn es ganz "einfach" sein soll, brauchst du auch nur die Tabellen SalesTable, SalesLine und InventDim.

Für den Aufruf der "neuen" Maske braucht nur ein neues MenuItem angelegt werden. Diese kann dann ins Menü als neuer Menüpunkt eingebunden werden.

Re: Anpassung Auftragsformular

8. Mai 2012 10:30

Das mit dem neuen Form ist ja doch der einfachste Weg, Danke.

Allerdings habe ich jetzt trotzdem noch ein paar Fragen.
Obwohl ich ich die Eigenschaften der SalesLine in den DataSources folgendermasse gesetzt habe:
CounterField: LineNum
DelayActive: No
Index: SalesLineIdx
InsertAtEnd: No
InsertIfEmpty: No
JoinSource: SalesTable
LinkType: InnerJoin
bekomme ich im Grid SalesLine alle vorhanden Positionen angezeigt. Was muss man da ändern, damit nur der erste neue D(leere) Datensatz angezeigt wird.
Dazu muss ich wohl noch sagen, dass ich in der RUN nach dem super() salesTable_ds.create(true); eigefügt habe,
in der INIT: numberSeq = NumberSeq::newGetNumFromCode(SalesParameters::numRefSalesId().NumberSequence, true);
ANr = numberSeq.num();
accountNum = "100007";
Kundenname.text(CustTable::find(accountNum).Name);
und die Auftragsnummer, AccountNr und den Kundenname mittels Displaymethode in die Felder der SalesTable eingetragen habe. Aber display scheint wohl nicht der richtige Weg zu sein, da Der Wert noch nicht richtig übernommen wird (angezigt ja).

Re: Anpassung Auftragsformular

14. Mai 2012 22:04

Zum erstellen eines neuen Auftrags (Datensatz in Tabelle "SalesTable") musst du in der "Run" Methode der DataSource einen etwas anderen Code verwenden.

Damit das Gänze funktioniert musst du zuerst einen neuen Auftragskopf in der Tabelle SalesTable anlegen.
Mit "SalesTableDatasource.create" kannst du das so nicht machen.

Wirf bitte mal einen Blick auf meinen Blog. Dort findest du entsprechenden Code, welcher einen neuen Auftragskopf erzeugt.http://blog.ak-home.net/PermaLink,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx

In dem Beispielcode brauchst du nur die Salesline Aufrufe ignorieren.

Bitte aber auch das Thema nummernkreise beachten, um nicht unnotig viele Nummern zu "verschwenden".

Weiterhin musst du noch den erzeugten Auftragskopf in die Maske Laden. Sollte am besten funktionieren, wenn du dir die id oder die Record merkst und die Query der Datasource (salestable) entsprechend manipulieren um nur diesen Datensatz in die Maske zu Laden.

Re: Anpassung Auftragsformular

18. Mai 2012 10:21

Ich bin noch voll am basteln.
Ich versuche es nun auf dem Weg, über eine Hilfstabelle die benötigten Artikel schon im vorab abzufangen. Diese trage ich dann entsprechend gemeinsam mit dem Auftragskopf ein.

Eine Fehlermeldung kam, wenn ich Deine numberSeq ausführen wollte.
Mit:
Code:
numberSeq = NumberSeq::newGetNumFromCode(SalesParameters::numRefSalesId().NumberSequence, true);

konnte ich den Fehler beheben.
In Deiner Anweisung stand:
Code:
NumberSeq = NumberSeq::newGetNumFromCode(SalesParameters::numRefSalesId().numberSequence);

Re: Anpassung Auftragsformular

21. Mai 2012 12:16

Aktuell schlage ich mich mit 2 Problemen herum, wo ich ein Paar Tips gebrauchen könnte.

1. Die festen Werte trage ich über die InitValue der Tabelle ein. Das funktioniert auch soweit ganz gut, inklusive der Staffelpreise. Nur mit der SalesId hab ich meine Schwierigkeiten. Wie kann ich den Nummernkreis ziehen. In der InitValue geht das ja nicht, da für jede Position eine neue Nummer gezogen würde.
Derzeit habe ich den sicher etwas unschönen Weg versucht, den Nummernkreis in der Init des Formulares zu ziehen, und mittels Display anzeigen zu lassen. Den Wert kann ich beim eintragen in die SalesTable ja aus der ValueStr des Feldes nehmen.
Da gibt es doch bestimmt noch einen besseren Weg?

2. Die LineNum funktioniert auch noch nicht wie gewünscht. Wenn ich die <Pfeiltaste NachUnten> betätige, bekomme ich die neue ganze (Real) Zahl richtig ausgegeben. Wenn ich aber das Icon <NEU> betätige, wird der neue Datensatz oberhalb des aktuellen Datensatzes eingefügt und bekommt eine absteigende Nummer, wenn ich auf dem ersten Datensatz stand wird eine -1 ausgegeben.
Ich nehme mal an, das dies auch mit der fehlenden SalesId zusammenhängen könnte, und ich die Methode CreateLine aus der Tablle SalesLine dann entsprechend umarbeiten muß?

Re: Anpassung Auftragsformular

22. Mai 2012 11:44

AndreasLG hat geschrieben:1. Die festen Werte trage ich über die InitValue der Tabelle ein. Das funktioniert auch soweit ganz gut, inklusive der Staffelpreise. Nur mit der SalesId hab ich meine Schwierigkeiten. Wie kann ich den Nummernkreis ziehen. In der InitValue geht das ja nicht, da für jede Position eine neue Nummer gezogen würde.Derzeit habe ich den sicher etwas unschönen Weg versucht, den Nummernkreis in der Init des Formulares zu ziehen, und mittels Display anzeigen zu lassen. Den Wert kann ich beim eintragen in die SalesTable ja aus der ValueStr des Feldes nehmen.Da gibt es doch bestimmt noch einen besseren Weg?


Hmm.. es gibt hier mehrere Möglichkeiten. Ich denke es wäre aber gut, wenn du dich an dem orientierst, wie es auch der Standard für die SalesTable (Form) macht.

Zuerst brauchts du als DataSource die Tabelle "SalesTable" und nicht nur die Tabelle "SalesLine" (Bitte auch an das setzen der Links, etc für die DataSources denken...).
In der INIT-Methode der Form erzeugst du dann einen neuen "SalesTable" Datensatz. Wenn du das machst, wird dieser aber gleich in der Datenbank angelegt. Wenn du das nicht möchtest, musst du die Datasource mittels "settmp" auf Temporär setzen. Du musst auch noch ein paar methoden der SalesTable datasource überschreiben um die SalesId aus dem Nummernkresi zu beziehen. Erklärt wird das ganze hier.
Der Standard von AX macht es eigentlich genau so.

Bei den SalesLines musst du, denke ich, auch mit settmp arbeiten, damit diese nicht beim erzeugen einer neuen Position gleich in die Datenbank geschrieben werden, sondern erst wenn der Auftrag "fertig" ist.
Hierfür wird aber ein wenig Handarebit notwendig sein, da du zuerst den temporären SalesTable datensatz in der Datenbank speiechren musst und anschließend alle Datensätze der temporären SalesLine.

Wegen der LineNum solltest du dann erst einmal sehen, ob diese richtig funktioniert, wenn die Nummernkreise richtig "gezogen" werden.

Re: Anpassung Auftragsformular

27. Mai 2012 07:22

Zur Zeit muss ich erst einmal noch etwas anderes machen. Danach geht es aber wieder weiter.

Ich habe eine Hilfstabelle erstellt, in welche ich alle benötigten Felder aus der SalesTable und der SalesLine gezogen habe, um dann beim Buchen des Auftrages alle Positionen in den Auftrag schreiben zu können.

Wenn ich in meinem Formular z.B. die Artikelnummer auswähle, soll auch der (Staffel)Preis und der Artikelname in die Hilfstabelle geschrieben und im Formular angezeigt werden. Der Klick auf den PFEIL und Auswahl der Artikelnummer löst die Überschreibmethode des Formularfeldes aber noch nicht aus. Um das zu erreichen, müsste ich erst noch z.B. in das Feld klicken. Auch mit der LostFocus-Methode müsste ich das Feld für die Aktualisierung erst noch verlassen.
Welche Methoden könnte man da am besten nutzen?

Das nächste Problem wird dann ein Rundungsproblem.
Wenn ich einen Artikel zum Nettopreis von 1,76 € habe, wird der mit 2,09 € Brutto im Geschäft ausgepreist. Wenn dann ein Kunde 10 Stück kauft, wird aber statt 20,90 € ein Positionspreis von 20,94 € ausgegeben. Das bringt natürlich immer Rückfragen.
Wie kann ich es per Code bewerkstelligen, dass ich beim Buchen in die SalesTable gleichzeitig mitteile, das mit dem BruttoEinzelStückpreis gerechnet wird (wurde)?

Re: Anpassung Auftragsformular

3. Juni 2012 13:49

Hi,

AndreasLG hat geschrieben:Ich habe eine Hilfstabelle erstellt, in welche ich alle benötigten Felder aus der SalesTable und der SalesLine gezogen habe, um dann beim Buchen des Auftrages alle Positionen in den Auftrag schreiben zu können.


das würde ich nicht mit einer Hilftabelle, sondern einer temporären Instanz der SalesTable und SalesLine lösen, welche erst nur im Speicher gehalten wird und "beim Buchen" in die Datenbank geschrieben wird.
Mit diesem Weg brauchst du weniger Code schreiben, da du vieles aus dem Standard übernehmen kannst (Bsp. Lagerdimensionen...).

AndreasLG hat geschrieben:Wenn ich in meinem Formular z.B. die Artikelnummer auswähle, soll auch der (Staffel)Preis und der Artikelname in die Hilfstabelle geschrieben und im Formular angezeigt werden.


Das kannst du aus dem Standrad-Formular "abgucken". Einfach eine Methode des Feldes für die Artikelnummer auf Ebene Datasource oder Control überschreiben und die Preisfindung aufrufen.

AndreasLG hat geschrieben:Das nächste Problem wird dann ein Rundungsproblem.Wenn ich einen Artikel zum Nettopreis von 1,76 € habe, wird der mit 2,09 € Brutto im Geschäft ausgepreist. Wenn dann ein Kunde 10 Stück kauft, wird aber statt 20,90 € ein Positionspreis von 20,94 € ausgegeben. Das bringt natürlich immer Rückfragen.Wie kann ich es per Code bewerkstelligen, dass ich beim Buchen in die SalesTable gleichzeitig mitteile, das mit dem BruttoEinzelStückpreis gerechnet wird (wurde)?


Ja, hier kommt es drauf an, was du wie machst. :-( Es kommt halt drauf an, wie du von Netto zu Brutto kommst bzw. wie du die Bruttopreise berechnest.
Wenn du dies mittels der Mehrwertsteuereinstellungen von a) Artikel und b) Kunde durchführst sollte es eigentlich keine Rundungsprobleme geben.

Diesen Teil kannst du dir aber z.B. bei dem Report der Auftrags-Rechnung ansehen. Je nach Steuereinstellungen (Mehrwertsteuergruppe von Artikel und Kunde) wird hier ja auch der richtige Bruttopreis ausgerechnet.

Re: Anpassung Auftragsformular

4. Juni 2012 17:49

Jetzt habe ich nochmal angefangen mit einem neuen Form. SalesTable, SalesLine und InventDim als Datasource hinzugefügt.

SalesTable: Index: IndexIdx, Startposition: Last.

SalesLine: Counterfield: LineNum, DelayActive: No, Index: SalesLineIdx, InsertAtEnd: No, InsertIfEmpty: No, JoinSource: SalesTable, LinkType: InnerJoin.

InventDim: DelayActive: No, InsertAtEnd: No, InsertIfEmpty: No, JoinSource: SalesLine, LinkType: InnerJoin.


In den Methoden des Formulares:

in ClassDeclaration Formhandler deklariert.

numberSeqFormHandler und close eingefügt.


In den Methoden DataSources:
--- SalesTable: create, delete, validateWrite, write und linkActive erstellt für NumberSeqHandler lt.Beschreibung.
- in der init(): salesTable.setTmp() vor dem super()
- in der initValue() alle mandatory-Felder und Defaultwerte gesetzt (noch ohne doInsert())

---SalesLine: in der init(): SalesLine.setTmp() vor dem Super()
- in der initValue() alle mandatory-Felder und Defaultwerte gesetzt (noch ohne doInsert())

Ab hier fängt der Spass schon an. Wenn ich das Formular schliesse, kommt folgende Fehlermeldung:

Warning Meldung (17:14:24) Die Bestellung wurde gelöscht.
Warning Meldung (17:14:24) Abweichung zwischen Währungscode in der Auftragsposition und im Auftragskopf.

In beiden Währungsfeldern steht aber der Euro drin?!?

Die salesId ist ja in den Positionen noch nicht bekannt. Also habe ich in der classDeclaration des Formulares die SalesId hinzugefügt.

In der Create() der DataSource SalesTable habe ich deshalb:

salesId = element.numberSeqFormHandler().lastUncommitedNumber();
salesLine.SalesId = salesId;

hinzugefügt. Die Fehlermeldung bleibt nach wie vor bestehen. Irgendetwas wichtiges scheine ich zu übersehen. Ein guter Tip wäre sehr hilfreich.

Und vielen Dank für Deine bisher geopferte Zeit und Hilfe.

Re: Anpassung Auftragsformular

4. Juni 2012 17:56

Hi,

ich werde mir das mal "nachbauen". So spontan kann ich dir leider nicht direkt sagen wo des problem liegt. :-)
Werde aber eine entsprechende Antwort posten, wenn ich deinen Fall mal nachgestellt habe......

Re: Anpassung Auftragsformular

30. August 2012 15:20

Jetzt kam ich endlich wieder dazu, an dem Formular weiter zu arbeiten.
Ich habe je 1 Tabelle für Kopf und Positionen neu erstellt, und ein Formular mit Unterformular dazu.
Jetzt habe ich Probleme beim übertragen in SalesTable und SalesLine.

Wie in Deiner Antwort vom 14.Mai beschrieben
http://blog.ak-home.net/PermaLink,guid,5f347b6a-f6b2-4343-af0c-27d517219f18.aspx
will ich nun meine Daten Übertragen. Solange ich nur 1 Position übertrage funktioniert es gut. Sobald ich 2 oder mehr Positionen einfügen möchte, kommt info"Artikelnummer kann nicht geändert wenn, wenn Artikelbuchungen generiert wurden. Position löschen und mit neuer Artikelnummer neu erstellen." error"Aktualisierung wurde storniert."

Nach dem Eintragen in die SalesTable, musste ich für die Positionen den Code abändern, da ich sonst den Datensatz doppelt - mit Standardwerten und mit meine Daten in der SalesLine hatte.

while select * from meinePosTabelle
order by meinePosTabelle.LineNum
where meinePosTabelle.SalesId == _salesId
{
if (meinePosTabelle)
{
salesLine.clear();
1. meine Daten holen
2. salesLine.SalesId = _salesId;
3. salesLine.ItemId = _itemId;
4. SalesLIne.createLine/true,true,true,true,true,true);
5. meine Feldzuweisungen
6. salesLine.update();
}
}

Wie gesagt, mit einer Position klappt alles wie gewünscht, auch das Buchen. Bei mehreren Positionen gibte es den Fehler.

Muss ich da noch etwas beachten?

Re: Anpassung Auftragsformular

7. September 2012 08:39

eines der Felder in der inventTableModule war wohl nicht richtig gefüllt. Jetzt funktioniert das ganze jedenfalls genau wie gewünscht.

Re: Anpassung Auftragsformular

10. September 2012 20:12

Wie sieht deine Lösung denn jetzt genau aus?
Verwendest du jetzt neue Tabellen (Einer Kopfdaten, eine für Positionsdaten)?

Könntest du bitte auch das Thema auf gelöst stetzen, wenn es gelöst ist?

Re: Anpassung Auftragsformular

14. September 2012 14:39

Komplett gelöst ist das ganze noch nicht. Da ich nur selten Zeit habe, an diesem Formular weiter zu arbeiten, und auch noch nicht alle Vorgaben vollends geklärt sind wird die Vollendung noch etwas dauern.

Die Hauptaufgabenstellung war ja, das das Formular ohne das SalesCreateOrderForm funktionieren soll, und ein Großteil der Felder über eine Parametertabelle gefüllt wird. An der Geschäftskasse hilft das sehr viel Zeit zu sparen.
Als nächstes sollen noch ein paar Button dynamisch eingefügt werden, für häufig verkaufte Artikel. (Klick und der Artikel soll in den Positionen eingefügt werden - ohne Suche im Nachschlagefeld der ItemId) Das wird aber erst noch durchgesprochen.

Ich habe je eine Tabelle für den Auftrag und die Positionen angelegt. In denen werden nur die Gleitdaten aufgefangen. Wenn dann festeht, wieviel Artikel gekauft wurden, wird über den Buchen-Rechnung-Button dann alles in die SalesTable und SalesLine übertragen und mit den Parameterdaten aufgefüllt. Je nachdem, welcher Button gedrückt wurde, wird dann auch der LS oder die Rechnung mit ausgedruckt.

Aber wie gesagt, noch ist nicht alles komplett gelöst und auch noch keine volle Systemintegrität getestet. Bin mal gespannt, wie das dann mit der Übergabe aus den dynamischen Buttons an die Positionstabelle wird.

Re: Anpassung Auftragsformular

27. November 2012 11:54

So langsam neigt sich das Projekt dem Ende entgegen. Die Dynamischen Buttons funktionieren auch super. Allerdings habe ich noch 2 Problem zu lösen.

1. Wenn der Auftrag gebucht wird, wird er in SalesTable und SalesLine geschrieben. Dazu ziehe ich mir aus dem Nummernkreis die Auftragsnummer:

NumberSeq numberSeq;
SysLastValue nextNumSeq;
Num generatedNumber;
;

if(!PPC_CashRegisterTable.SalesId)
{
nextNumSeq.Value = connull();
numberSeq = NumberSeq::newGetNumFromCode(SalesParameters::numRefSalesId().NumberSequence, true, false, nextNumSeq, true);
if(numberSeq)
{
[generatedNumber] = nextNumSeq.value;
}
und schreibe diese zuerst in meine Hilfstabelle. Funktioniert soweit auch. Allerdings, wenn ich das Projekt, oder AOS kompiliere, bekomme ich Auftragsnummern geliefert, die schon vergeben sind. Es sind dies immer die gleichen Nummern, und zwar die, die zu Beginn meines Projektes damals frei waren. Mittlerweile sind schon über 100 Aufträge gebucht und ich muss dann diese ganzen Nummern einzeln durchbuchen bis ich bei der nächsten freien Nummer ankomme. Dann gehts (erstmal) wieder. Kann man da was machen?

2. Wenn Auftragsbestätigung, Lieferschein oder Rechnung gebucht werden, sollen z.B. 2 Kopien der Rechnung automatisch gedruckt werden.
salesTable = SalesTable::find(_salesId);

salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice);

salesFormLetter.update(salesTable, SystemDateGet(), SalesUpDate::All,
AccountOrder::None, NoYes::No, NoYes::Yes);

printJobSettings.deviceName(printer);
printJobSettings.setTarget(PrintMedium::Printer);
printJobSettings.copies(2);
printJobSettings.getPrinter(1);

if( !printIt)
{
return; // Benutzerabbruch
}

salesFormLetter.updatePrinterSettingsFormLetter(printJobSettings.packPrintJobSettings());

select firstOnly custInvoiceJour
where custInvoiceJour.salesid == _salesId;

args.record(custInvoiceJour);
args.caller(salesFormLetter);

Funktioniert alles super. NUr die Druckvorschau bekomme ich noch nicht ausgeschaltet. Wie macht man das am besten?

Re: Anpassung Auftragsformular

30. November 2012 22:15

AndreasLG hat geschrieben: Allerdings, wenn ich das Projekt, oder AOS kompiliere, bekomme ich Auftragsnummern geliefert, die schon vergeben sind. Es sind dies immer die gleichen Nummern, und zwar die, die zu Beginn meines Projektes damals frei waren.


Hast du schon die Einstellungen des Nummernkreises überprüft?

Klingt so, als wäre mit der Einrichtung des Nummernkreises was nicht ok. Ggf. hat er diese Nummern als "freie Nummern" registriert.

Ich würde 2 Versuche durchführen.
    1. Verwendung eines neuen Nummernkreises um zu sehen wie es damit Funktioniert. Ist das Ok, sollte es an den Einstellungen des orginalen Nummernkreises liegen.
    2. Überprüfen der Einstellungen des "orginalen" Nummernkreises.

Re: Anpassung Auftragsformular

7. Dezember 2012 09:35

Der Nummernkreislauf läuft im Auftragsformular korrekt.
Der Originalnummerkreis steht auf 5000. bei mir war er dann auf 4900 zurückgerutscht. Wenn ich in meinem Formular dann wieder einen Auftrag buche, wird mir die 4901 ausgegeben, usw. Wenn ich dann die nächste freie Nummer erreicht habe, geht auch alles ok.
Gestern hatte ich im Testlauf einen Auftrag gebucht, der nicht validiert werden konnte. Auftrag konnte nicht gebucht werden... Daraufhin war meine nächste SalesId wieder auf 4900. Das Problem scheint also an anderer Stelle zu liegen.
Jetzt habe ich das Problem so (Teil) gelöst, in dem ich in der Funktion, wo ich die SalesId generiere, einen select auf die SalesId der SalesTable mache. Wenn die generatedNumber <= SalesTable.SalesId ist, dann rufe ich die Funktion erneut auf.
Somit bekomme ich jedenfalls die nächste freie ID auch wenn zwischenzeitlich ein Auftrag am Originalformular gemacht wurde, und kann den Auftrag in die SalesTable schreiben und buchen. Aber ich glaube, das des Rätsels Lösung doch noch an einer anderen Stelle zu finden ist.

Hast Du evtl. auch noch eine Antwort auf die Frage, wie ich die Druckvorschau der salesFormLetter ausschalten kann?

Re: Anpassung Auftragsformular

20. Februar 2013 09:15

Jetzt ist alles soweit gelöst. Noch ein paar kleine Anpassungen und das Projekt kann Live gehen.

Re: Anpassung Auftragsformular

20. Februar 2013 10:48

AndreasLG hat geschrieben:Jetzt ist alles soweit gelöst. Noch ein paar kleine Anpassungen und das Projekt kann Live gehen.


Super! Ich drück dir die Daumen!
Ich sitz selber hier vor AX 2009 :-)