Blog: Latest Entries (15):


Shopware: Eigenes Einkaufswelten Element

Da es zu dem Thema "Einkaufswelten Elemente selber bauen mit ExtJS" relativ wenig Hilfe bei Shopware gibt, habe ich mich mal wirklich mit [url=https://developers.shopware.com/developers-guide/custom-shopping-world-elements/#advanced:-adding-a-custom-emotion-component-in-extjs]Hilfe von dem Shopware eigenen Tutorial zu Einkaufswelten Elementen[/ur]) und vielen einzelnen Formum-Beitragen da durch gekämpft. Ich mag ExtJS immer noch nicht, aber so langsam komme ich wenigstens mit den Components klar. Ist am Ende nicht so viel anders wie Swing oder SWT, nur wird in den Constructoren der Componenten die man erweitert sehr viel "Magic" gemacht auf die man angewiesen ist. Allein die Frage: wie bekomme ich ein einfaches kleines Text-Feld in das richtige FieldSet?

Elemente von Einkaufswelten sind ein wirklich nicht so einfaches Thema, wenn man die reine PHP-Schiene verlässt und mit ExtJS arbeitet. Aber diese Mischung im Vimoe-Element Beispiel finde ich jetzt auch nicht so wirklich toll. Felder hier, Stores da.. man sollte alles auf einen Blick haben und wenn man mit JavaScript arbeitet muss man das Plugin auch nicht öfters neu installieren sondern nur den Cache löschen und das Shopware-Backend neu laden.

Init-Methode einer einfachen kleinen GUI mit einem Feld zur Artikel-Auswahl:


initComponent: function() {
var me = this;
me.callParent(arguments);

me.articleStore = Ext.create('Ext.data.Store', {
model: 'Shopware.model.Dynamic',
proxy: {
type: 'ajax',
url: '{url controller="EntitySearch" action="search"}?model=Shopware\\Models\\Article\\Article',
reader: Ext.create('Shopware.model.DynamicReader')
}
});

me.articles = Ext.create('Ext.form.field.ComboBox', {
name: 'article',
fieldLabel: 'Artikel',
store: me.articleStore,
allowBlank: false,
valueField: 'id',
displayField: 'name'
});
me.articles.setVisible(true);
me.elementFieldset.add(me.articles);
},


Darin sieht man wie meinen einen eigenen Store mit AJAX-Backend definiert und diesen in der ComboBox verwendet, die man wiederum in den Element-Einstellungen anzeigt. Wenn man schon mal soweit ist, steht einen auf dem Weg zu Einkaufswelten mit eigenen Elementen in Shopware nicht mehr viel im Weg.

Shopware-Plugin: Dropshipping-Solutions

Dropshipping mit Shopware ist ja nicht immer ganz einfach, wenn man nicht direkt alle Produkte von einem Vendor bezieht. Wenn man nur einen für alles hat ist alles ganz einfach weil man direkt, die gesamte Bestellung an diesen senden kann. Hat man nur einen, aber der auch nur bestimmte Produkte liefert geht es jetzt auch bzw. der erste Testdurchlauf für diesen Use-Case lief sauber durch.

Für Multi-Vendor Orders muss man eine Bestellung in mehrere kleine pro Distributor/Vendor/Lieferant aufteilen. Wenn man nur einmal alle 2h oder so die Bestellungen übermittelt und die Waren an sich selbst liefern lassen möchte, kann man diese sogar noch mal vorher wieder mergen, weil dann Lieferant und Empfänger bei allen Bestellungen immer gleich sind. Aber das ist schon ein Ausnahmefall.
Natürlich kann jeder Vendor einen eigenen Endpoint für die Bestellungen bereitstellen. Entweder per Email, Datei-Upload oder REST-API können die Daten in immer unterschiedlichen XML-Formaten übertragen werden. Das macht dann mehr Probleme.

Mein Shopware-Plugin kann nun aber immerhin verschiedene Vendor/Hersteller bei diesem Splitting ignorieren. Damit ist es nun möglich, wenn man nur einen Vendor für bestimmte Produkte hat, diesen auch mit dem Plugin die Bestellungen automatisch zu zustellen. Bei mehr als einem muss mein Plugin noch leider passen.

Das Plugin kann also momentan folgende Fälle komplett abdecken:

- Übertragung von allen Bestellungen in ein ERP-System oder ähnliches
- Übertragung von allen Bestellungen an einen Vendor (mit oder ohne Dropshipping)
- Übertragung von bestimmten Bestellungen oder auch nur Teil-Bestellungen an einen Vendor (mit oder ohne Dropshipping)

ob es sich um eine einfache Order bei dem Vendor handelt oder um Dropshipping, muss man sich teilweise im XSLT für das Order-XML selbst zusammen bauen (oder mich damit beauftragen). Für die openTRANS-Formate versuche ich momentan eine Lösung zu entwickeln, die dann z.B. die Lieferadresse automatisch nach Konfiguration mit den eigenen Adress- oder den Kunden-Adressdaten befüllt.

bbcode-image


bbcode-image
Für den Export zulassen


bbcode-image


An einer vollständigen Lösung, um beliebig viele Vendor mit jeweils eigenen Übertragungsarten und XML-Formaten anzubinden, arbeite ich auch nebenbei. Gerne würde ich eine Shop-System unabhängige Lösung bauen.. leider fehlt dafür aber Zeit und Geld... bzw. hauptsächlich Geld.. weil wenn man das Geld hat, hat man auch die Zeit.


Der Blog, die Arbeit und zu wenig Zeit

Der Blog liegt leider bei mir gerade etwas brach. Zu viel zu Arbeiten und auch das Haus zieht viel Aufmerksamkeit auf sich. Das Wetter ist eben so gut, dass man den Garten dann gegen Ende doch fast auf dem Niveau hat, das man sich Anfang des Jahres vorgenommen hat.

Momentan steht ein Projekt mit meinem PHP-Framework, ganz oben auf der Todo-Liste. Wenn ich mal das Blog-Modul und das Admin-Panel verbessern würde, kann man es auch über all da einsetzen, wo sonst eher WordPress eingesetzt wird. Aber ist Dabei modular, MVC, Events, etc... also doch noch eher dazu da darin selbst zu entwickeln.
Die Pflege der Shopware Plugins und die Entwicklerer weiter Shopware Plugins ist momentan auch eher zurück gestellt. Wobei dass das ist, was ich dann gegen Ende des Jahres wieder mehr verstärkt betreiben werden.

Zum Ende des Jahres, werde ich mal wieder mehr schreiben. Auch mal wieder etwas mehr über das Thema Arbeit an sich. Druck, Arbeitszeitmodelle und so, da ich in letzter Zeit doch öfters in nicht immer positiver Weise damit konfrontiert wurde.

Wobei man natürlich auch Garten heutzutage nicht ohne IT auskommt (Temperatur-Überwachung).
bbcode-image

Text-Editor für Linux

Ich habe ja lange nach einem guten Text-Editor für Linux gesucht.

- gedit: zu primitiv
- Geany: schelchte UI und ich muss neue Tabs vor dem Schließen speichern
- Atom: Nett und das mit dem Tabs und dem Schließen funktionierte FAST

Am Ende habe ich wieder Notepad++ mit Wine verwendet und bin damit echt sehr zufrieden. Nur leider ist es kein natives Linux-Programm.

Heute habe ich dann Visual Studio Code ausprobiert.

bbcode-image


Tab aufgemacht, was geschrieben, Editor geschlossen, wieder geöffnet UND alles war noch da! Er kann das was ich bis jetzt nur bei Notepad++ gefunden habe und sieht noch gut aus. Bis jetzt gefällt er mir sehr gut.

bbcode-image


Wer hätte vor paar Jahren gedacht, dass einer der besten Editoren für Linux von Microsoft kommen wird?

Projekt: Highspeed USB-Stick

Die Idee klang erst einmal ganz interessant. Eine ältere SSD im mSATA oder M.2 Format in einen USB 3.0 Adapter einbauen und als schnellen USB-Stick verwenden. Kostet auch so gut wie nichts. Ein Adapter so 3-5 EUR in China und eine 32GB mSATA SSD kostet auch nur etwas über 10 EUR.
Nettes kleines Projekt dachte ich mir. Kann ja nicht viel schief laufen, außer dass der Adapter vielleicht am Ende doch alles aus bremst, weil der schlecht ist.

bbcode-image


Und mein vorhaben ist grandios gescheitert. Eines von beiden funktioniert nicht. Formatieren ging nach vielen versuchen. Aber irgendwann bricht die Übertragung ab und Windows meldet einen Timeout.

bbcode-image


bbcode-image


Was jetzt? SSD neu bestellen? Adapter erneut bestellen?

Ich bestell einen SATA-Adapter (kann man immer mal gebrauchen) und teste mal die SSD. Wenn die defekt ist, wird die zurück geschickt. Ansonsten werde ich mal abwarten, ob man einen neuen Adapter mal für 1 EUR oder so bekommt, der hoffentlich dann richtig funktioniert.

Altes Alienware + SSD = wrummmmm

Gestern Abend wurde das Alienware Notebook mit einer Intel Pro 2500 SSD aufgerüstet, die die beiden HDDs ersetzt hat.

bbcode-image


bbcode-image


Bringt echt was und es wird noch einen ausführlichen Blog-Post mit Benchmark-Ergebnissen geben.

Aber es hat sich auf jeden Fall gelohnt und SSDs sind wirklich günstig geworden.

Damit wird er uns auch die nächsten Jahre noch gute Dienste leisten. Bei Spielen und Outdoor-Einsätzen.

bbcode-image
Im Regen bei Zeitmessungen



Shopware-Plugin: Dropshipping mit XML Export-Plugin

In den letzten Wochen hat sich doch einiges beim meinem XML-Export Plugin getan. Langsam aber zielstrebig geht es in die Bereiche Dropshipping und Bestellung-Konsolidierung. Dadurch wird es zu einem wichtigen B2B-Baustein.

Mit der Version 0.4.1 ist nun viel mehr in dem Bereich möglich (Veröffentlichung folgt in den nächsten Tagen)

Als erstes Beispiel wie man das Plugin nicht nur dafür verwenden kann für das eigene ERP Bestellungen zu exportieren, habe ich hier erotikgrosshandel.de . Deren Schnittstellen-Doku ist ziemlich gut und sie haben ein sehr minimalistisches Format, so dass man relativ schnell zum Ziel kommt. Die Voraussetzung waren:

- Ein eigenes passendes XSLT-Template (nach deren Doku)
- Der ApiClient muss FORM-Data per Post senden können (nicht nur wie bisher JSON)
- CronJob und CLI-Command müssen den Push an eine API auslösen
- Das Model muss die Lieferanten spezifischen Bestellnummern der Artikel enthalten (Puchase-Preise kamen gleich mit dazu...)

Das ganze war dann eigentlich nur viel Kleinkram und der POST als FORM-Data. War also an sich relativ schnell umgesetzt und lies sich gut testen.

Eingestellt muss sein:

- Format: eigene XSLT-Transformation
- Den Pfad zur eigenen XSLT angeben (absoluter Pfad vom /-Root aus!)
- Export-Pfad ist nicht nötig, aber sollte man doch setzen, falls man als Kontrolle die XML-Daten doch selbst noch mal vorhalten möchte (auch hier der absolute Pfad)
- nie automatisch exportieren (nur per CLI, CronJob oder API), man sollte den CronJob verwenden
- CronJob soll nur Bestellungen mit dem Status 0 und 12 (offen und vollständig bezahlt) verarbeiten: "0,!1,!2,!3,!4,!5,!6,!7,!8,!9,!10,!11,12,!13,!14"
- nach dem Export auf Status 1 (in Bearbeitung) setzen
- Host und URL setzen für erotikgrosshandel.de
- Content-Feldname auf "data" ändern
- Post-Format auf "FORM" setzen, damit in "data" die XML-Daten zu finden sind

bbcode-image


Damit sendet er per CLI oder CronJob alle 0+12 Bestellungen im Lieferanten eigenen XML-Format an deren Schnittstelle und setzt danach die Bestellung auf 1+12, damit sie beim nächsten Durchlauf kein weiteres mal übertragen wird.

Ein passendes XSLT kann so aussehen:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<orderdetails>
<!-- replace with your data -->
<customerdetails>
<email>testaccount@edc-internet.nl</email>
<apikey>7651320RK8RD972HR966Z40752DDKZKK</apikey>
<output>advanced</output>
</customerdetails>
<!-- shopware customer -->
<receiver>
<own_ordernumber><xsl:value-of select="order/number"/></own_ordernumber>
<name><xsl:value-of select="order/shipping/firstName"/> <xsl:value-of select="order/shipping/lastName"/></name>
<street><xsl:value-of select="order/shipping/streetSimple"/></street>
<house_nr><xsl:value-of select="order/shipping/houseno"/></house_nr>
<postalcode><xsl:value-of select="order/shipping/zipCode"/></postalcode>
<city><xsl:value-of select="order/shipping/city"/></city>

<xsl:if test="order/shipping/country/iso = 'NL'">
<country>1</country>
</xsl:if>
<xsl:if test="order/shipping/country/iso = 'BE'">
<country>2</country>
</xsl:if>
<xsl:if test="order/shipping/country/iso = 'DE'">
<country>3</country>
</xsl:if>
<!-- TODO complet -->

<extra_email><xsl:value-of select="order/customer/email"/></extra_email>
</receiver>
<products>
<xsl:for-each select="order/details/detail">
<xsl:if test="purchaseInfo/supplierNumber != ''">
<artnr><xsl:value-of select="purchaseInfo/supplierNumber"/></artnr>
</xsl:if>
</xsl:for-each>
</products>
</orderdetails>
</xsl:template>
</xsl:stylesheet>


Den CronJob auf 10min stellen und dann sollten alle 10 Minuten alle "offenen" Bestellungen an den Server übertragen.

Über XSLT-Dateien kann man in anderen Fällen natürlich dann auch andere Formate wie GS1 oder OCI implementieren. Um die Daten zu den anderen Systemen übertragen zu können stehen der API-Client, Emails, Abruf über die Shopware-API oder der Export als Datei (und dann Übertragung per FTP oder SCP) zur Verfügung.

In den nächsten Wochen steht bei mir auf dem Plan, Bestellungen konsolidieren zu können, so dass bei einem CronJob-Lauf alle 2h nicht alle Bestellungen einzeln übertragen werden müssen, sondern auch zusammen gefasst werden können, wenn die Bestellungen für den selben Empfänger vorgesehen sind.

Mein B2B-Shop Gedankenexperiment Teil 1-3

B2B ist anders. B2C ist einfach. Bei B2C macht man Werbung, zeigt Preise und versucht einen möglichst offenen (Paypal-Express) und einfachen Checkout den Kunden zu präsentieren. Bei B2B kommt der Kunde teilweise nicht einfach in den Shop. Da ist der Shop eine Dienstleistung, die den Kunden bereit gestellt wird. Also wird man teilweise erst Kunde und kommt dann in den Shop. Preise sind oft auch so eine Verhandlungssache und nicht jedem Kunden werden sofort Preise präsentiert, weil diese ihn verschrecken könnten, da man mit Abnahmen in kleinen Mengen kalkuliert und Staffelpreise zu ungenau wären, weil hier keine Abnahmen pro Jahr oder so dargestellt werden können. Bloß weil ich 1000 Stück bestelle heißt es nicht, dass ich als B2B-Kunde nicht schon genau weiß, dass ich noch weitere 11000 im restlichen Jahr bestellen werde (aber ich will natürlich Lagerplatz sparen oder nicht Dinge aufwendig gekühlt lagern).

Mein erster Versuch etwas für den B2B-Bereich in Shopware zu entwickeln war mein Plugin zum Verhindern von Kundenregistrierungen. Das klingt nach weniger als es kann, weil es doch sehr fein granulär regelt was bei der Registrierung möglich sein soll:

- Keine Registrierung und nur ein Text mit Infos
- Keine Registrierung aber ein Formular für Anfragen
- Blockieren von bestimmten Email-Adressen
- nur bestimmte Email-Adressen erlauben (Mitarbeiter-Shops und so)
- Nur Firmen als Kunden
- Keine Firmen als Kunden

Damit lässt sich schon mal sehr klar definieren, wer und wie in meinen B2B-Shop darf. Muss ich den Account selbst anlegen für meinen Kunden (dann kann ich direkt festlegen was er sehen darf und was nicht) oder darf es selbst muss aber meine Einstellungen abwarten und darf erst dann kaufen? Das alles kann ich damit steuern.

Ich würde gerne stärker in die Richtung gehen und habe anfangen mir eine recht eigene aber doch nicht so einzigartige, wie Firmen oft glauben, Fantasy-Firma aus zu denken und damit einmal exemplarisch einen Weg zu einem fertigen B2B-Shop zu skizzieren. Die Firma vertreibt noch nicht über einen Shop, hat aber eine entsprechende IT mit ERP und WWS. Die Firma produziert selbst, oft auch nach Bedarf, bietet aber auch einige kleine OEM-Produkte zusätzlich zu ihren Produkten an. Diese OEM-Produkte sind meist kleines Zubehör und Verbrauchsmaterialien.

Als Shopware Edition kommt die CE zum Einsatz, weil die an sich ja alles kann und wenn mehr Support gewünscht ist, kann man ja immer noch nachrüsten. Die B2B-Suite lasse ich aus und gucke, ob man nicht die nötigsten Dinge auch einfacher und günstiger selber schreiben kann und wo hier die Grenzen sind (Workflows mit Freigaben und Hierarchien, wäre hier ein Punkt, wo man echt überlegen sollte, ob man da selbst was schreibt).

Die wichtigsten Punkte sind:

1) Produkt-Daten in den Shop bekommen
2) Bestellungen exportieren
3) Lagerbestände abgleichen
4) Kunden Registrierung
5) Preise und Rechnungen
6) Abrufbestellungen
7) Sets aus Produkten (in Hinsicht auf OEM-Zubehör, das ausgehen könnten)

Also fangen wir mal an die Punkte zu analysieren und einfache + schnelle Lösungen zu finden. Denn eine Time-To-Market sollte auch hier nicht länger als 4-6 Monate benötigen. Was das kostet... darüber kann man vielleicht ganz am Ende noch mal nachdenken. Aber so viel würde ich schon mal sagen: Das Team sollte aus einem Shopware-Entwickler, einen Entwickler aus dem ERP-/WWS-Bereich, jemanden für das Theme + allgemeines Design (Umsetzung kann ja über den Shopware-Entwickler laufen) und jemanden der Kunden-/Preis-/Produktdaten betreut.

1) Produkt-Daten in den Shop bekommen
Das ERP sollte an sich schon eine Schnittstelle mitbringen um Produkte zu exportieren, wenn nicht kann man die in 2-3 Tagen realisieren. Ob SAP oder was eigenes, es funktioniert alles ganz einfach und linear. Wird ein Produkt angelegt oder geändert und ist von den Daten her vollständig wird es als Datei oder per JMS ausgegeben (per Änderung-Flag oder direkt Live ist dabei sogar egal).
Wenn noch keine Schnittstelle existiert, wäre es gut, wenn diese direkt auf das Event reagiert und den Content per Push an den nächsten Service weiterreicht oder auch auch direkt im richtigen JON-Format an Shopware sendet.
Am einfachsten lässt sich so etwas über eine Template-Engine realisieren, wie sie für fast jede Umgebung existiert.
Ansonsten kann man sich eine eigene kleine Middlware bauen, die Daten per File-Watcher oder MDB empfang, die Daten auf Objekte mappt, die vom Interface her den Models von Shopware gleichen und dann per JSON-Serialisierung ausgeben und direkt an die Shopware-API sendet.
Nur eine Sache würde ich wirklich an der Shopware-API über ein Plugin ändern: Es sollte egal sein, ob man POST oder PUT verwendet, wenn eine Produktnummer dabei steht und useNumberAsId=true gesetzt ist, sollte die API selbst heraus bekommen.
Also das Plugin nimmt die Nummer und lädt die Id dazu nach. Existiert eine wird diese im Model, das gerade rein kommt, ergänzt und die Anfrage an die PUT-Action weitergeleitet. Existiert keine Id wird zur POST-Action weitergeleitet. Das ist dann genau so wie ein Merge bei einem ORM (Doctrine, JPA). Ich hab so ein Plugin schon mal geschrieben und es ist echt praktisch und beschleunigt die Datenübermittlung sehr, weil nicht erst durch ein GET bestimmt werden muss, ob die Software die Daten
als POST oder PUT senden muss.

Sollte als Schnittstelle OCI oder BMEcat zur Verfügung stehen, sollte man diese nutzen. Einen eigenen API-Controller für diese Formate zu schreiben, geht relativ schnell und unkompliziert. Teilweise kann soet was sogar besser sein, als die vorhandene Shopware-API. Wenn man Standard-Formate nutzen kann, sollte man es tun, dann wäre selbst ein Wechsel es ERP (z.B. von was eigenen auf SAP) mit übersichtlich viel Arbeit möglich und was am Shop ändern zu müssen.

2) Bestellungen exportieren

Genau so wichtig wie der Import und Abgleich der Artikeldaten ist der Rückweg, nämlich der Export von Bestellungen. Eine einfache API-Schnittstelle mit Filter auf den Bestell-Status zu schreiben geht schnell und einfach. Somit kann ein anderes System sich alle Bestellungen mit einem oder mehreren Status/Status aus dem Shop einfach abholen. Die simpelste Variante ist es per Scheduler-EJB oder Cron-Job laufen zu lassen.
Wenn man mehr in Richtung Echtzeit gehen möchte, kann man eine neue Bestellung natürlich auch vom Shop aus mit einem Push-Client an eine REST-API einer Middleware oder eines ERP senden.
Die primitivste Variante ist natürlich, die Bestellung als Datei abzulegen und per FileWatcher dann dort abholen zu lassen.

Wichtig bei dem Vorgang ist der Faktor Zeit. Denn ja schneller alles geht, desto weniger Gefahr besteht, das Bestellungen aus dem Shop und dem ERP einen Konflikt um Lagerbestände auslösen könnten.

Es fing alles mit einem kleinen Plugin zum dumpen von Bestellungen an, dass ich zum Debugen auf dem produktiven Server entworfen habe. Es entwickelte sich weiter zu einem vollwertigen order-Export Plugin und kann nun:

- Export als Shopware-XML, openTRANS 1.0, openTRANS 2.1
- per XSLT kann man auch jedes weiter XML-format erzeugen (OCI sollte so auch gehen.. sollte.. habe leider kein System zum Testen)
- Export als Datei direkt nach der Bestellung
- Export über CLI-Command und Cron-Job (in das Dateisystem)
- Automatisches Status-Update nach dem Export
- Export oder einen REST-API Controller (mit manuellen Status-Update)
- Automatischer Push an eine REST-API (RESTEasy im Wildfly wurde getestet)

Mit den ganzen verschiedenen Wegen und Formaten, ist eine Integration in vielen Fällen möglich. Man benötigt weiterhin einen Entwickler, da mit die Gegenseite korrekt eingebunden werden kann, aber wenn man die Kommunikation erst einmal laufen hat, läuft alles sehr stabil und zuverlässig (eine Version läuft seit Nov. 2017 und hat bis jetzt nie Probleme verursacht).

Bestellungen sind zum Glück immer sehr einfach strukturiert und sind seit Jahrzehnten auch fast unverändert geblieben.

Was das Plugin nicht zur Verfügung stellt sind allgemeine Updates beider Status und die Übermittlung von Trackingcodes. Hier ist aber die REST-API die Lösung des Problems. Da die Nummer der Bestellung beim Export mit übermittelt wurde, kann man anhand dieser die Bestellung über die REST-API laden und modifizieren.

Wenn man das fertige Plugin verwendet, ist der Aufwand eher gering und man kann sich eher um die Update-Aktionen, die vom ERP aus getriggert werden kümmern.
Momentan entwickelt es sich auch zu einem Dropshipping-fähigen Plugin, mit dem man Bestellungen, für sich oder für seinen Kunden, direkt an externe Lieferanten und Großhändler weiterreichen kann.

3) Lagerbestände abgleichen
Lagerbestände abzugleichen ist mit das komplexeste Thema bei der ganzen Anglegenheit. Während bei den Artikeln sich nur ein System in eine Richtung synchronisieren muss, geht es hier in beide Richtungen. Denn Bestellungen können sowohl über den Shop als auch das ERP ausgelöst werden und manchmal fällt im Lager auch einfach was runter.
Das schlimmste was passieren kann ist, dass man mehr verkauft als man hat. Im einfachsten Fall muss der Kunde länger warten bis man selbst nachbestellt oder nach produziert hat. Im schlimmsten Fall muss man dem Kunden sagen, dass er die bestellte Ware nicht bekommen kann.

Das eigentliche Problem bei den Lagerbeständen ist, dass alles asynchron und nebenläufig ist. Während im ERP eine Order gespeichert wird, wird auch der aktuelle Lagerbestand bestimmt und 2 Bestellungen aus dem Shop liegen in der Import-Queue (alles mit dem selben Artikel). Wenn der Shop jetzt einfach den da bestimmten Lagerbestand anzeigen würde, wäre bis zum nächsten Abgleich der Lagerbestand wieder um 2 höher, weil der schon durch die Bestellungen abgezogene Bestand bei der Neuberechnung nicht verbucht war, der Shop diese 2 Bestellungen aber ab sich schon kennt.
Hier muss mit Differenz-Buchungen und Timestamp gearbeitet werden. Eine sehr gute Lösung ist das führen einer Lagerbewegung-Chain, die durch Absolute-Lagerbestände in Blöcke auf geteilt wird. Man rechnet immer ab dem neusten Absolute-Eintrag aufwerts.

Beispiel:


-1 order 136 2018-01-01 12:15:00 (exportiert)
-1 order 135 2018-01-01 12:14:59 (exportiert)
-1 order 134 2018-01-01 12:02:00 (exportiert und importiert im ERP)
+8 absolute 2018-01-01 12:00:00


Bestand: 5 im Shop

Es ist gerade 12:15:10 und der Lagerbestand im ERP bestimmt und in den Shop importiert, die beiden Orders brauchen noch 15s bis deren Import beginnt (weil der Austausch über Dateien und Cronjobs läuft). Die letzte Bestandsänderung für den Artikel verzeichnet das ERP für 12:03:10, weil dort die Order von 12:02:00 im ERP verarbeitet wurde.


-1 order 136 2018-01-01 12:15:00 (exportiert)
-1 order 135 2018-01-01 12:14:59 (exportiert)
7 absolute 2018-01-01 12:03:10
-1 order 134 2018-01-01 12:02:00 (exportiert und importiert im ERP)
8 absolute 2018-01-01 12:00:00


Bestand: 5 im Shop

Das ist super! Der Bestand aus Shop-Sicht ist gleich geblieben, weil er in beiden Fällen alle Daten kannte. Es wird nie zuviel verkauft werden, obwohl das ERP noch gerade glaubt 7 auf Lager zu haben, weil es die beiden neusten Bestellungen noch nicht kennt.

Am Ende kann man so schnell wie möglich sein und es wird immer diesen kleinen Bereich geben, wo eie BEstellung gerade unterwegs ist, während der Bestand im ERP berechnet wird.

Wo man diese Differenzverrechnung macht ist nicht ganz so wichtig. Ob in einer Middleware oder im Shop direkt, macht kaum einen Unerschied. Es muss immer der verkaufte Bestand aus den Orders als Differenz verbucht werden und Bestandsmeldungen vom ERP entgegen genommen und gespeichert werden.

Das schöne an dem Prinzip ist auch, dass es sich super erweitern lässt, um zukünftige Bestande über Liefer-Avis und ähnliches. Darüber lassen sich dann wieder Lieferzeiten sehr viel genauer bestimmen, wenn man schon weiß, wann wieder etwas auf Lager sein wird und dann auch wie viel. Wenn ich 10 Stück bestelle und im Avis nur 5 Stück angekündigt sind,muss ich ein Lieferdatum nach der kommenden Lieferung verwenden. Normal bei Shopware hätte man nur die typische Lieferzeit des Suppliers, weiß aber nie ob dann wirklich was da ist und wenn doch wie viel Stück.

Die Implementierung so einer Tabelle und den passenden Queries ist relativ einfach. Events für Orders, um die Verkäufe zu vermerken, sind leicht gefunden. Ein API-Controller, um die Bestandmeldungen vom ERP/der Middleware zu empfangen ist auch nicht viel Arbeit.

Ich habe mal so ein Plugin angefangen und einen schon wirklich sehr vollständigen Prototypen hatt ich nach 3 Abenden.. also wohl so 4-5 Stunden. 1-2 Tage voll daran arbeiten und man bekommt so etwas ohne Probleme hin. Die Zeit zum Testen natürlich nicht mit gerechnet.


QNAP TS120: Speicher erweitern

Eine QNAP TurboStation 120 hat neben der fehlenden Virtualisierung und dem fehlenden Domain Controller nur ein Problem: Es passt nur eine Festplatte rein.
Aber im Gegensatz zu vielen anderen NAS-Systemen hat die TS120 sowohl USB 3.0 als auch einen eSATA-Anschluss. Ich wollte also mal wissen wie kostengünstig ich mein NAS mit einer doch nicht ganz so großen 600GB-Festplatte um Speicher erweitern kann.

Ich habe ein sehr günstiges eSATA-Gehäuse gekauft (das alle Kabel und auch einen kleinen Schraubenzieher dabei hatte) und eine alte 500GB Notebook-HDD dort eingebaut.

bbcode-image


Ich habe dann die Festplatte im laufenden Betrieb angeschlossen und mich in der WebUI angemeldet. Die Festplatte wurde sofort erkannt.

bbcode-image


Ich konnte sie direkt als Freigabe-Ordner für andere Benutzer konfigurieren.

bbcode-image


bbcode-image


bbcode-image


Und auch unter Windows war die Festplatte sofort zu finden.

bbcode-image


Alles sehr einfach und funktioniert super. Man könnte also auch einfach ein 4x eSATA-Gehäuse mit 4x 2GB da ran hängen. Wobei mir die Idee das NAS und den Speicher zu trennen an sich auch ganz gut gefällt.

Shopware-Plugins: Bronze zertifiziert

Eines meiner Plugins hat jetzt eine Bronze-Zertifizierung. Das ist toll, dass besagt, das das Plugin öfters runter geladen und schon bewertet wurde. Wenn man das geschafft hat man die Zertifizierung aktivieren. Es soll viele Vorteile bringen und helfen das Plugin besser zu verkaufen.

Ich bin gespannt!

bbcode-image


In der Zwischenzeit wird mehr Zeit in ein andere Projekt und das XML-Export Plugin investiert bzw. so viel Zeit wie der Garten einen gerade übrig lässt.

Shopware-Plugin: Order XML-Export das Format anpassen

Die neue Version vom automatischen XML Order-Export, nutzt für openTrans2.1 XSLT und keinen PHP-Code mehr. Der Vorteil davon ist, dass so für jeden Anpassungen an der Ausgabe sehr viel einfacher werden. Man kopiert sich die vorhandene XSLT-Datei und kann die Kopie so anpassen wie man will. Im Plugin kann man die Datei dann angeben und diese anstelle der originalen XSLT-Datei verwenden.

Wenn man z.B. ein Attribute-Field zusätzlich als offiziellen openTRANS2.1 XML-Tag einbinden:

bbcode-image
Meine Datei


bbcode-image
Ohne Anpassung


bbcode-image
Mit eigener Anpassung


bbcode-image
Die neue Datei angeben und Ausgabeformat anpassen

Older posts:

Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?