Eine Einzelhandels-Weihnachtsgeschichte von Miki D. Bork
Es ist ungefähr 16:30. Die Sonne ist schon komplett untergegangen. Beladen mit viel zu viel Tüten, die auch alle schon viel zu voll sind, hetzt man durch den vorweihnachtlichen Matsch. Die Straßenlaternen spiegeln sich leicht in den nassen Steinen der Fußgängerzone, dann sie werden bei weiten von den grellen Schaufenstern der Geschäfte überstrahlt. Schaufenster säumen den Weg zu den Eingängen der Geschäfte, die nicht direkt an die Einkaufsstraße anschließen sondern weiter nach hinten versetzt sind. In diesen Tunneln, die einen von allen Seiten den Besucher mit voller Gewalt in gleisenden Licht die Vielfalt des Angebots in die Augen hämmern stehen angelehnt an die Scheiben erschöpfte Menschen. Kinder laufen in die Geschäfte und lassen die von allen Eindrücken übersättigten Menschen für einen Moment eine Art von Ruhe erfahren, die eher ein Kapitulieren vor der Gesamtsituation ist. Wo kommen wir her? Wo gehen wir hin? Was ist der Sinn des Lebens? Alle diese Fragen verlieren gerade an Bedeutung. In welchen überfüllten Kaufhaus ist das nächste Klo? Hätte man den langen Weg zum Parkhaus doch antreten sollen, um ein paar der Einkäufe im Auto abladen zu können? Wie lange hat dieses verdammte Parkhaus überhaupt noch auf? Länger als 18:00? Dann grummelt der Bauch. Getrunken hat man auch länger nichts und eine Glasflasche mit Wasser mitzuschleppen, wäre auch zu schwer. Der Schneematsch nähert sich mit jedem einzelnen Kunden immer weiter den automatischen Schiebetüren des Geschäfts.
Während die Kinder in der Spielzeugabteilung die großen Regaler mit den verschiedenen Spielzeugserien begutachten versucht der Partner unbemerkt was zu kaufen. Wenn das Bargeld reicht. Für was zu essen wird es nicht mehr reichen und man muss in eine Bank, um neues Geld zu holen. Vorher noch Kontoauszüge um zu gucken ob man noch im Budget liegt.
Die McDonalds-Filiale platz aus allen Nähten. Die obligatorischen Pizzarien sind auch voll. Unter jeden Tisch stapeln sich die Einkaufstaschen. Das Plastik ist die kleine Grenze zwischen den wertvollen Waren und dem unbändigen Kräften der Natur, der sich als Schneematsch nun auch schon der Pizzaria und den Innenraum der Schuhe der Gäste bemächtigt hat. Das gedämmte Licht und der warme Geruch der Pizza könnte einen nun fast einnicken lassen, wenn nicht diese extreme Lautstärke herrschen würde. Am Nachbartisch verhindert eine Mutter mit viel Geschrei gerade so, dass das Kind auf der Suche nach seinem Einkauf die Geschenke-Tüte öffnet. Der Bruder liest konzentriert in der Anleitung seines neuen Computerspiels. FSK? +-4 Jahre sind sicher ok, solange es nicht FSK18 ist, ist es sicher ok. Zwei Monate später wird er glücklich sein, sich das Spiel gekauft haben, weil es dann doch auf dem Index gelandet ist.
Am Ende steht man im noch kalten in einer endlosen Schlange in Richtung Ausfahrt im Parkhaus und wartet, dass man endlich dort bezahlen und in die Freiheit entlassen werden kann. Sicher versucht gerade jemand das Kleingeld, das vom Weihnachtseinkauf sich in rauen Mengen angesammelt hat, an der mit einem Menschen besetzen Parkhauskasse los zu werden. Eine Münze fällt dabei herunter.
Der Beifahrer befreit sich aus Gurt, Tüten und quetscht sich aus der Tür. Tritt in noch mehr Matsch. Hätte man sich es also sparen können die Schuhe im Parkhaus noch mal sauber zu machen, bevor man ins Auto stieg. Alle denken sich: Scheiß auf die 2 Mark.. aber es sind 2 Mark. Die Uhr interessiert es nicht und sie rückt un erbärmlich weiter und macht den Kindern klar, dass diesen Samstag genau die TV-Serie die letzte Woche mit einer Doppelfolge aufwartete heute nicht zu sehen geben wird. Showview wäre der Retter in der Not gewesen, aber mit dieser endlosen Schlange an Autos, die sich bis auf die oberste Ebene des Parkhauses erstreckt, hatte niemand gerechnet. Wie auch? Eine Frage, die man auf das nächste Jahr
verschiebt, wenn man wieder in dieser Situation ist. Du schließt genervt deine Augen. Dieses CBD-Schlafspray macht echt intensive Träume. Leider sehr teuer, aber ein paar hatten sowie noch gefragt, was du dir zu Weihnachten wünscht. Praktisch. Du musst denen nur noch kurz den Link schicken.
Daten per Criteria abfragen und in einer Table oder einer Form darzustellen oder verarbeiten ist in der Shopware 6 Administration extrem einfach und fast zu 100% genau so wie in PHP. Aber manchmal will man auch auf eine sehr spezielle Art oder Weise Daten erhalten und diese dem Benutzer direkt als Download anbieten können.
Hier ein kleines Beispiel eines CSV-Downloads der von einem API-Controller mit der Route "/api/example-module/download/csv/{id}" kommt. Man kann aber genau so gut alles per Criteria abfragen und das CSV in JavaScript bauen.
Die Methode für den Download sieht mit Controller-Lösung so aus:
Das Prinzip ist an sich sehr einfach. Man baut sich ein a-Element mit gesetzten download-Attribute und simuliert einen Click darauf. Nur hinterlegt man hier die Daten als Data-URL und nicht die URL zum Controller direkt. Das würde nicht funktionieren als dann dort die Authorization-Infos im GET-Header fehlen würden.
Die Data-URL kann eben aus Daten von einem Controller gebaut werden oder direkt aus Daten, die JavaScript aggregiert wurden.
Sehr viel einfacher als die alten Lösungen mit FileSaver-Lib und viel hin und her wandeln von Blobs.
Falls man seinen Shopware 6 in einem Shared-Hosting Paket von Cyon (Schweiz) betreibt, ist man es ja schon fast gewohnt, dass es Probleme beim Bauen der Administration über CLI gibt. Momentan gibt es wohl Probleme mit Puppeteer. Die Lösung hier ist es vor eine entsprechende Umgebungsvariable zu setzen:
export PUPPETEER_SKIP_DOWNLOAD='true'
Dann geht es wieder.. nicht schnell aber das war es dort ja noch nie.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! administration@1.0.0 build: `mode=production webpack`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the administration@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /var/www/.npm/_logs/2022-11-24T11_18_35_338Z-debug.log
sollte man gucken, ob vorher ein Fehler dieser Art aufgetreten ist
Während die Intenetnutzung im ICE mit dem Smartphone ohne Probleme geht, kann es mit Linux schnell zu Problemen kommen. Das liegt am IP-Bereich und Docker. Zwar kann sich das Gerät mit Linux ohne Probleme mit dem eigentlichen Netzwerk verbinden, aber dann kann die Seite zum bestätigen der AGBs nicht geladen werden.
Anleitung: - Mit dem WLAN verbinden
- prüfen welcher IP-Bereich zu gewiesen wurde
-
ip addr
- gucken welcher Eintrag mit dem Bereich kolliedert
- diesen Eintrag entfernen
-
Meine erste Lösung war es den MD5-Hash als Dateiname zu nehmen. Dann später kam wollte ich doch lieber ein CustomField dafür nutzen (wie ich auch schon in der Shopware 5 Version ein Attribute genutzt hatte). Funktionierte alles super bis ich dann auf ein System kam, das nicht im dev-Mode lief. Am fileName hängt wohl mehr als man denkt und ich habe gelernt, dass man in einem produktiven Shopware 6 nicht den fileName ändern sollte. Kommt mit auf meine Liste der ganz großen Shopware 6 Nein-Nein's.
Eine wirklich gutes Upgrade für den Creality Ender 3 ist das Spider Hotend des selben Herstellers. Es gibt auch eine V2.0, die von der Größe besser passen sollte, als Ersatz des Stock-Hotends. Aber die 1.0 Version ist auch schon sehr gut und bedeutend günstiger.
Mit dem Hotend ist PETG Druck bei 100-120mm/s bei 245 Grad kein Problem mehr mit dem Ender 3 (Pro). Da das Hotend aber insgesamt höher ist würde der Lüfter nun gegen den Heizblock blasen und nicht mehr aus das frischgedruckte Filament. Es gibt bei Thingiverse Ersatz, der aber bei mir am Ende zu dicht über dem Filament und auch zu dicht an der Nozzle war. Deswegen habe ich dieses Design etwas angepasst. Gedruckt mit Resin (weil der Ender 3 ja gerade im Umbau war). Funktioniert super und auch wenn man etwas Filament vom Bed im ersten Layer abstehen zieht es nicht damit direkt den gesamten Layer wieder ab.
Oft will man einfach nur den Status der Stellung anpassen, weil irgendwas mit der Bestellung nicht stimmt oder man sie auf abgeschlossen setzen will, aber der Rest über das ERP/die WaWi läuft. Man will keine Mail an den Kunden senden. Leider ist die Mail immer direkt aktiviert und man muss immer daran denken diese zu deaktivieren.
Nervig.. also ein tolles kleines (wirklich kleines) Plugin-Projekt:
die Art und Weise erinnert mich etwas wie ich damals bei meinen cJSv2-Framework die Controller an Elemente gebunden und initialisiert habe.. der default-Name der Init-Methode war da auch init.
Der DomAccess-Helper ist super und sollte man so verwenden. Über den kann man auch den QuerySelector nutzen und dass schützt hoffentlich davor, dass ein Haufen klassischer Webdesigner versuchen JQuery wieder da rein zu bringen. Der HttpClient ist auch nett aber man kann genau so gut direkt mit fetch() arbeiten, wenn man nicht unbedingt irgendwelche Steinzeit Browser supporten möchte. Aber besonder mag ich von den Helpern DeviceDetection.isTouchDevice() weil man damit einfach unterschieden kann ob man gerade ein Touch oder ein MouseEnter
Event nutzen muss.
Wenn man in der Storefront an einem eignem JavaScript-Plugin arbeitet ist es beim Debuggen, oft nervig, dass der JavaScript Code nicht direkt lesbar ist. Oft weiß man beim eigenen Code direkt was los ist, aber gerade wenn 3rd Party Plugins auch mit rein spielen, kommt man nicht drum herum sich Exceptions mit lesbaren Stacktrace anzeigen zu lassen.
Das ist zum Glück extrem einfach:
* Port 9998 aus dem Docker-Container durchleiten
* Dem SalesChannel in dem man entwickelt die Domain "localhost" zu ordnen
* das Script bin/watch-storefront.sh starten
Nun kann man localhost:9998 im Browser aufrufen. Der JavaScript Code ist lesbar und Änderungen werden sofort übernommen ohne dass man die Storefront neu bauen muss.
Einmal schnell gucken, wie viele und welche Art von Produkten über welchen SalesChannel und URL zu kaufen sind.
SELECT x.url, 'single' type, count(x.id)
FROM (
select d.url, p.id, p.parent_id, count(p2.id) children from sales_channel_domain d
join sales_channel sc on d.sales_channel_id = sc.id
join product_visibility pv on pv.sales_channel_id = sc.id
join product p on p.id = pv.product_id
left outer join product p2 on p.id = p2.parent_id
where sc.active = 1
group by d.url, p.id, p.parent_id
)x
WHERE x.parent_id is null and x.children < 1
group by x.url
union all
SELECT x.url, 'main' type, count(x.id)
FROM (
select d.url, p.id, p.parent_id, count(p2.id) children from sales_channel_domain d
join sales_channel sc on d.sales_channel_id = sc.id
join product_visibility pv on pv.sales_channel_id = sc.id
join product p on p.id = pv.product_id
left outer join product p2 on p.id = p2.parent_id
where sc.active = 1
group by d.url, p.id, p.parent_id
)x
WHERE x.parent_id is null and x.children > 0
group by x.url
union all
SELECT x.url, 'variant' type, count(x.id)
FROM (
select d.url, p2.id, p2.parent_id, 0 children from sales_channel_domain d
join sales_channel sc on d.sales_channel_id = sc.id
join product_visibility pv on pv.sales_channel_id = sc.id
join product p on p.id = pv.product_id
left outer join product p2 on p.id = p2.parent_id
where sc.active = 1
)x
group by x.url
Gerade in Migrations kommt man manchmal in darum herum mit den UUIDs arbeiten zu müssen. Da es binary-Daten sind muss man etwas mit den anstellen, um die aus Shopware 6 bekannte Darstellung zu erreichen und auch um diese wieder die in Datenbank zu bekommen.
Lesen der Id: Um die aus Shopware 6 gewohnte Darstellung zu bekommen muss man in MySQL die HEX-Function verwenden. Zusätzlich muss der String noch in Kleinbuchstaben umgewandelt werden.
Schreiben der Id: Zuerst wieder alles in Großbuchstaben umwandelnt. Dann muss mit der MySQL-Function UNHEX der Hex-String wieder in binary Data umgewandelt werden.
Es bleibt zwar etwas umständlich, aber ist damit durch aus handhabbar. Da es in dem Sinne kein Autoincrement gibt für die UUIDs hilft dann dort Uuid::randomHex().