diff --git a/models/ows_models.py b/models/ows_models.py
index 1bf2fec..325326a 100644
--- a/models/ows_models.py
+++ b/models/ows_models.py
@@ -378,17 +378,56 @@ class OwsUser(models.Model):
('partner_unique', 'unique(partner_id)', 'Jeder Partner darf nur einen OWS-Datensatz haben.')
]
+AVAILABLE_COLORS = [
+ ('#000000', 'schwarz'),
+ ('#ff0000', 'Rot'),
+ ('#E91E63', 'Pink'),
+ ('#9C27B0', 'Lila'),
+ ('#3F51B5', 'Indigo'),
+ ('#0000ff', 'Blau'),
+ ('#008000', 'Grün'),
+ ('#ffff00', 'Gelb'),
+ ('#FF9800', 'Orange'),
+ ('#795548', 'Braun'),
+ ('#1f1f1f', 'Grau'),
+]
class OwsMachineArea(models.Model):
_name = 'ows.machine.area'
- _table = "ows_machine_area"
+ _table = 'ows_machine_area'
_description = 'OWS: Maschinenbereich'
_order = 'name'
- name = fields.Char(required=True, translate=True)
- #color = fields.Integer(string="Farbe")
- color_hex = fields.Char(string="Farbe (Hex)", help="Hex-Farbcode wie #FF0000 für Rot")
+ name = fields.Char(string="Name", required=True, translate=True)
+ color_hex = fields.Selection(
+ selection=AVAILABLE_COLORS,
+ string="Farbe (Hex)",
+ required=True,
+ )
+
+ color_hex_value = fields.Char(
+ string="Farbcode",
+ compute='_compute_color_hex_value',
+ store=False
+ )
+
+ color_name = fields.Char(
+ string="Farbname",
+ compute='_compute_color_name',
+ store=False
+ )
+
+ @api.depends('color_hex')
+ def _compute_color_hex_value(self):
+ for rec in self:
+ rec.color_hex_value = rec.color_hex or ''
+
+ @api.depends('color_hex')
+ def _compute_color_name(self):
+ label_dict = dict(AVAILABLE_COLORS)
+ for rec in self:
+ rec.color_name = label_dict.get(rec.color_hex, 'Unbekannt')
class OwsMachine(models.Model):
_name = 'ows.machine'
@@ -397,13 +436,37 @@ class OwsMachine(models.Model):
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')
- product_ids = fields.One2many('ows.machine.product', 'machine_id', string="Nutzungsprodukte")
- product_names = fields.Char(string="Nutzungsprodukte Liste", compute="_compute_product_using_names", store=False,)
+ category = fields.Selection([
+ ('green', 'Kategorie 1: grün'),
+ ('yellow', 'Kategorie 2: gelb'),
+ ('red', 'Kategorie 3: rot'),
+ ], string="Sicherheitskategorie", required=True, default='red', help="Sicherheitsrelevante Maschinenkategorie:\n"
+ "- grün: keine Einweisungspflicht\n"
+ "- gelb: empfohlene Einweisung\n"
+ "- rot: Einweisung zwingend erforderlich")
+
+ category_icon = fields.Char(string="Kategorie-Symbol", compute="_compute_category_icon", store=False)
+
+ @api.depends('category')
+ def _compute_category_icon(self):
+ for rec in self:
+ icon_map = {
+ 'green': '🟢',
+ 'yellow': '🟡',
+ 'red': '🔴',
+ }
+ rec.category_icon = icon_map.get(rec.category, '⚪')
+
+ description = fields.Text(string="Gerätebeschreibung", translate=True, help="Beschreibung der Maschine oder des Geräts.")
+ active = fields.Boolean(string="Aktive", default=True, help="Ist die Maschine oder das Gerät aktiv? Inaktive Maschinen werden nicht mehr in der POS-Ansicht angezeigt.")
+ area_id = fields.Many2one('ows.machine.area', string='Bereich', help="Bereich in der Werkstatt, in dem die Maschine oder das Gerät steht.")
+ product_ids = fields.One2many('ows.machine.product', 'machine_id', string="Nutzungsprodukte", help="Dies ist das zugehörige Produkt, falls die Maschine oder das Geräte eine zeitliche Nutzungsgebühr hat.")
+ product_names = fields.Char(string="Liste der Nutzungsprodukte", compute="_compute_product_using_names", store=False,)
training_ids = fields.One2many('ows.machine.training', 'machine_id', string="Einweisungsprodukte")
- training_names = fields.Char(string="Einweisungsprodukte Liste", compute="_compute_product_training_names", store=False,)
+ training_names = fields.Char(string="Liste der Einweisungsprodukte", compute="_compute_product_training_names", store=False,)
+ storage_location = fields.Char(string="Lagerort", help="Lagerort der Maschine oder des Geräts.")
+ purchase_price = fields.Float(string="Kaufpreis", help="Kaufpreis der Maschine oder des Geräts.")
+ purchase_date = fields.Date(string="Kaufdatum", help="Kaufdatum der Maschine oder des Geräts.")
@api.depends('product_ids.product_id.name')
def _compute_product_using_names(self):
@@ -426,12 +489,34 @@ class OwsMachine(models.Model):
@api.model
def get_access_list_grouped(self, partner_id):
+ """
+ Gibt eine gruppierte Liste von Maschinenzugängen für einen bestimmten Partner zurück. Diese Funktion wird in
+ Odoo POS Frontend verwendet um die Ansicht zu erzeugen auf Welche Maschinen der Partner Zugriff hat.
+
+ Für einen gegebenen Partner (über die partner_id) werden alle Maschinenbereiche (areas) abgefragt.
+ Für jeden Bereich wird geprüft, auf welche Maschinen der Partner Zugriff hat. Das Ergebnis wird
+ als Liste von Bereichen mit jeweils zugehörigen Maschinen und Zugriffsstatus zurückgegeben.
+
+ Zusätzlich werden sicherheitsrelevante Informationen des Partners (wie Sicherheitsunterweisung,
+ Sicherheits-ID, RFID-Karte und Geburtstag) aus dem zugehörigen ows_user ermittelt und mitgeliefert.
+
+ Args:
+ partner_id (int): Die ID des Partners, für den die Zugriffsübersicht erstellt werden soll.
+
+ Returns:
+ dict: Ein Dictionary mit folgenden Schlüsseln:
+ - 'access_by_area': Liste von Bereichen mit Maschinen und Zugriffsstatus.
+ - 'security_briefing': Sicherheitsunterweisung des Nutzers (bool oder False).
+ - 'security_id': Sicherheits-ID des Nutzers (str oder '').
+ - 'rfid_card': RFID-Kartennummer des Nutzers (str oder '').
+ - 'birthday': Geburtstag des Nutzers (str oder '').
+ """
+ partner = self.env['res.partner'].browse(partner_id)
areas = self.env['ows.machine.area'].search([], order="name")
- _logger.info("🔍 Maschinenbereiche: %s", areas.mapped('name'))
- _logger.info("🔍 Partner_id: %s", partner_id)
- res = []
+
+ access_by_area = []
for area in areas:
- machines = self.search([('area_id', '=', area.id)], order="name")
+ machines = self.search([('area_id', '=', area.id), ('category', '=', 'red')], order="name")
machine_list = []
for machine in machines:
has_access = bool(self.env['ows.machine.access'].search([
@@ -442,12 +527,21 @@ class OwsMachine(models.Model):
'name': machine.name,
'has_access': has_access,
})
- res.append({
- 'area': area.name,
- 'color_hex': area.color_hex or '#000000',
- 'machines': machine_list
- })
- return res
+ if machine_list:
+ access_by_area.append({
+ 'area': area.name,
+ 'color_hex': area.color_hex or '#000000',
+ 'machines': machine_list
+ })
+
+ user = partner.ows_user_id[:1]
+ return {
+ 'access_by_area': access_by_area,
+ 'security_briefing': user.security_briefing if user else False,
+ 'security_id': user.security_id if user else '',
+ 'rfid_card': user.rfid_card if user else '',
+ 'birthday': user.birthday if user else '',
+ }
class OwsMachineAccess(models.Model):
diff --git a/static/src/js/machine_access_sidebar.js b/static/src/js/machine_access_sidebar.js
index f94cb2b..2cf1dfa 100644
--- a/static/src/js/machine_access_sidebar.js
+++ b/static/src/js/machine_access_sidebar.js
@@ -53,7 +53,7 @@ odoo.define('open_workshop.machine_access_sidebar', function (require) {
}).then(function (result) {
partner.create_date = partner.create_date && partner.create_date.substring(0, 10);
var html = QWeb.render('PartnerMachineAccessList', {
- areas: result || [],
+ areas: result.access_by_area || [],
partner: partner,
});
self.$('.access-content').html(html);
diff --git a/views/machine_views.xml b/views/machine_views.xml
index 0dd3ec6..a2b3fc9 100644
--- a/views/machine_views.xml
+++ b/views/machine_views.xml
@@ -6,30 +6,44 @@
ows.machine
+
+
+
+
+
-
- ows.machine.form
- ows.machine
-
-