TriggerBusinessLayer
DatevFormatBuchungssatz
Dieses Ereignis wird beim Durchführen der Fibu-Ausgabe nach dem Erzeugen der Zeichenkette für jeden Buchungsdatensatz ausgeführt. Der Trigger 'DatevFormatBuchungssatz' kann im SDK dazu verwendet werden, die Buchungsdatensätze beim Exportieren der Daten aus der Fibu-Ausgabe inhaltlich zu ergänzen oder zu verändern.
LagerBuchung
Dieses Ereignis wird vor und nach einer manuellen oder automatischen Lagerbuchung ausgelöst. Die manuelle Lagerbuchung kann über die beiden Menüfunktionen 'Lager-Buchungen' und 'Lager-Bestand' ausgelöst werden. Automatische Lagerbuchungen werden beim Fertigmelden von Fertigungsaufträgen oder beim Erstellen von (Rück-)Lieferungen im Ein- und Verkauf durchgeführt, sofern in der Mandantenkonfiguration eingeschaltet, sowie in verschiedenen weiteren Fällen wie z.B. beim Buchen der Inventur, oder in der EDI-Drehscheibe. Der sender ist ein Objekt vom Typ 'Lager' und e ist ein 'LagerbuchungsEventArgs' mit den Eigenschaften
- LagerBuchungsSTR As LagerBuchungsStruktur
- VorLagerbuchung As Boolean
- NachLagerbuchung As Boolean
'LagerBuchungsSTR' selbst hat 24 Eigenschaften, z.B.
- Artikel As Guid
- Menge As Double
- Beleg As Guid
- Position As Guid
- FertigungsAuftrag As Guid
Der sender vom Typ 'Lager' enthält die LagerBuchungListe (mit Einträgen vom Typ 'LagerBuchungsStruktur'), in der die einzelnen durchzuführenden Lagerbuchungen enthalten sind.
Das Trigger-Ereignis wird vor und nach jeder einzelnen Lagerbuchung eines bestimmten Artikels innerhalb der Lagerbuchungs-Transaktion aufgerufen, d.h. es wird bei jedem Aufruf nur ein Lagerbestand in der Datenbank erzeugt, verändert oder entfernt. Enthält die LagerBuchungListe also mehrere Einträge, so wird dieser Trigger entsprechend oft ausgelöst. e.LagerBuchungsSTR ist dabei der Eintrag der LagerBuchungListe, welcher gerade bearbeitet wird.
Beispiel 1: Vor einer Lagerbuchung wird der Lagerbuchungspreis des Artikels nach kundenspezifischen Algorithmen ermittelt und im Artikelstamm gesetzt und somit für die Lagerbuchung gezogen. Beispiel 2: Der 'sender' wird in ein Objekt der Klasse 'Lager' umgewandelt, so dass anschließend Zugriff besteht z.B. auf die verschiedenen erzeugten GUIDs über die 'GuidInformationenSTR'. Beispiel 3: Wird eine automatische Lagerbuchung eines chargenfähigen Artikels ohne Abfrage durchgeführt, bei der keine Charge im Lager vorhanden ist, so wird automatisch eine Chargenbezeichung nach der Form 'CHARGE-YYYY-MM-DD-HH-mm-ss-millisekunden' verwendet. Mit diesem Code wird diese Bezeichnung vor der Lagerbuchung in eine gewünschte Form geändert.
VB.NET: LagerBuchung - Beispiel 1
#Region " TriggerBusinessLayer_LagerBuchung-Ereignis "
Private Sub TriggerBusinessLayer_LagerBuchung(ByVal sender As Object, ByVal e As LagerbuchungsEventArgs) Handles Me.LagerBuchung
Dim tmpDBZ As SQLServerZugriff = Datenbank.DatenDB
Dim artikelFertigung As Guid
Dim artikelPreisEinkauf As Double
'>>> Nur vor einer Lagerbuchung und nur bei Fertigungs-Aufträgen
If e.VorLagerbuchung AndAlso e.LagerBuchungsSTR.FertigungsAuftrag <> Guid.Empty Then
artikelFertigung = C.ToGuidX(tmpDBZ.HoleFeld(TBL.FertigungsAuftrag.ArtikelGUID, TBL.FertigungsAuftrag.TBL, TBL.FertigungsAuftrag.GUID, C.ToStringX(e.LagerBuchungsSTR.FertigungsAuftrag)))
'>>> Nur bei den Buchungen des zu fertigenden Artikels
If e.LagerBuchungsSTR.Artikel = artikelFertigung Then
artikelPreisEinkauf = C.ToDoubleX(tmpDBZ.HoleFeld(TBL.Artikel.PreisEKDBL, TBL.Artikel.TBL, TBL.Artikel.GUID, e.LagerBuchungsSTR.Artikel))
'>>> UPDATE:
tmpDBZ.LöscheFelder()
tmpDBZ.AddFelder(TBL.Artikel.LagerPreisAktuellDBL, artikelPreisEinkauf, EwaSQL.Float)
tmpDBZ.UpdateDatensatz(TBL.Artikel.TBL, artikelFertigung)
End If
End If
End Sub
#End Region
VB.NET: LagerBuchung - Beispiel 2
#Region " TriggerBusinessLayer_LagerBuchung-Ereignis "
Private Sub TriggerBusinessLayer_LagerBuchung(ByVal sender As Object, ByVal e As LagerbuchungsEventArgs) Handles Me.LagerBuchung
'>>> Nur nach einer jeden einzelnen Lagerbuchung:
If e.NachLagerbuchung Then
Dim lagerOBJ As Lager = CType(sender, Lager)
Dim belegGepusht As Boolean
Dim artikel, beleg As Guid
'>>> Information, ob ein Beleg gepusht wurde, z.B. Button 'Wareneingangs-Lieferung zu Bestellung erzeugen'
belegGepusht = lagerOBJ.GepushterBelegJN
Debug.WriteLine("Beleg gepusht: " & belegGepusht.ToString)
'>>> GUID des Beleges der Lagerbuchung, z.B. der beim Pushen erzeugten Wareneingangs-Lieferung
beleg = e.LagerBuchungsSTR.Beleg
Debug.WriteLine("Beleg-GUID: " & beleg.ToString)
'>>> GUID des Artikels der Lagerbuchung
artikel = e.LagerBuchungsSTR.Artikel
Debug.WriteLine("Artikel-GUID: " & artikel.ToString)
'>>> GUIDs der ggf. erzeugten / geänderten Datensätze ausgeben der Tabellen 'ArtikelLagerBestand', 'ArtikelLagerBestandChargen',
'>>> 'LagerJournal', 'VorgangsPositionsChargen'
Debug.WriteLine("Erzeugter Artikel-Lager-Bestand: " & lagerOBJ.GuidInformationenSTR.ErzeugterArtikelLagerBestandGUID.ToString)
Debug.WriteLine("")
Debug.WriteLine("Geänderter Artikel-Lager-Bestand: " & lagerOBJ.GuidInformationenSTR.GeänderterArtikelLagerBestandGUID.ToString)
Debug.WriteLine("")
Debug.WriteLine("Erzeugte Charge: " & lagerOBJ.GuidInformationenSTR.ErzeugteChargeGUID.ToString)
Debug.WriteLine("")
Debug.WriteLine("Geänderte Charge: " & lagerOBJ.GuidInformationenSTR.GeänderteChargeGUID.ToString)
Debug.WriteLine("")
Debug.WriteLine("Erzeugter Lagerjournal-Eintrag: " & lagerOBJ.GuidInformationenSTR.ErzeugterLagerJournalEintragGUID.ToString)
Debug.WriteLine("")
If lagerOBJ.GuidInformationenSTR.ErzeugtePositionsChargenLIS.Count > 0 Then
Debug.WriteLine("Erzeugte Positions-Charge 1: " & lagerOBJ.GuidInformationenSTR.ErzeugtePositionsChargenLIS(0).ToString)
Debug.WriteLine("")
End If
If lagerOBJ.GuidInformationenSTR.GeändertePositionsChargenLIS.Count > 0 Then
Debug.WriteLine("")
Debug.WriteLine("Geänderte Positions-Charge 1: " & lagerOBJ.GuidInformationenSTR.GeändertePositionsChargenLIS(0).ToString)
End If
End If
End Sub
#End Region
VB.NET: LagerBuchung - Beispiel 3
#Region " TriggerBusinessLayer_LagerBuchung-Ereignis "
Private Sub TriggerBusinessLayer_LagerBuchung(ByVal sender As Object, ByVal e As LagerbuchungsEventArgs) Handles Me.LagerBuchung
If e.VorLagerbuchung AndAlso e.LagerBuchungsSTR.Charge.StartsWith("CHARGE-") Then
e.LagerBuchungsSTR.Charge = "99-" & Strings.Right(Now.Year.ToString, 2) & _
Now.Month.ToString.PadLeft(2, "0"c) & _
Now.Day.ToString.PadLeft(2, "0"c)
End If
End Sub
#End Region
LagerBuchungsPlausibilitätsPrüfung
Dieses Ereignis wird vor und nach jeder einzelnen Plausibilitätsprüfung ausgelöst. Die Prüfungen werden in einer Funktion zu Beginn einer Lager-Buchungs-Transaktion (Lager.LagerBuchungsTransaktion) durchgeführt. Der sender ist ein Objekt vom Typ 'Lager' und e ist ein 'LagerBuchungsPlausibilitätsPrüfungEventArgs' mit den Eigenschaften:
- LagerBuchungsSTR As LagerBuchungsStruktur
- Zeitpunkt As LagerBuchungsPlausibilitätsPrüfungsZeitpunkt
'LagerBuchungsSTR' selbst hat 24 Eigenschaften, z.B.:
- Artikel As Guid
- Menge As Double
- Beleg As Guid
- Position As Guid
- FertigungsAuftrag As Guid
Der sender vom Typ 'Lager' enthält die LagerBuchungListe (mit Einträgen vom Typ 'LagerBuchungsStruktur'), in der die einzelnen durchzuführenden Lagerbuchungen enthalten sind. Enthält die LagerBuchungListe also mehrere Einträge, so wird dieser Trigger entsprechend oft ausgelöst. e.LagerBuchungsSTR ist dabei der Eintrag der LagerBuchungListe, welcher gerade bearbeitet wird.
Wird der Trigger, wie in Beispiel 1 beschrieben, zum Blockieren negativer Lagerbuchungen verwendet, so ist eine solche Blockade auch in folgenden Triggern zu realisieren:
- EwaLagerortMagazinChargenAuswahl (FormFrameworkLayer)
- ÜbergreifendeNegativeLagerBestandsPrüfung (BusinessLayer)
Beispiel: Negative Lagerbuchungen sind in der Mandanten-Konfiguration grundsätzlich ausgeschaltet. Nur für Artikel, deren Artikelnummer mit 'A' beginnt, soll das Buchen in den negativen Bestand eingeschaltet werden.
VB.NET: LagerBuchungsPlausibilitätsPrüfung - Beispiel
#Region " TriggerBusinessLayer_LagerBuchungPlausibilitätsPrüfung-Ereignis "
Private Sub TriggerBusinessLayer_LagerBuchungPlausibilitätsPrüfung(sender As Object, e As LagerBuchungPlausibilitätsPrüfungEventArgs) Handles Me.LagerBuchungPlausibilitätsPrüfung
If e.Zeitpunkt = LagerBuchungsPlausibilitäsPrüfungsZeitpunkt.StartPrüfung Then
If e.LagerBuchungsSTR.ArtikelNummer.StartsWith("A") Then
GV.ConfigMandant.NegativerLagerBestandZulässig = True
End If
Else
GV.ConfigMandant.NegativerLagerBestandZulässig = False
End If
End Sub
#End Region
ManagedScannerAktion
Dieses Ereignis wird beim Senden an und beim Empfangen von Daten bei der Interaktion mit einem Datalogic PowerScan PM9100, PM9300 oder PM9500 bzw. mit seiner Basisstation ausgelöst. Per Barcode-Scan oder mittels Eingabe über die (je nach Modell vorhandenen) Tasten wird eine Zeichenkette an den verarbeitenden easyWinArt-Dienst gesendet. easyWinArt kann wiederum (jederzeit unabhängig oder als Antwort) eine Zeichenkette auf das Display senden, die beiden LEDs rot oder grün aufleuchten lassen, sowie verschiedene akkustische Signale ansteuern.
Wird der die permanente Aufgabe 'Scanner-Kom-Server' vom easyWinArt-Dienst gestartet oder ein weiterer Scanner (oder Basisstation) initialisiert, wird zunächst ein Standard-Hauptmenü an den Scanner gesendet. Schon hier kann mit dem SDK eingegeriffen und ein eigenes Menü oder anderer Text eingeblendet werden.
Beispiel: Die Standard-Funktionen werden unterbunden, stattdessen wird eine eigene Logik für den Barcode-Scanner realisiert.
VB.NET: ManagedScannerAktion - Beispiel
#Region " TriggerBusinessLayer_ManagedScannerAktion-Ereignis "
Private Sub TriggerBusinessLayer_ManagedScannerAktion(sender As Object, e As ManagedScannerAktionEventArgs, ByRef AktionAusführen As Boolean) Handles Me.ManagedScannerAktion
'>>> Darauf reagieren, wenn der Dienst startet und etwas zu einem Scanner vom Typ 'PowerScanPM9X00' gesendet wird
If e.Richtung = easyWinArt.ManagedScanner.Richtung.SendenZumScanner AndAlso
e.Zeitpunkt = easyWinArt.ManagedScanner.EreignisZeitpunkt.VorStandardbehandlung AndAlso
TypeOf e.Scanner Is PowerScanPM9X00.Scanner Then
'>>> Wenn als Scanner-Funktion, welche auf die nächsten Daten vom Scanner reagieren wird, die Funktion 'HauptmenüAntwort' hinterlegt ist, dann muss dieser
' Sendevorgang das Senden des Hauptmenüs an den Scanner sein, darauf hier reagieren
Dim scannerFunktion As ManagedScanner.IScannerFunktion = Nothing
If ManagedScanner.ScannerFunktionenDIC.TryGetValue(e.Scanner.Guid, scannerFunktion) AndAlso
TypeOf scannerFunktion Is PowerScanPM9X00.HauptmenüAntwort Then
'>>> Typkonvertierung um den konkreten Scanner zu erhalten
Dim pm9xScanner As PowerScanPM9X00.Scanner = CType(e.Scanner, PowerScanPM9X00.Scanner)
'>>> Ausführung des Standard-Codes (und damit Senden des Standard-Hauptmenüs) unterbinden
AktionAusführen = False
'>>> Eigene Antwort-Klasse für diesen Scanner hinterlegen, damit gilt nicht mehr die Standard-Klasse 'HauptmenüAntwort'
ManagedScanner.ScannerFunktionenDIC(e.Scanner.Guid) = New MeineAntwort1
'>>> [Alternativ kann hier die Standard-Antwortklasse auch entfernt werden, wenn ohne ScannerFunktion-en gearbeitet werden soll]
' ManagedScanner.ScannerFunktionenDIC.Remove(e.Scanner.Guid)
'>>> Eigenen Text (z.B. eigenes Hauptmenü oder Nachricht) an den Scanner senden
Dim nachricht As String = PowerScanPM9X00.Message.GrüneLedAn.Plain & PowerScanPM9X00.Message.KurzerHoherTon.Plain &
PowerScanPM9X00.Message.GrüneLedAus.Plain & PowerScanPM9X00.Message.ClearDisplayUndCursorObenLinks.Plain &
PowerScanPM9X00.TextFürDisplayAnpassen("Bitte Artikelnummer scannen:")
CType(e.Basisstation, PowerScanPM9X00).DatenSenden(PowerScanPM9X00.AntwortTyp.Unabhängig, PowerScanPM9X00.SendeFormat.PlainUndSteuerzeichen, pm9xScanner, nachricht)
End If
End If
End Sub
#End Region
#Region "Class MeineAntwort1"
Class MeineAntwort1
Implements ManagedScanner.IScannerFunktion
Public Sub Run(Scanner As ManagedScanner.Scanner, Barcode As String) Implements ManagedScanner.IScannerFunktion.Run
'>>> In der Klasse 'MeineAntwort' wird nun programmiert, wie mit der Antwort (Barcodescan oder Tastatureingabe) durch den Anwender umgegangen wird
' Kann der Anwender verschiedene Aktionen durchführen, so können natürlich auch mehrere AntwortKlassen geschrieben werden, von denen jeweils die
' zur nächsten Eingabe des Anwenders passende in 'ManagedScanner.ScannerFunktionenDIC' für diesen Scanner hinterlegt wird
'>>> Typkonvertierung um den konkreten Scanner zu erhalten
Dim pm9xScanner As PowerScanPM9X00.Scanner = CType(Scanner, PowerScanPM9X00.Scanner)
'>>> Verarbeitung unterschiedlicher Antworten
Select Case Barcode
Case "1"
'>>> Code, wenn der Anwender nur eine 1 zurückschickt
' ...
Case "2"
'>>> Code, wenn der Anwender nur eine 2 zurückschickt, usw.
' ...
Case Else
'>>> z.B. bei allen anderen Eingaben / Scan die Eingabe als Artikelnummer suchen
Dim dbz As SQLServerZugriff = Datenbank.DatenDB
Dim nachricht As String
If C.ToGuidX(dbz.HoleFeld(TBL.Artikel.GUID, TBL.Artikel.TBL, TBL.Artikel.ArtikelNummerVC, Barcode)) <> Guid.Empty Then
'>>> Code zum Durchführen einer Lagerbuchung für den gescannten Artikel
' ...
nachricht = PowerScanPM9X00.Message.GrüneLedAn.Plain & PowerScanPM9X00.Message.KurzerHoherTon.Plain &
PowerScanPM9X00.Message.GrüneLedAus.Plain & PowerScanPM9X00.Message.ClearDisplayUndCursorObenLinks.Plain &
PowerScanPM9X00.TextFürDisplayAnpassen("Buchung durchgeführt. Bitte nächste Artikelnummer eingeben:")
CType(pm9xScanner.Basisstation, PowerScanPM9X00).DatenSenden(PowerScanPM9X00.AntwortTyp.AlsAntwort, PowerScanPM9X00.SendeFormat.PlainUndSteuerzeichen, pm9xScanner, nachricht)
Else
nachricht = PowerScanPM9X00.Message.RoteLedAn.Plain & PowerScanPM9X00.Message.LangerTieferTon.Plain &
PowerScanPM9X00.Message.RoteLedAus.Plain & PowerScanPM9X00.Message.ClearDisplayUndCursorObenLinks.Plain &
PowerScanPM9X00.TextFürDisplayAnpassen("Diese Artikelnummer exisitiert nicht, bitte neue Artikelnummer eingeben:")
CType(pm9xScanner.Basisstation, PowerScanPM9X00).DatenSenden(PowerScanPM9X00.AntwortTyp.AlsAntwort, PowerScanPM9X00.SendeFormat.PlainUndSteuerzeichen, pm9xScanner, nachricht)
End If
End Select
End Sub
End Class
#End Region
MenueFunktionDeleted
Beschreibung: folgt bald
Beispiel: folgt bald
NachPreisfindung
Dieses Ereignis wird nach dem Durchführen der Preisfindung in der Klasse 'Preisfindung' ausgelöst. Die Preisfindung dient dazu, aus den vielen möglichen Faktoren die korrekten Werte für eine Position in einem Verkaufs- oder Einkaufsbeleg zu finden. mit diesem Trigger können die ermittelten Daten durch eigene ersetzt werden. Dabei stehen über mehrere Eigenschaften die verschiedenen verwendeten oder ermittelten Daten wie 'ArtikelGUID', 'AdressGUID', 'Menge', 'Datum', 'EinzelPreis', usw. zur Verfügung. Für die Ersetzung der Daten stehen mehrere Prozeduren zur Verfügung, z.B. 'ÜberschreibeEinzelpreis' oder 'ÜberschreibeRabatt'. Somit kann z.B. unter bestimmten Bedingungen ein ganz eigener Algorithmus oder eine eigene Datenquelle zur Festlegung des Verkaufspreises verwendet werden.
Beispiel: Der Preis wird immer fest auf 199,90 gesetzt.
ÜbergreifendeNegativeLagerBestandsPrüfung
Im Rahmen der Plausibilitätsprüfung zu Beginn einer Lager-Buchungs-Transaktion (Lager.LagerBuchungsTransaktion) werden in einem Lagerbuchungs-Liste-übergreifenden Teil vier übergreifende Prüfungen (in vier Schleifen) durchgeführt: pro Artikel, pro Artikel-Lagerplatz, pro Artikel-Charge und pro Artikel-Lagerplatz-Charge. In jeder dieser vier Schleifen wird dieser Trigger zu Beginn und am Ende ausgelöst. Der sender ist ein Objekt vom Typ 'Lager' und e ist ein 'ÜbergreifendeNegativeLagerBestandsPrüfungEventArgs' mit den Eigenschaften:
- Artikel As Guid
- Lagerort As Guid
- Magazin As Guid
- Charge As String
- Zeitpunkt As ÜbergreifendeNegativeLagerBestandsPrüfungsZeitpunkt
- AktionAusführen As Boolean
Der sender vom Typ 'Lager' enthält die LagerBuchungListe (mit Einträgen vom Typ 'LagerBuchungsStruktur'), in der die einzelnen durchzuführenden Lagerbuchungen enthalten sind.
Die Variable 'AktionAusführen' ist an dieser Stelle dafür gedacht, um einzelne Prüfungen zu umgehen. Die Lagerbuchung selbst wird demnach immer ausgeführt, jedoch können einzelnen Prüfungen somit deaktiviert werden.
Wird der Trigger, wie im Beispiel beschrieben, zum Blockieren negativer Lagerbuchungen verwendet, so ist eine solche Blockade auch in folgenden Triggern zu realisieren:
- EwaLagerortMagazinChargenAuswahl (FormFrameworkLayer)
- LagerBuchungsPlausibilitätsPrüfung (BusinessLayer)
Beispiel: Negative Lagerbuchungen sind in der Mandanten-Konfiguration grundsätzlich ausgeschaltet. Nur für Artikel, deren Artikelnummer mit 'A' beginnt, soll das Buchen in den negativen Bestand eingeschaltet werden.
VB.NET: ÜbergreifendeNegativeLagerBestandsPrüfung - Beispiel
#Region " TriggerBusinessLayer_ÜbergreifendeNegativeLagerBestandsPrüfung-Ereignis "
Private Sub TriggerBusinessLayer_ÜbergreifendeNegativeLagerBestandsPrüfung(sender As Object, e As ÜbergreifendeNegativeLagerBestandsPrüfungEventArgs, ByRef AktionAusführen As Boolean) Handles Me.ÜbergreifendeNegativeLagerBestandsPrüfung
If e.Zeitpunkt = ÜbergreifendeNegativeLagerBestandsPrüfungsZeitpunkt.StartArtikel OrElse
e.Zeitpunkt = ÜbergreifendeNegativeLagerBestandsPrüfungsZeitpunkt.StartLagerPlatz OrElse
e.Zeitpunkt = ÜbergreifendeNegativeLagerBestandsPrüfungsZeitpunkt.StartCharge OrElse
e.Zeitpunkt = ÜbergreifendeNegativeLagerBestandsPrüfungsZeitpunkt.StartLagerplatzCharge Then
Dim artGUID As Guid = e.Artikel
Dim tmpDBZ As SQLServerZugriff = Datenbank.DatenDB
If C.ToStringX(tmpDBZ.HoleFeld(TBL.Artikel.ArtikelNummerVC, TBL.Artikel.TBL, TBL.Artikel.GUID, artGUID.ToString)).StartsWith("A") Then
AktionAusführen = False
End If
End If
End Sub
#End Region