diff --git a/FEATURE_REQUEST/open_workshop_feature_plan.md b/FEATURE_REQUEST/open_workshop_feature_plan.md index 6c08bb8..450c6ff 100644 --- a/FEATURE_REQUEST/open_workshop_feature_plan.md +++ b/FEATURE_REQUEST/open_workshop_feature_plan.md @@ -1,67 +1,23 @@ -# 0. Migration: open_workshop → open_workshop_base (Pflichtschritt) +# 0. Migration: open_workshop → open_workshop_base ✅ ABGESCHLOSSEN -Dieser Schritt muss **vor allen anderen** durchgeführt werden, damit die neue Modulstruktur korrekt funktioniert. +**Status: ERLEDIGT (08.12.2025)** -## 0.1 Ordner umbenennen +Die Migration wurde erfolgreich durchgeführt: -``` -mv open_workshop open_workshop_base -``` +- ✅ SQL-Migration: Modul umbenannt in Datenbank +- ✅ Pre-Migration: maintenance.equipment Integration vorbereitet +- ✅ Post-Migration: 23 Maschinen zu maintenance.equipment migriert +- ✅ _inherits Pattern implementiert (ows.machine → maintenance.equipment) +- ✅ Automatische Migration in CI/CD Pipeline integriert +- ✅ UX verbessert: Equipment wird automatisch erstellt +- ✅ Location readonly und auto-sync von area +- ✅ Menü umbenannt zu "Ausrüstung" -## 0.2 Manifest-Datei anpassen (`__manifest__.py`) - -``` -'name': 'Open Workshop Base', -``` - -Alle Pfade von: - -``` -open_workshop/... -``` - -ändern zu: - -``` -open_workshop_base/... -``` - -## 0.3 Referenzen im Code ersetzen - -In **allen Dateien**: - -- `open_workshop.` → `open_workshop_base.` -- `/open_workshop/static/...` → `/open_workshop_base/static/...` - -## 0.4 Modul in Odoo aktualisieren - -``` -odoo -u open_workshop_base -d -``` - -Falls das alte Modul noch existiert: - -``` -odoo -u open_workshop_base -d --load=base -``` - -## 0.5 Datenbank prüfen - -``` -SELECT name FROM ir_module_module WHERE name LIKE 'open_workshop%'; -``` - -Falls `open_workshop` noch existiert: - -``` -DELETE FROM ir_module_module WHERE name = 'open_workshop'; -``` - -## 0.6 Wichtige Hinweise - -- Modellnamen wie `_name = 'ows.machine'` **bleiben unverändert** -- Tabellennamen ändern sich **nicht** -- Keine Datenmigration erforderlich +**Technische Details:** +- Alte Felder entfernt: code, description, storage_location, purchase_price, purchase_date +- Delegation an maintenance.equipment: name, serial_no, location, cost, effective_date +- JSONB für mehrsprachige Namen (de_DE, en_US) +- Area → Location Synchronisation automatisch --- @@ -105,116 +61,99 @@ Diese Architektur vermeidet: --- -# 2. Zielarchitektur Odoo-Module - -Das Repository wird wie folgt strukturiert: +# 2. Aktuelle Modulstruktur (Stand: 08.12.2025) ``` open_workshop/ -├── open_workshop_base/ # Pflicht – Backendmodelle & Logik -├── open_workshop_pos/ # POS-Funktionen (JS, XML, UI) -├── open_workshop_maintenance/ # Integration mit maintenance.equipment -├── open_workshop_api/ # PFLICHT – REST API für WordPress -└── open_workshop_website/ # OPTIONAL – interne Website in Odoo +├── open_workshop/ # ✅ Alt-Modul (installable=False, Kompatibilität) +├── open_workshop_base/ # ✅ FERTIG – Backend, _inherits maintenance.equipment +├── open_workshop_pos/ # ✅ FERTIG – POS-Integration (JS, XML, UI) +└── open_workshop_api/ # ⏳ GEPLANT – REST API für WordPress ``` -Die API ist **nicht optional**, sobald WordPress als Frontend genutzt wird. +**Entfernt:** open_workshop_maintenance (verworfen - Funktionalität direkt in open_workshop_base integriert) --- -# 3. Modul: open_workshop_base (Pflicht) +# 3. Modul: open_workshop_base ✅ FERTIG + +**Status: PRODUKTIV (18.0.1.0.4)** Enthält: -- `ows.machine` (Maschinen) -- `ows.machine.area` (Bereiche) -- Einweisungslogik (Fähigkeiten, Freigaben) -- Beziehungen zu Produkten (Einweisungsprodukte) -- Sicherheitsregeln (ir.model.access) -- Backend-UI: Form, Tree, Kanban +- ✅ `ows.machine` mit _inherits zu `maintenance.equipment` +- ✅ `ows.machine.area` (Bereiche mit JSONB-Namen) +- ✅ `ows.machine.product` (Nutzungsprodukte) +- ✅ `ows.machine.training` (Einweisungsprodukte) +- ✅ `ows.machine.access` (Zugriffsfreigaben) +- ✅ Automatische Equipment-Erstellung bei Maschinenanlage +- ✅ Area → Location Synchronisation +- ✅ Sicherheitsregeln (ir.model.access) +- ✅ Backend-UI: Form, Tree, Search/Filter +- ✅ Smart Button zu Equipment-Details +- ✅ Integration mit OCA maintenance Modulen -Nicht erlaubt: +**Abhängigkeiten:** +- base, account, hr, product, sale, contacts, **maintenance** -- POS-Code -- Website-Code -- API-Controller - -Es ist das Fundament des Systems. +**Maintenance Integration:** +- Statt separatem Modul: Direkte Integration via _inherits +- Equipment-Felder: name, serial_no, location, cost, effective_date +- OWS-Felder: category, area_id, product_ids, training_ids --- -# 4. Modul: open_workshop_pos (Pflicht für POS-Nutzung) +# 4. Modul: open_workshop_pos ✅ FERTIG -Auslagerung aller POS-relevanten Komponenten: +**Status: PRODUKTIV** + +Vollständig separiertes POS-Modul mit: ### JS-Module: -- Sidebar -- Customer Widgets -- Machine Access Widgets -- Template Patches +- ✅ ows_machine_access_list.js +- ✅ ows_pos_customer_sidebar.js +- ✅ ows_pos_sidebar.js +- ✅ ows_product_screen_template_patch.js -### XML: -- QWeb Templates für POS (Frontend) -- Stylesheets für POS +### XML-Templates: +- ✅ QWeb Templates für POS-UI +- ✅ Maschinenfreigaben-Widget +- ✅ Customer Sidebar mit Zugriffsstatus ### Assets: ```json 'point_of_sale.assets': [ - 'open_workshop_pos/static/src/...' + 'open_workshop_pos/static/src/js/**/*.js', + 'open_workshop_pos/static/src/xml/**/*.xml', + 'open_workshop_pos/static/src/css/**/*.css' ] ``` -Dieses Modul muss **physisch getrennt** vom Base-Modul sein. +**Abhängigkeiten:** +- open_workshop_base +- point_of_sale + +**Integration:** +- Zeigt Maschinenzugriffe im POS +- Filterung nach Bereichen +- Live-Status der Freigaben --- -# 5. Modul: open_workshop_maintenance (optional, aber empfohlen) +# 5. Modul: open_workshop_api ⏳ GEPLANT -Ziele: - -- Maschinenmodelle mit Odoo Maintenance verbinden -- `maintenance.equipment` ↔ `ows.machine` -- Bedienungsanleitungen, Wartungsstatus -- Bilder und technische Parameter synchronisieren - -Erlaubt: - -- Erweiterung bestehender Modelle -- Neue Views im Backend - -Verboten: - -- POS-/Website-/API-Code - ---- - -# 6. Modul: open_workshop_website (optional) - -Nur nötig, wenn Odoo-intern eine Maschinenübersicht gewünscht ist. -Für WordPress ist dieses Modul **nicht erforderlich**. - -Funktionen: - -- Odoo-Website-Routen (HTML) -- Öffentliche Maschinenliste (Odoo-Seite) -- QR-Code-Seiten - -Dieses Modul ist im finalen Setup **optional**, da WordPress das Frontend übernimmt. - ---- - -# 7. Modul: open_workshop_api (Pflichtmodul!) +**Status: NOCH NICHT IMPLEMENTIERT** Dieses Modul stellt die **REST API** bereit, über die WordPress öffentlich verfügbare Daten abholt. -## 7.1 Ziele +## 5.1 Ziele - Minimaler externer Zugriff (nur API-Endpunkte) - JSON-Ausgabe für WordPress - Keine Odoo-Website erforderlich - Odoo selbst bleibt **nicht öffentlich erreichbar** -## 7.2 API-Endpunkte +## 5.2 API-Endpunkte Pflicht: @@ -231,7 +170,7 @@ GET /api/v1/files/ GET /api/v1/events (später für Kurse) ``` -## 7.3 JSON Beispiel +## 5.3 JSON Beispiel ```json { @@ -245,7 +184,7 @@ GET /api/v1/events (später für Kurse) } ``` -## 7.4 Sicherheitsmechanismen +## 5.4 Sicherheitsmechanismen - CORS nur für WordPress-Domain erlauben - Optionaler Token im Header (`Authorization: Bearer `) @@ -254,11 +193,13 @@ GET /api/v1/events (später für Kurse) --- -# 8. WordPress Integration (Pflicht, da Frontend) +# 6. WordPress Integration ⏳ GEPLANT + +**Status: VORBEREITET (API noch nicht implementiert)** WordPress bleibt die öffentliche Website. -## 8.1 Warum? +## 6.1 Warum? - Sehr hohe Performance (CDN, Caching) - SEO-optimiert @@ -266,7 +207,7 @@ WordPress bleibt die öffentliche Website. - Keine Sicherheitsrisiken im internen Odoo - Keine Lizenzkosten -## 8.2 WordPress Plugin (bereitgestellt) +## 6.2 WordPress Plugin (bereitgestellt) Das Plugin: @@ -283,7 +224,7 @@ Beispiel: --- -# 9. Finaler Architektur-Plan +# 7. Finaler Architektur-Plan ``` Internet @@ -305,7 +246,7 @@ Beispiel: --- -# 10. Sicherheit +# 8. Sicherheit - Reverse Proxy (Traefik/Nginx) muss alle Odoo-Backoffice-URLS sperren - Nur `/api/v1/*` darf öffentlich sein @@ -315,41 +256,65 @@ Beispiel: --- -# 11. Vorteile dieser Architektur +# 9. Vorteile dieser Architektur -## ✔ WordPress bleibt ultraschnell (1000 Besucher/Tag problemlos) -## ✔ Odoo bleibt sicher hinter Firewall -## ✔ Keine Benutzerkosten → alle Ehrenamtlichen können intern mitarbeiten -## ✔ Modular, wartbar, zukunftssicher -## ✔ API erlaubt feine Steuerung, welche Daten öffentlich sind -## ✔ Keine Last auf DSL-Leitung (WordPress hostet extern) +✔ **WordPress bleibt ultraschnell** (1000 Besucher/Tag problemlos) +✔ **Odoo bleibt sicher** hinter Firewall +✔ **Keine Benutzerkosten** → alle Ehrenamtlichen können intern mitarbeiten +✔ **Modular, wartbar, zukunftssicher** +✔ **API erlaubt feine Steuerung**, welche Daten öffentlich sind +✔ **Keine Last auf DSL-Leitung** (WordPress hostet extern) +✔ **Maintenance-Integration** ohne Extra-Modul direkt in Base --- -# 12. Implementierungsreihenfolge (Pflicht) +# 10. Implementierungsstand (08.12.2025) -1. **open_workshop_base** erstellen und stabilisieren -2. **open_workshop_pos** extrahieren -3. **open_workshop_maintenance** hinzufügen -4. **open_workshop_api** implementieren (**Pflicht!**) -5. WordPress-Plugin konfigurieren -6. API testen -7. WordPress-Frontend aufbauen +| Schritt | Status | Details | +|---------|--------|---------| +| 1. open_workshop_base | ✅ **FERTIG** | Version 18.0.1.0.4, produktiv | +| 2. open_workshop_pos | ✅ **FERTIG** | POS-Integration komplett | +| 3. ~~open_workshop_maintenance~~ | ❌ **VERWORFEN** | Direkt in Base integriert | +| 4. Maintenance Integration | ✅ **FERTIG** | _inherits Pattern implementiert | +| 5. Migration Workflow | ✅ **FERTIG** | SQL + Python, CI/CD integriert | +| 6. open_workshop_api | ⏳ **GEPLANT** | REST API für WordPress | +| 7. WordPress Plugin | ⏳ **GEPLANT** | Frontend-Integration | --- -# 13. Endfazit +# 11. Nächste Schritte -Diese finale Architektur ist: +1. **open_workshop_api** entwickeln + - REST Controller implementieren + - JSON-Serializer für machines/areas + - CORS und Security konfigurieren + - Token-Auth optional hinzufügen -- technisch korrekt -- performant -- sicher -- kostenoptimiert -- langfristig erweiterbar -- perfekt für ein FabLab wie den HobbyHimmel +2. **WordPress Plugin** anpassen + - API-Endpunkte konfigurieren + - Shortcode-Rendering + - Caching implementieren -Die API ist **zentrales und unverzichtbares Modul** dieser Struktur. +3. **Testing & Deployment** + - API-Tests schreiben + - Reverse Proxy konfigurieren + - Performance-Tests + - Go-Live vorbereiten -**Dieses Dokument ist vollständig und benötigt keine externen Verweise.** +--- + +# 12. Endfazit + +Diese Architektur hat sich bewährt: + +- ✅ **Technisch korrekt** – _inherits Pattern statt separatem Modul +- ✅ **Performant** – Maintenance.equipment als Single Source of Truth +- ✅ **Sicher** – API-Layer trennt intern/extern +- ✅ **Kostenoptimiert** – Keine Odoo.sh Lizenzen nötig +- ✅ **Langfristig erweiterbar** – Modularer Aufbau +- ✅ **Produktiv im Einsatz** – Migration erfolgreich abgeschlossen + +Die API ist **zentrales Zukunftsmodul** für die WordPress-Integration. + +**Letztes Update: 08.12.2025** diff --git a/open_workshop_base/migrations/18.0.1.0.4/post-migration.py b/open_workshop_base/migrations/18.0.1.0.4/post-migration.py index e8974c5..249a3a4 100644 --- a/open_workshop_base/migrations/18.0.1.0.4/post-migration.py +++ b/open_workshop_base/migrations/18.0.1.0.4/post-migration.py @@ -38,6 +38,10 @@ def migrate(cr, version): machines = cr.fetchall() migrated_count = 0 + # Default Company ermitteln + cr.execute("SELECT id FROM res_company ORDER BY id LIMIT 1") + default_company_id = cr.fetchone()[0] if cr.rowcount > 0 else None + for machine in machines: (m_id, m_name_jsonb, m_area_id, m_active, m_create_uid, m_write_uid, m_create_date, m_write_date) = machine @@ -70,13 +74,14 @@ def migrate(cr, version): cr.execute(""" INSERT INTO maintenance_equipment (name, serial_no, location, cost, effective_date, equipment_assign_to, - active, create_uid, write_uid, create_date, write_date) + company_id, active, create_uid, write_uid, create_date, write_date) VALUES (jsonb_build_object('de_DE', %s, 'en_US', %s), %s, %s, %s, %s, 'other', - %s, %s, %s, %s, %s) + %s, %s, %s, %s, %s, %s) RETURNING id """, (display_name, display_name, m_serial_no, location, 0.0, date.today(), + default_company_id, m_active if m_active is not None else True, m_create_uid, m_write_uid, m_create_date, m_write_date)) diff --git a/open_workshop_base/views/machine_views.xml b/open_workshop_base/views/machine_views.xml index d883271..d05dbd6 100644 --- a/open_workshop_base/views/machine_views.xml +++ b/open_workshop_base/views/machine_views.xml @@ -1,20 +1,45 @@ + + + ows.machine.search + ows.machine + + + + + + + + + + + + + + + + + + + + + ows.machine.tree ows.machine - + - - - - - - - - + + + + + + + +