Kurzes Update von meiner Seite - nach langem hin und her und mit den Beschränkungen im Preismodel von JTL, haben wir es rein
Datenbankseitig umgesetzt:
Custom Tabelle mit Trigger in der Datenbank und Stored Procedure.
Nachteil ist, dass diese Lösung zurzeit nur Änderungen im Netto Verkaufspreis, nicht im Sonderpreis, Kundenspezifischen Preisen oder Staffeln abdeckt. Aber nach 3h war die Luft raus
Außerdem besteht natürlich die Gefahr das eine Änderung in JTL
WaWi Änderungen in der Datenbank überschreiben kann. Und es ist keine schöne Ausgabe im JTL, sondern man muss sich einen Bericht selbst bauen.
Vorteil ist, so haben wir eine JTL unabhängige Lösung alle möglichen Änderungen zu protokollieren. Und gerade wenn man mehrere Benutzer hat, verhindert es eine Verzögerung beim Speichern von Artikeländerungen und es sind keine Customer
Workflow nötig.
Disclaimer
Für alle die etwas ähnliches machen wollen und Ahnung von SQL haben, habe ich meinen Weg hier zusammengefasst. Für etwaige Kommentare & Verbesserungen bin ich dankbar.
ACHTUNG! Das greift direkt in die produktive Datenbank ein, also bitte nur den Code kopieren und ausführen, wenn ihr mit der SQL Datenbank vertraut seid. Unbedingt vorher alles sichern, wenn ihr euch unsicher seid
Diese Lösung funktioniert wie folgt
- Der Trigger wird aktiviert, wenn in tArtikel eine Aktualisierung stattfindet.
- Er prüft, ob das Feld fVKNetto geändert wurde.
- Wenn ja, holt er die relevanten Informationen (ArtikelID, neuer Preis, BenutzerID) aus der inserted Tabelle.
- Dann ruft er die Stored Procedure spUpdatePreisHistorie mit diesen Parametern auf.
- Die Stored Procedure prüft, ob der neue Preis sich vom letzten Preis in tArtikelPreisHistorie unterscheidet.
- Wenn ja, fügt sie einen neuen Eintrag in tArtikelPreisHistorie hinzu.
Diese Lösung erfüllt die Anforderungen
- Sie erfasst Änderungen in fVKNetto in tArtikel.
- Sie verwendet tArtikelPreisHistorie für die komplette Preishistorie.
- Sie vergleicht mit dem letzten geänderten Preis je Artikel.
- Sie verwendet den Benutzer der letzten Änderung aus kBenutzerLetzteAenderung in tArtikel.
Diese triggerbasierte Lösung sollte zuverlässig alle Preisänderungen erfassen, unabhängig davon, wie sie in
tArtikel vorgenommen werden.
=> Auch nicht in JTL, sondern in der DB direkt erfasste Änderungen werden protokolliert
Technische Umsetzung
Erstellung neue Tabelle in der Datenbank [SQL]
SQL:
-- Tabelle für Preishistorie erstellen (falls noch nicht vorhanden)
CREATE TABLE tArtikelPreisHistorie (
kArtikelPreisHistorie INT IDENTITY(1,1) PRIMARY KEY,
kArtikel INT NOT NULL,
fVKNetto DECIMAL(10,2) NOT NULL,
dAenderungsDatum DATETIME NOT NULL,
kBenutzer INT NOT NULL
)
Initialisierung der Tabelle [SQL]
SQL:
-- Initialisieren der tArtikelPreisHistorie mit aktuellen Preisen
INSERT INTO tArtikelPreisHistorie (kArtikel, fVKNetto, dAenderungsDatum, kBenutzer)
SELECT p.kArtikel, p.fVKNetto, GETDATE(), p.kBenutzerLetzteAenderung
FROM tArtikel p
WHERE NOT EXISTS (
SELECT 1
FROM tArtikelPreisHistorie h
WHERE h.kArtikel = p.kArtikel
);
Einrichtung der Stored Procedure [SQL]
SQL:
CREATE PROCEDURE spUpdatePreisHistorie
@ArtikelID INT,
@NeuerPreis DECIMAL(10, 2),
@BenutzerID INT
AS
BEGIN
DECLARE @AlterPreis DECIMAL(10, 2);
SELECT TOP 1 @AlterPreis = fVKNetto
FROM tArtikelPreisHistorie
WHERE kArtikel = @ArtikelID
ORDER BY dAenderungsDatum DESC;
IF @AlterPreis IS NULL OR @AlterPreis != @NeuerPreis
BEGIN
INSERT INTO tArtikelPreisHistorie (kArtikel, fVKNetto, dAenderungsDatum, kBenutzer)
VALUES (@ArtikelID, @NeuerPreis, GETDATE(), @BenutzerID);
END
END;
Die Stored Procedure ist nach Anlage zu finden unter Datenbank > Programmability > Stored Procedures
Einrichtung eines Triggers auf der Tabelle tArtikel
SQL:
CREATE TRIGGER trg_UpdatePreisHistorie
ON [dbo].[tArtikel]
AFTER UPDATE
AS
BEGIN
IF UPDATE(fVKNetto)
BEGIN
DECLARE @ArtikelID INT, @NeuerPreis DECIMAL(10, 2), @BenutzerID INT;
SELECT @ArtikelID = i.kArtikel,
@NeuerPreis = i.fVKNetto,
@BenutzerID = i.kBenutzerLetzteAenderung
FROM inserted i
INNER JOIN deleted d ON i.kArtikel = d.kArtikel
WHERE i.fVKNetto <> d.fVKNetto;
IF @ArtikelID IS NOT NULL
BEGIN
EXEC [dbo].[spUpdatePreisHistorie] @ArtikelID, @NeuerPreis, @BenutzerID;
END
END
END;