...feel the spirit of Microsoft Dynamics AX RSS 2.0
 Saturday, April 12, 2008

Das Erstellen von Produktionsaufträgen sollte an sich kein Problem darstellen. Leider ist dem nicht ganz so.

Anders als in anderen Modulen (z.B. Aufträge) von Dynamics AX, existiert hierfür keine Klassenstruktur, welche die entsprechenden Funktionen bereit stellt.
Der Dynamics AX Standard erstellt Produktionsaufträge immer über die Maske „ProdTableCreate“. Es gibt aber Situationen, wo für die Erstellung eines Produktionsauftrages keine Maske verwendet werden kann. Ein Beispiel hierfür könnte eine Schnittstelle sein, welche über eine Textdatei die zu produzierenden Waren einließt und entsprechende Produktionsaufträge im System generiert.

Die Frage ist nun, wie erstellt man Produktionsaufträge per Quellcode, damit diese auch „richtig“ im System erzeugt werden (inkl. Stückliste, Arbeitsplan und Lagerbuchung).

  • Zuerst muss der Produktionsauftrag mit den Daten des zu produzierenden Artikels initialisiert werden.
  • Weiterhin müssen Produktionsmenge und Lieferdatum festgelegt werden.
  • Ebenfalls sind die zu verwendende Stückliste und der Arbeitsplan zu definieren.
  • Und als letzter Schritt muss der Produktionsauftrag noch erzeugt werden.

Hierbei gilt es aber zu beachten, dass die Erstellung (Speichern in der Datenbank) nicht mit der Methode „insert“ der Tabelle „ProdTable“ geschieht, sondern dass hierfür die Klasse „ProdTableType“ und deren Methode „insert“ verwendet wird. Nur so wird die entsprechende Lagerbewegung / Lagerbuchung im System erzeugt und wenn notwendig Referenzen zu einem Verkaufsauftrag oder einer anderen Produktion hinterlegt.

Um dies zu veranschaulichen ein kurzes Beispiel, in welchem ein neuer Produktionsauftrag erstellt wird.

static void CreateProductionOrder(Args _args)
{
    //Die zu produzierende Menge
    ProdQtySched productionQty = 1;
    //Der zu produzierende Artikel
    ItemId productionItem = "Artikelnummer";

    ProdTable prodTable;
    InventTable inventTable;
    ;
    inventTable = InventTable::find(productionItem);

    //Initialisierung des Produktionsauftrags
    prodTable.initValue();
    prodTable.ItemId = inventTable.ItemId;
    prodTable.initFromInventTable(inventTable);

    //Lieferdatum festlegen
    prodTable.DlvDate = today();

    prodTable.QtySched = productionQty;
    prodTable.RemainInventPhysical = prodTable.QtySched;

    //Die zu verwendende Stückliste und Arbeitsplan bestimmen
    prodTable.initRouteVersion();
    prodTable.initBOMVersion();

    //Produktionsauftrag erstellen
    prodTable.type().insert();
}

Selbstverständlich sind auch weitere Angaben bei der Erstellung des Produktionsauftrags möglich.
Z.B. kann ein Produktionsauftrag auch aus einer Verkaufsauftragsposition erzeugt werden (bei Verwendung der Methode "initFromSalesLine").

Saturday, April 12, 2008 2:30:59 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 |  | 

 Saturday, January 26, 2008

Das Buchen von Bestellungen in Microsoft Dynamics AX geschieht über die Klasse „PurchFormLetter“ bzw. einer ihrer konkretisierten (abgeleiteten) Klassen. Jeder Buchungstyp (z.B. Bestätigung oder Rechnung) ist durch eine eigene Klasse abgebildet, welche von der Basisklasse „PurchFormLetter“ abgeleitet ist (siehe Abbildung).

Abbildung 1 - Klassenhierarchie der Klasse „PurchFormLetter“

Vergleicht man die Klassenhierarchie der „PurchFormLetter“ Klassen mit der Klassenhierarchie der „SalesFormLetter“ Klassen, so ist zu erkennen, dass auch das Buchen von Bestellungen vom Prinzip her genau so funktioniert wie das Buchen von Aufträgen (Vergleiche hierzu: Microsoft Dynamics AX API – Teil 3 „Buchen von Aufträgen“).

Deswegen sind auch für das Buchen von Bestellungen im Wesentlichen nur zwei Schritte notwendig.

  1. Über die Methode „construct“ der Klasse „PurchFormLetter“ ein dem Buchungstyp einsprechendes Objekt erzeugen.
  2. Über den Aufruf der Methode „update“ die Bestellung buchen.

Hierzu ein Beispiel (Buchen des Lieferscheins für eine Bestellung):

static void PurchPostPackingSlip(Args _args)
{
   PurchFormLetter purchFormLetter;
   PurchTable purchTable;
   PurchId purchId;
   Num packingSlipId;
   ;
   //Angabe der Bestellung, für welche der Lieferschein gebucht werden soll.
   purchId = "00244_049";
   purchTable = PurchTable::find(purchId);

   //Bestimmen des Buchungstyps durch Angabe des DocumentStatus (Lieferschein).
   purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);

   //Festlegen der externen Lieferscheinnummer.
   packingSlipId = "EXT-100155L";

   //Buchen des Lieferscheins.
   purchFormLetter.update(purchTable,
                          packingSlipId,
                          SystemDateGet(),
                          PurchUpdate::All,
                          AccountOrder::Auto,
                          NoYes::No,
                          NoYes::No,
                          NoYes::No,
                          NoYes::No);
}

Einziger Unterschied zu den Auftragsbuchen ist, dass bei der Buchung einer Bestellung die „externe“ Nummer des Belegs (Lieferscheinnummer, Rechnungsnummer, etc.) angegeben werden muss.

Analog zu den Auftragsbuchen, sind auch beim Buchen von Bestellungen umfangreichere oder etwas speziellere Buchungsszenarien möglich (Vergleiche hierzu: Microsoft Dynamics AX API – Teil 3 „Buchen von Aufträgen“).

Saturday, January 26, 2008 3:12:18 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 | 

 Thursday, October 25, 2007

Das Buchen von Aufträgen in Microsoft Dynamics AX geschieht über die Klasse „SalesFormLetter“ bzw. einer ihrer konkretisierten (abgeleiteten) Klassen. Jeder Buchungstyp (z.B. Bestätigung, Lieferschein, Rechnung) ist durch eine eigene Klasse abgebildet, welche von der Basisklasse „SalesFormLetter“ abgeleitet ist (siehe Abbildung).

Um einen Auftrag per Programmcode zu buchen, muss ein Objekt der Klasse „SalesFormLetter“ erstellt werden.

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

Dies geschieht, wie Allgemein in Microsoft Dynamics AX üblich, über die “construct” Methode der Klasse. Als Parameter muss dieser Methode die gewünschte Art der Buchung (z.B. Bestätigung, Lieferschein, Rechnung) angegeben werden. Die „construct“ Methode erzeugt ein,der Buchungsart entsprechendes, Objekt und gibt dieses zurück (In diesem Fall wird ein „SalesFormLetter_Confirm“ Objekt erzeugt).
Die eigentliche Buchung wird über die Methode „update“ aufgerufen. Da dieser Methode alle für die Buchung notwendigen Daten als Parameter übergeben werden können, ist eine einzelne Zuweisung von z.B. dem Auftrag, welcher gebucht werden soll, nicht notwendig.

Hierzu ein Beispiel:

// --- Buchen ohne Ausdruck ---
static void PostingConfimation(Args _args)
{
   SalesFormLetter salesFormLetter;
   SalesTable salesTable;
   SalesId salesId;
   PrintJobSettings printJobSettings;
   ;
   //Angabe des Auftrags, welcher gebucht werden soll.
   salesId = "00423_036";
   salesTable = SalesTable::find(salesId);

   // Bestimmen des Buchungstyps durch Angabe des DocumentStatus
   salesFormLetter = SalesFormLetter::construct(DocumentStatus::Confirmation);

   //Buchen des Auftrags (aber nicht Drucken).
   salesFormLetter.update(salesTable,
                          SystemDateGet(),
                          SalesUpdate::All,
                          AccountOrder::None,
                          NoYes::No,
                          NoYes::No);
}

Bei diesem Beispiel ist gut zu sehen, dass für die Buchung eines Auftrags im Wesentlichen nur zwei Schritte notwendig sind.

  1. Über die Methode „construct“ ein dem Buchungstyp einsprechendes Objekt erzeugen.

  2. Über den Aufruf der Methode „update“ den Auftrag buchen.

Natürlich können auch noch umfangreichere oder etwas speziellere Buchungsszenarien mit der Klasse „salesFormLetter“ abgebildet werden. So ist es z.B. möglich, gleich bei der Buchung entsprechende Dokumente auszudrucken (einmal, mehrfach und in verschiedene Formate), die Maske für die Buchung zu öffnen (damit der Benutzer Einfluss auf die Buchung nehmen kann) oder die Buchung nicht direkt auszuführen, sondern diese für die Stapelverarbeitung bereit zu stellen.

Damit es nicht zu komplex wird, kurz noch ein Beispiel zum Buchung und gleichzeitigen ausdrucken entsprechender Dokumente.

// --- Buchen mit Ausdruck ---
static void PostingConfimation(Args _args)
{
   SalesFormLetter salesFormLetter;
   SalesTable salesTable;
   SalesId salesId;
   PrintJobSettings printJobSettings;
   ;
   //Angabe des Auftrags, welcher gebucht werden soll.
   salesId = "00423_036";
   salesTable = SalesTable::find(salesId);
   salesFormLetter = SalesFormLetter::construct(DocumentStatus::Confirmation);

   //Buchen des Auftrags und drucken (Druckmedium aus Std. Einstellung).
   salesFormLetter.update(salesTable,
                          SystemDateGet(),
                          SalesUpdate::All,
                          AccountOrder::None,
                          NoYes::No,
                          NoYes::Yes);

   //2ter Ausdruck.
   printJobSettings = new PrintJobSettings(salesFormLetter.printerSettingsFormletter(
                                                           PrintSetupOriginalCopy::Original));
   //Wohin möchten wir drucken (hier Datei).
   printJobSettings.setTarget(PrintMedium::File);

   //In welches Format soll gedruckt werden (hier PDF).
   printJobSettings.format(PrintFormat::PDF);
   printJobSettings.fileName(@"C:\Test_Order.pdf");

   //Übergabe der Druckoptionen an das SalesFormLetter Objekt.
   salesFormLetter.updatePrinterSettingsFormLetter(printJobSettings.packPrintJobSettings());

   salesFormLetter.printJournal();
}

Thursday, October 25, 2007 6:45:14 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 | 

 Monday, September 03, 2007

Eine Bestellung umfasst in Microsoft Dynamics AX immer einen Datensatz der Tabelle „PurchTable“ und wenn die Bestellung einen Artikel enthält, auch einen Datensatz in der Tabelle „PurchLine“. Zusätzlich werden in Abhängigkeit von den Daten der Bestellung (Einmallieferant: Ja/Nein, Intercompany: Ja/Nein, etc.) zusätzliche Datensätze in anderen Tabellen erzeugt bzw. geändert. Beispielhaft sei hier die Tabelle „VendTable“ genannt. In dieser wird ein neuer Lieferant erstellt, wenn beim Erstellen der Bestellung angegeben wurde, dass es sich um einen Einmallieferanten handelt. Ein weiteres Beispiel wäre die Tabelle „MarkupTrans“ in der in Abhängigkeit von den Einstellungen für sonstige Zuschläge ebenfalls weitere Datensätze erzeugt werden.

Die Logik, die das Erstellen der einzelnen Datensätze der verschiedenen Tabellen steuert wird in Microsoft Dynamics AX durch die Klassen „PurchTableType“ (Abbildung 1) und „PurchLineType“ (Abbildung 2), sowie deren abgeleiteten Klassen abgebildet. Diese Klassen steuern das Verhalten bei Anlage, Änderung und Löschung einer Bestellung. Dies beinhaltet auch, welche Werte ein Feld bei welchem Bestellungstyp annehmen darf, was geschieht wenn ein Feld geändert wird, was wird wie gebucht und so weiter.

Diese Klassen werden von überschriebenen Methoden der Tabellen „PurchTable“ und „PurchLine“ aufgerufen. So ruft zum Beispiel die Methode „Insert“ der Tabelle „PurchTable“, die Methode „Insert“ der Klasse „PurchTableType“ auf. Abhängig vom Bestellungstyp wird über die Methode „construct“ bei der Initialisierung eines „PurchTableType“ Objekts gesteuert, welches konkrete Objekt erzeugt wird („PurchTableType_Purch“, „PurchTableType_ReturnItem“, etc.). Dies erfolgt in der Methode „type“ der Tabelle „PurchTable“ oder „PurchLine“. Unter anderem sind weiterhin die Methoden „Update“, „Delete“, „InitValue“, „ValidateField“ und „Delete“ auf die gleiche Weise überschrieben.
Ein Blick in die Methoden der Tabelle „PurchTable“ sollte dies verdeutlichen.

Somit ist die Logik, die für die Steuerung von Bestellungen in Microsoft Dynamics AX verantwortlich ist, vom Prinzip her vergleichbar mit der Logik welche die Aufträge „steuert“ (vergleiche hierzu: Microsoft Dynamics AX API – Teil 1 „Erstellen von Aufträgen“).

Deswegen ist das Erstellen einer Bestellung genau so einfach wie das Erstellen eines Auftrags. Um eine neue Bestellung zu erstellen muss im Wesentlichen nur:

  1. Eine neue Nummer des entsprechenden Nummernkreises gezogen werden.
  2. Die Methode „InitValue“ der Tabelle „PurchTable“ aufgerufen werden.
  3. Die Methode „InitFromVendTable“ der Tabelle „PurchTable“ mit Angabe des Lieferanten Datensatzes aufgerufen werden.
  4. Die Methode „Insert“ der Tabelle  „PurchTable“ aufgerufen werden.

Soll für diese gerade erzeugte Bestellung nun noch eine Artikelposition erzeugt werden, muss im Wesentlichen nur die Methode „CreateLine“ der Tabelle „PurchLine“, mit vorheriger Definition von Bestellungsnummer („PurchLine.PurchId“) und Artikelnummer („PurchLine.ItemId“), aufgerufen werden.

Hierzu ein Beispiel:

void createPurchTableAndLine()
{
   VendAccount vendAccount = "<yourVendAccount>";
   ItemId itemId = "<yourItemId>";

   PurchTable purchTable;
   PurchLine purchLine;
   NumberSeq numberSeq;
   InventTable inventTable;
   ;
   //Bestellungskopf (PurchTable)
   //Neue Bestellungsnummer aus Nummernkreis erzeugen
   NumberSeq = NumberSeq::newGetNumFromCode(
   PurchParameters::numRefPurchId().numberSequence);
   purchTable.PurchId = NumberSeq.num();

   //Bestellungskopf initialisieren
   purchTable.initValue();

   //Initialisierung der lieferantenspezifischen Bestellungsdaten
   purchTable.initFromVendTable(VendTable::find(vendAccount));

   //Bestellungskopf erstellen
   purchTable.insert();

   //Bestellungsposition (PurchLine)
   purchLine.clear();

   //Zuweisen von Bestellungsnummer und Artikelnummer
   purchLine.purchId = purchTable.PurchId;
   purchLine.ItemId = itemId;

   //Bestellungsposition erstellen (ruft PurchLine.insert auf)
   purchLine.createLine(NoYes::Yes, NoYes::Yes, NoYes::Yes,
                        NoYes::Yes, NoYes::Yes, NoYes::Yes);
}

Monday, September 03, 2007 8:02:32 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 | 

 Friday, August 17, 2007

Ein Auftrag umfasst in Microsoft Dynamics AX immer einen Datensatz in der Tabelle „SalesTable“ (Auftragskopf) und wenn der Auftrag einen Artikel enthält (Auftragsposition), auch einen Datensatz in der Tabelle „SalesLine“. Zusätzlich werden in Abhängigkeit von den Daten des Auftrags (Einmalkunde: Ja/Nein, Intercompany: Ja/Nein, etc.) zusätzliche Datensätze in anderen Tabellen erzeugt bzw. geändert. Beispielhaft sei hier die Tabelle „CustTable“ genannt. In dieser wird ein neuer Kunde erstellt, wenn beim Erstellen des Auftrags angegeben wurde, dass es sich um einen Einmalkunden handelt. Ein weiteres Beispiel wäre die Tabelle „MarkupTrans“ in der in Abhängigkeit von den Einstellungen für Sonstige Zuschläge ebenfalls weitere Datensätze erzeugt werden.

Die Logik, die das Erstellen der einzelnen Datensätze der verschiedenen Tabellen steuert (die so genannte Geschäftslogik) wird in Microsoft Dynamics AX durch die Klassen „SalesTableType“ (Abbildung 1) und „SalesLineType“ (Abbildung 2), sowie deren abgeleiteten Klassen abgebildet. Diese Klassen steuern das Verhalten bei Anlage, Änderung und Löschung eines Auftrags. Dies beinhaltet auch, welche Werte ein Feld bei welchem Auftragstyp annehmen darf, was geschieht wenn ein Feld geändert wird, was wird wie gebucht und so weiter.

Diese Klassen werden von überschriebenen Methoden der Tabellen „SalesTable“ und „SalesLine“ aufgerufen. So ruft zum Beispiel die Methode „Insert“ der Tabelle „SalesTable“, die Methode „Insert“ der Klasse „SalesTableType“ auf. Abhängig vom Auftragstyp wird über die Methode „construct“ bei der Initialisierung eines „SalesTableType“ Objekts gesteuert, welches konkrete Objekt erzeugt wird („SalesTableType_Sales“, „SalesTableType_ItemReq“, etc.).
Unter anderem sind weiterhin die Methoden „Update“, „Delete“, „InitValue“, „ValidateField“ und „Delete“ auf die gleiche Weise überschrieben. Ein Blick in die Methoden der Tabelle „SalesTable“ oder „SalesLine“ sollte dies verdeutlichen.

Somit gestaltet sich das Erstellen eines neuen Auftrags sehr einfach, da die gesamte Geschäftslogik die hinter einem Auftrag steht, automatisch aufgerufen wird.

Um einen neuen Auftrag zu erstellen muss im Wesentlichen nur

  1. Eine neue Nummer des entsprechenden Nummernkreises gezogen werden.
  2. Die Methode „InitValue“ der Tabelle „SalesTable“ aufgerufen werden.
  3. Die Kundennummer zugewiesen werden.
  4. Die Methode „InitFromCustAccount“ der Tabelle „SalesTable“ aufgerufen werden.
  5. Die Methode „Insert“ der Tabelle  „SalesTable“ aufgerufen werden.

Soll für diesem gerade erzeugten Auftrag nun noch eine Artikelposition erzeugt werden, muss im Wesentlichen nur die Methode „CreateLine“ der Tabelle „SalesLine“, mit vorheriger Definition von Auftragsnummer („SalesLine.SalesId“) und Artikelnummer („SalesLine.ItemId“), aufgerufen werden.

Hierzu ein Beispiel:

void createSalesTableAndLine()
{
   AccountNum custAccount = <yourCustAccount>;
   ItemId itemId = <yourItemId>;

   SalesTable salesTable;
   SalesLine salesLine;
   NumberSeq NumberSeq;
   ;
   //Auftragskopf (SalesTable)
   //Neue Auftragsnummer aus Nummernkreis erzeugen
   NumberSeq = NumberSeq::newGetNumFromCode(
   SalesParameters::numRefSalesId().numberSequence);
   salesTable.SalesId = NumberSeq.num();

   //Auftragskopf initialisieren
   salesTable.initValue();
   salesTable.CustAccount = custAccount;

   //Initialisierung der kundenspezifischen Auftragsdaten
   salesTable.initFromCustTable();

   //Auftragskopf erstellen
   salesTable.insert();

   //Auftragsposition (SalesLine)
   salesLine.clear();

   //Zuweisen von Auftragsnummer und Artikelnummer
   salesLine.SalesId = salesTable.SalesId;
   salesLine.ItemId = itemId;

   //Auftragsposition erstellen (ruft SalesLine.insert auf)
   salesLine.createLine(NoYes::Yes, NoYes::Yes, NoYes::Yes, NoYes::Yes,
                        NoYes::Yes, NoYes::Yes);
}

Friday, August 17, 2007 3:47:28 PM (Mitteleuropäische Zeit, UTC+01:00)  Axel Kühn  #    Comments [0] - Trackback
 | 



Translate
Über/Kontakt

     







© Copyright 2009 Axel Kühn
Sign In
Subscribe this blog
Archiv
<January 2009>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567
Statistik
Total Posts: 96
This Year: 0
This Month: 0
This Week: 0
Comments: 45





All Content © 2009, Axel Kühn
DasBlog theme 'Business' created by Christoph De Baene (delarou)