From 9ae8b095da9eae000bedd3c25d5f6f105c2cf57b Mon Sep 17 00:00:00 2001 From: MaPaLo76 <72209721+MaPaLo76@users.noreply.github.com> Date: Sat, 29 Mar 2025 17:28:05 +0100 Subject: [PATCH] intial version of open workshop v13.0 --- __manifest__.py | 36 +++--- data/demo_data.xml | 154 +++++++++++++++++++++++++ data/maschine.csv | 9 -- models/__init__.py | 7 +- models/machine.py | 12 -- models/ows_models.py | 65 +++++++++++ models/pos_order.py | 51 ++++++++ models/res_partner.py | 11 -- models/training.py | 29 ----- security/ir.model.access.csv | 7 +- views/machine_area_views.xml | 37 ++++++ views/machine_views.xml | 34 ++++++ views/menu_views.xml | 46 ++++++++ views/open_workshop_machine_views.xml | 54 --------- views/open_workshop_training_views.xml | 48 -------- views/res_partner_view.xml | 21 ++++ views/res_partner_views.xml | 30 ----- 17 files changed, 430 insertions(+), 221 deletions(-) create mode 100644 data/demo_data.xml delete mode 100644 data/maschine.csv delete mode 100644 models/machine.py create mode 100644 models/ows_models.py create mode 100644 models/pos_order.py delete mode 100644 models/res_partner.py delete mode 100644 models/training.py create mode 100644 views/machine_area_views.xml create mode 100644 views/machine_views.xml create mode 100644 views/menu_views.xml delete mode 100644 views/open_workshop_machine_views.xml delete mode 100644 views/open_workshop_training_views.xml create mode 100644 views/res_partner_view.xml delete mode 100644 views/res_partner_views.xml diff --git a/__manifest__.py b/__manifest__.py index 11b5792..6f18d93 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,28 +1,20 @@ { - 'name': 'Open Workshop', - 'version': '1.0', - 'author': 'Dein Name / Deine Organisation', - 'category': 'Custom', - 'summary': 'Verwaltung von Maschinen & Einweisungen in einer offenen Werkstatt', - 'description': """ -Dieses Modul fügt zwei neue Modelle hinzu: -- Maschinen (mit Metadaten) -- Maschineneinweisungen (Verknüpfung zwischen Partner und Maschine) - -Außerdem wird das Partnerformular erweitert, damit man direkt sieht, -für welche Maschinen ein Partner bereits eingewiesen ist. - """, - 'depends': [ - 'base', - 'point_of_sale', - ], + 'name': 'POS Open Workshop', + 'license': 'AGPL-3', + 'version': '13.0.1.0.0', + 'summary': 'Erstellt Maschinenfreigaben basierend auf POS-Einweisungsprodukten', + 'depends': ['point_of_sale'], + 'author': 'matthias.lotz', + 'category': 'Point of Sale', 'data': [ 'security/ir.model.access.csv', - 'views/open_workshop_machine_views.xml', - 'views/open_workshop_training_views.xml', - 'views/res_partner_views.xml', + 'views/machine_area_views.xml', + 'views/machine_views.xml', # <--- diese Zeile hinzufügen + 'views/res_partner_view.xml', + 'views/menu_views.xml', ], + 'demo': [ + 'demo/demo_data.xml', # <--- DEMO-DATEN HINZUGEFÜGT + ], 'installable': True, - 'application': True, } - diff --git a/data/demo_data.xml b/data/demo_data.xml new file mode 100644 index 0000000..3821d0e --- /dev/null +++ b/data/demo_data.xml @@ -0,0 +1,154 @@ + + + + + Fablab + 3 + + + + Holzbereich + 1 + + + + Metallbereich + 2 + + + + Elektronikbereich + 4 + + + + + Sabako Laser + sabako_laser + + + + + Prusa + prusa + + + + + Prusa MMU + prusa_mmu + + + + + 3D Delta + 3d_delta + + + + + CNC Beamicon + cnc_beamicon + + + + + + Formatkreissäge + formatkreissaege + + + + + Bandsäge + bandsaege_holz + + + + + Abricht Dickenhobel + dickenhobel + + + + + Drechselbank + drechselbank + + + + + Festool Domino Fräse + festool_domino + + + + + Maffel Duo Dübler + maffel_duo + + + + + Lamello Zeta P2 + lamello_zeta_p2 + + + + + + Kreissäge + kreissaege_metall + + + + + Bandsäge + bandsaege_metall + + + + + MIG/MAG Schweißgeräte + mig_mag + + + + + WIG Schweißgerät + wig + + + + + Schweißen allgemein + schweissen_allgemein + + + + + Drehbank + drehbank + + + + + Fräse + fraese + + + + + Abkantbank + abkantbank + + + + + + Lötkolben + loetkolben + + + + diff --git a/data/maschine.csv b/data/maschine.csv deleted file mode 100644 index 5a7410c..0000000 --- a/data/maschine.csv +++ /dev/null @@ -1,9 +0,0 @@ -Name,Maschinen-Code,Standort,Active,Beschreibung -Standbohrmaschine,M-0001,Allgemein,1,Beschreibung 1 -Kantenschleifer,M-0001,Holz,1,Beschreibung 1 -Tischfräse,M-0001,Holz,1,Beschreibung 1 -Felder Kreissäge,M-0001,Holz,1,Beschreibung 1 -Felder Abricht-Dickenhobel,M-0001,Holz,1,Beschreibung 1 -Felder Fräse,M-0001,Holz,1,Beschreibung 1 -Felder Bandsäge,M-0001,Holz,1,Beschreibung 1 -Drechselbank,M-0001,Holz,1,Beschreibung 1 diff --git a/models/__init__.py b/models/__init__.py index 5ce593d..9f91cbd 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,4 +1,5 @@ -from . import machine -from . import training -from . import res_partner +from . import ows_models +from . import pos_order + + diff --git a/models/machine.py b/models/machine.py deleted file mode 100644 index 241b6cb..0000000 --- a/models/machine.py +++ /dev/null @@ -1,12 +0,0 @@ -from odoo import models, fields, api - -class OpenWorkshopMachine(models.Model): - _name = 'open.workshop.machine' - _description = 'Open Workshop Machine' - - name = fields.Char(string='Name', required=True) - code = fields.Char(string='Maschinen-Code', help='Interner Code oder Inventar-Nr.') - location = fields.Char(string='Standort') - description = fields.Text(string='Beschreibung') - active = fields.Boolean(default=True) - diff --git a/models/ows_models.py b/models/ows_models.py new file mode 100644 index 0000000..06e17cb --- /dev/null +++ b/models/ows_models.py @@ -0,0 +1,65 @@ +from odoo import models, fields + +class OwsMachineArea(models.Model): + _name = 'ows.machine.area' + _table = "ows_machine_area" + _description = 'OWS: Maschinenbereich' + _order = 'name' + + name = fields.Char(required=True, translate=True) + color = fields.Integer(string="Farbe") + + +class OwsMachine(models.Model): + _name = 'ows.machine' + _table = 'ows_machine' + _description = 'OWS: Maschine' + + name = fields.Char(required=True, translate=True) + code = fields.Char(required=True, help="Eindeutiger Kurzcode, z.B. 'lasercutter'") + description = fields.Text() + active = fields.Boolean(default=True) + + area_id = fields.Many2one('ows.machine.area', string='Bereich') + + _sql_constraints = [ + ('code_unique', 'unique(code)', 'Maschinencode muss eindeutig sein.') + ] + + def name_get(self): + return [(rec.id, f"{rec.name} ({rec.code})") for rec in self] + + +class OwsMachineAccess(models.Model): + _name = 'ows.machine.access' + _table = 'ows_machine_access' + _description = 'OWS: Maschinenfreigabe' + _order = 'partner_id, machine_id' + + partner_id = fields.Many2one('res.partner', required=True, ondelete='cascade') + machine_id = fields.Many2one('ows.machine', required=True) + date_granted = fields.Date(default=fields.Date.today) + date_expiry = fields.Date(string="Ablaufdatum") + granted_by_pos = fields.Boolean(default=True) + + _sql_constraints = [ + ('partner_machine_unique', 'unique(partner_id, machine_id)', 'Der Kunde hat diese Freigabe bereits.') + ] + + +class OwsMachineProduct(models.Model): + _name = 'ows.machine.product' + _table = 'ows_machine_product' + _description = 'OWS: Zurordnung Produkt der Einweisung zur die Maschine' + + product_id = fields.Many2one('product.product', required=True, domain=[('available_in_pos', '=', True)], ondelete='cascade') + machine_id = fields.Many2one('ows.machine', required=True, ondelete='cascade') + +class ResPartner(models.Model): + _inherit = 'res.partner' + + machine_access_ids = fields.One2many( + 'ows.machine.access', + 'partner_id', + string='Maschinenfreigaben' + ) diff --git a/models/pos_order.py b/models/pos_order.py new file mode 100644 index 0000000..8eb1a22 --- /dev/null +++ b/models/pos_order.py @@ -0,0 +1,51 @@ +from odoo import models, fields, api + +import debugpy +import logging + +_logger = logging.getLogger(__name__) +_logger.info("✅ pos_order.py geladen") + +debugpy.listen(("0.0.0.0", 5678)) +print("✅ debugpy wartet auf Verbindung (Port 5678) ...") +# Optional: Starte erst, wenn VS Code verbunden ist +#debugpy.wait_for_client() + +class PosOrder(models.Model): + _inherit = 'pos.order' + + def _process_order(self, order, draft, existing_order): + pos_order_id = super(PosOrder, self)._process_order(order, draft, existing_order) + pos_order = self.browse(pos_order_id) + + training_products = self.env['ows.machine.product'].search([]) + product_map = { + tp.product_id.product_tmpl_id.id: tp.machine_id.id + for tp in training_products + } + + partner = pos_order.partner_id + if not partner: + _logger.info("🟡 POS-Bestellung ohne Partner – keine Freigabe möglich") + return pos_order_id + + for line in pos_order.lines: + product_tmpl_id = line.product_id.product_tmpl_id.id + machine_id = product_map.get(product_tmpl_id) + + _logger.info("🔍 Prüfe Produkt %s → Maschine ID: %s", line.product_id.display_name, machine_id) + + if machine_id: + already_exists = self.env['ows.machine.access'].search([ + ('partner_id', '=', partner.id), + ('machine_id', '=', machine_id) + ]) + if not already_exists: + self.env['ows.machine.access'].create({ + 'partner_id': partner.id, + 'machine_id': machine_id, + 'granted_by_pos': True + }) + _logger.info("✅ Maschinenfreigabe erstellt: %s für %s", machine_id, partner.name) + + return pos_order_id diff --git a/models/res_partner.py b/models/res_partner.py deleted file mode 100644 index 9d30ee0..0000000 --- a/models/res_partner.py +++ /dev/null @@ -1,11 +0,0 @@ -from odoo import models, fields - -class ResPartner(models.Model): - _inherit = 'res.partner' - - machine_training_ids = fields.One2many( - 'open.workshop.machine.training', - 'partner_id', - string='Maschineneinweisungen' - ) - diff --git a/models/training.py b/models/training.py deleted file mode 100644 index cb64bbb..0000000 --- a/models/training.py +++ /dev/null @@ -1,29 +0,0 @@ -from odoo import models, fields, api - -class OpenWorkshopMachineTraining(models.Model): - _name = 'open.workshop.machine.training' - _description = 'Machine Training for Partners' - - partner_id = fields.Many2one( - 'res.partner', - string='Partner', - required=True, - ondelete='cascade' - ) - machine_id = fields.Many2one( - 'open.workshop.machine', - string='Maschine', - required=True, - ondelete='restrict' - ) - training_date = fields.Datetime( - string='Datum der Einweisung', - default=fields.Datetime.now - ) - notes = fields.Text(string='Notizen') - - trainer_id = fields.Many2one( - 'res.users', - string='Einweiser/In' - ) - diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index 46e6374..7fb6e76 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -1,4 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_open_workshop_machine_user,access_open_workshop_machine_user,model_open_workshop_machine,base.group_user,1,1,1,1 -access_open_workshop_training_user,access_open_workshop_training_user,model_open_workshop_machine_training,base.group_user,1,1,1,1 - +access_ows_machine_access_user,ows.machine.access,model_ows_machine_access,base.group_user,1,1,1,1 +access_ows_machine_user,ows.machine,model_ows_machine,base.group_user,1,1,1,1 +access_ows_machine_product_user,ows.machine.product,model_ows_machine_product,base.group_user,1,1,1,1 +access_ows_machine_area,ows.machine.area,model_ows_machine_area,base.group_user,1,1,1,1 diff --git a/views/machine_area_views.xml b/views/machine_area_views.xml new file mode 100644 index 0000000..b5f99bf --- /dev/null +++ b/views/machine_area_views.xml @@ -0,0 +1,37 @@ + + + + Maschinenbereiche + ows.machine.area + tree,form + + + + + + + + ows.machine.area.tree + ows.machine.area + + + + + + + + + + + ows.machine.area.form + ows.machine.area + +
+ + + + +
+
+
+
diff --git a/views/machine_views.xml b/views/machine_views.xml new file mode 100644 index 0000000..82637df --- /dev/null +++ b/views/machine_views.xml @@ -0,0 +1,34 @@ + + + + ows.machine.tree + ows.machine + + + + + + + + + + + + + ows.machine.form + ows.machine + +
+ + + + + + + + + +
+
+
+
diff --git a/views/menu_views.xml b/views/menu_views.xml new file mode 100644 index 0000000..fb28579 --- /dev/null +++ b/views/menu_views.xml @@ -0,0 +1,46 @@ + + + + Maschinen + ows.machine + tree,form + + + + + Einweisungs-Produkte + ows.machine.product + tree,form + + + + + + + + + + + ows.machine.product.tree + ows.machine.product + + + + + + + + + + ows.machine.product.form + ows.machine.product + +
+ + + + +
+
+
+
diff --git a/views/open_workshop_machine_views.xml b/views/open_workshop_machine_views.xml deleted file mode 100644 index 89c2fea..0000000 --- a/views/open_workshop_machine_views.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - Maschinen - open.workshop.machine - list,form - Verwaltung aller Maschinen in der offenen Werkstatt - - - - - - - - open.workshop.machine.tree - open.workshop.machine - - - - - - - - - - - - - open.workshop.machine.form - open.workshop.machine - -
- - - - - - - - - - - -
-
-
-
- diff --git a/views/open_workshop_training_views.xml b/views/open_workshop_training_views.xml deleted file mode 100644 index f5d8c33..0000000 --- a/views/open_workshop_training_views.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - Maschineneinweisungen - open.workshop.machine.training - list,form - Verwaltung aller Maschineneinweisungen (Partner -> Maschine) - - - - - - open.workshop.machine.training.tree - open.workshop.machine.training - - - - - - - - - - - open.workshop.machine.training.form - open.workshop.machine.training - -
- - - - - - - - - - - -
-
-
-
- diff --git a/views/res_partner_view.xml b/views/res_partner_view.xml new file mode 100644 index 0000000..97bb1c7 --- /dev/null +++ b/views/res_partner_view.xml @@ -0,0 +1,21 @@ + + + res.partner.form.ows.machine.access + res.partner + + + + + + + + + + + + + + + + + diff --git a/views/res_partner_views.xml b/views/res_partner_views.xml deleted file mode 100644 index cf76d5f..0000000 --- a/views/res_partner_views.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - res.partner.form.open.workshop.inherit - res.partner - - - - - - - - - - -
- - - - - - -
-
-
-
-
-
-
-