feat(dokuwiki): Add partner fields, editable smileys, category icon, and mass sync wizard
- Add partner_id and partner_ref template placeholders for supplier information - Implement editable status smiley field in maintenance.equipment.status - Add UI views for editing smileys in Odoo (Wartung → Konfiguration → Equipment Status) - Fix category field bug: use ows_category instead of category_id for security category - Add category_icon placeholder displaying emoji indicators (🔴/🟡/🟢) - Implement mass synchronization wizard (Wartung → Konfiguration → Wiki-Synchronisation) - Sync all equipment or filter by area - Sync only unsynchronized equipment - Force-sync option to overwrite existing documentation pages - Statistics display with error reporting - Add security access rules for wizard - Update README with new placeholders
This commit is contained in:
parent
3fa050f153
commit
a5f8fd32c3
|
|
@ -7,12 +7,15 @@ Basis-Felder (maintenance.equipment):
|
|||
{model} - Modell
|
||||
{category} - Kategoriename
|
||||
{status} - Status (aus status_id)
|
||||
{status_smiley} - Status als Smiley (aus status_id.smiley Feld, z.B. :-) oder :-()
|
||||
{location} - Standort
|
||||
{ows_area} - Bereichsname
|
||||
{assign_date} - Zuweisungsdatum (formatiert)
|
||||
{cost} - Kosten
|
||||
{warranty_date} - Garantiedatum (formatiert)
|
||||
{note} - Notizen
|
||||
{partner_id} - Lieferant (Name)
|
||||
{partner_ref} - Lieferanten-Referenz
|
||||
Spezial-Felder:
|
||||
|
||||
{view_type} - "Bereich" oder "Einsatzzweck"
|
||||
|
|
@ -32,4 +35,5 @@ ows.machine Felder (falls verknüpft):
|
|||
{ows_machine_id.serial_no} - Seriennummer
|
||||
{ows_machine_id.location} - Standort
|
||||
{ows_machine_id.note} - Notizen
|
||||
{ows_machine_id.category} - Kategorie
|
||||
{ows_machine_id.category} - Sicherheitskategorie (red/yellow/green)
|
||||
{ows_machine_id.category_icon} - Kategorie-Icon als Emoji (🔴/🟡/🟢)
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from . import models
|
||||
from . import wizard
|
||||
from .hooks import post_init_hook
|
||||
|
|
|
|||
|
|
@ -37,13 +37,17 @@ ACL:
|
|||
'depends': [
|
||||
'open_workshop_base',
|
||||
'maintenance',
|
||||
'maintenance_equipment_status',
|
||||
],
|
||||
'external_dependencies': {
|
||||
'python': ['dokuwiki'],
|
||||
},
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'data/ir_config_parameter.xml',
|
||||
'views/maintenance_equipment_views.xml',
|
||||
'views/maintenance_equipment_status_views.xml',
|
||||
'wizard/equipment_wiki_sync_wizard_views.xml',
|
||||
],
|
||||
'post_init_hook': 'post_init_hook',
|
||||
'installable': True,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from . import dokuwiki_client
|
||||
from . import maintenance_equipment
|
||||
from . import maintenance_equipment_status
|
||||
from . import res_config_settings
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ class MaintenanceEquipment(models.Model):
|
|||
values = {
|
||||
# Spezielle Werte
|
||||
'wiki_doku_page': doku_page_id,
|
||||
'wiki_doku_link': f"[[{doku_page_id}|✏️ Zentrale Dokumentation bearbeiten]]",
|
||||
'wiki_doku_link': f"[[{doku_page_id}| Wiki Dokumentation]]",
|
||||
'odoo_link': f"[[{odoo_equipment_url}|🔗 In Odoo öffnen]]",
|
||||
'odoo_url': odoo_equipment_url,
|
||||
'sync_datetime': datetime.now().strftime('%d.%m.%Y %H:%M'),
|
||||
|
|
@ -234,12 +234,15 @@ class MaintenanceEquipment(models.Model):
|
|||
'ows_area': self.ows_area_id.name if self.ows_area_id else '',
|
||||
'category': self.category_id.name if self.category_id else '',
|
||||
'status': self.status_id.name if self.status_id else '',
|
||||
'status_smiley': self.status_id.smiley if self.status_id and self.status_id.smiley else '',
|
||||
'location': self.location or '',
|
||||
'assign_date': self.assign_date.strftime('%d.%m.%Y') if self.assign_date else '',
|
||||
'cost': str(self.cost) if self.cost else '',
|
||||
'warranty_date': self.warranty_date.strftime('%d.%m.%Y') if self.warranty_date else '',
|
||||
'color': str(self.color) if self.color else '',
|
||||
'note': self.note or '',
|
||||
'partner_id': self.partner_id.name if self.partner_id else '',
|
||||
'partner_ref': self.partner_ref or '',
|
||||
}
|
||||
|
||||
# ows.machine Felder hinzufügen (falls verknüpft)
|
||||
|
|
@ -259,8 +262,10 @@ class MaintenanceEquipment(models.Model):
|
|||
ows_machine_fields['ows_machine_id.location'] = machine.location
|
||||
if hasattr(machine, 'note'):
|
||||
ows_machine_fields['ows_machine_id.note'] = machine.note or ''
|
||||
if hasattr(machine, 'category_id') and machine.category_id:
|
||||
ows_machine_fields['ows_machine_id.category'] = machine.category_id.name
|
||||
if hasattr(machine, 'ows_category') and machine.ows_category:
|
||||
ows_machine_fields['ows_machine_id.category'] = machine.ows_category
|
||||
if hasattr(machine, 'ows_category_icon') and machine.ows_category_icon:
|
||||
ows_machine_fields['ows_machine_id.category_icon'] = machine.ows_category_icon
|
||||
|
||||
values.update(ows_machine_fields)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class MaintenanceEquipmentStatus(models.Model):
|
||||
_inherit = 'maintenance.equipment.status'
|
||||
|
||||
smiley = fields.Char(
|
||||
string='Smiley',
|
||||
help='DokuWiki Smiley für diesen Status (z.B. :-) oder :-()'
|
||||
)
|
||||
2
open_workshop_dokuwiki/security/ir.model.access.csv
Normal file
2
open_workshop_dokuwiki/security/ir.model.access.csv
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_equipment_wiki_sync_wizard,equipment.wiki.sync.wizard,model_equipment_wiki_sync_wizard,base.group_user,1,1,1,1
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="maintenance_equipment_status_form_view" model="ir.ui.view">
|
||||
<field name="name">maintenance.equipment.status.form.dokuwiki</field>
|
||||
<field name="model">maintenance.equipment.status</field>
|
||||
<field name="inherit_id" ref="maintenance_equipment_status.maintenance_equipment_status_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="name" position="after">
|
||||
<field name="smiley" placeholder="z.B. :-) oder :-("/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="maintenance_equipment_status_tree_view" model="ir.ui.view">
|
||||
<field name="name">maintenance.equipment.status.tree.dokuwiki</field>
|
||||
<field name="model">maintenance.equipment.status</field>
|
||||
<field name="inherit_id" ref="maintenance_equipment_status.maintenance_equipment_status_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="name" position="after">
|
||||
<field name="smiley" optional="show"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
2
open_workshop_dokuwiki/wizard/__init__.py
Normal file
2
open_workshop_dokuwiki/wizard/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from . import equipment_wiki_sync_wizard
|
||||
123
open_workshop_dokuwiki/wizard/equipment_wiki_sync_wizard.py
Normal file
123
open_workshop_dokuwiki/wizard/equipment_wiki_sync_wizard.py
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EquipmentWikiSyncWizard(models.TransientModel):
|
||||
_name = 'equipment.wiki.sync.wizard'
|
||||
_description = 'Massen-Synchronisation von Equipment zu DokuWiki'
|
||||
|
||||
sync_mode = fields.Selection([
|
||||
('all', 'Alle Equipment'),
|
||||
('area', 'Nach Bereich filtern'),
|
||||
('unsynced', 'Nur nicht synchronisierte'),
|
||||
], string='Synchronisations-Modus', default='all', required=True)
|
||||
|
||||
ows_area_id = fields.Many2one(
|
||||
'ows.machine.area',
|
||||
string='Bereich',
|
||||
help='Nur Equipment aus diesem Bereich synchronisieren'
|
||||
)
|
||||
|
||||
force_sync = fields.Boolean(
|
||||
string='Zentrale Doku-Seiten überschreiben',
|
||||
default=False,
|
||||
help='Auch bereits existierende zentrale Dokumentationsseiten neu generieren (VORSICHT: Überschreibt manuell erstellten Inhalt!)'
|
||||
)
|
||||
|
||||
# Statistik-Felder (nach Sync)
|
||||
total_count = fields.Integer(string='Gefunden', readonly=True)
|
||||
success_count = fields.Integer(string='Erfolgreich', readonly=True)
|
||||
error_count = fields.Integer(string='Fehler', readonly=True)
|
||||
error_messages = fields.Text(string='Fehlermeldungen', readonly=True)
|
||||
|
||||
@api.onchange('sync_mode')
|
||||
def _onchange_sync_mode(self):
|
||||
"""Bereich-Feld nur bei 'area' Modus anzeigen"""
|
||||
if self.sync_mode != 'area':
|
||||
self.ows_area_id = False
|
||||
|
||||
def action_sync_equipment(self):
|
||||
"""
|
||||
Hauptaktion: Equipment synchronisieren basierend auf gewähltem Modus
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
# Equipment-Liste basierend auf Modus ermitteln
|
||||
domain = []
|
||||
|
||||
if self.sync_mode == 'area':
|
||||
if not self.ows_area_id:
|
||||
raise UserError("Bitte einen Bereich auswählen!")
|
||||
domain.append(('ows_area_id', '=', self.ows_area_id.id))
|
||||
elif self.sync_mode == 'unsynced':
|
||||
domain.append(('wiki_synced', '=', False))
|
||||
|
||||
# Equipment finden
|
||||
equipment_records = self.env['maintenance.equipment'].search(domain)
|
||||
|
||||
if not equipment_records:
|
||||
raise UserError("Keine Equipment-Einträge gefunden, die synchronisiert werden können!")
|
||||
|
||||
total = len(equipment_records)
|
||||
success = 0
|
||||
errors = 0
|
||||
error_list = []
|
||||
|
||||
_logger.info(f"Starte Wiki-Synchronisation für {total} Equipment-Einträge")
|
||||
|
||||
# Jeden Equipment-Eintrag synchronisieren
|
||||
for equipment in equipment_records:
|
||||
try:
|
||||
# Prüfen ob Bereich gesetzt ist
|
||||
if not equipment.ows_area_id:
|
||||
error_msg = f"{equipment.name}: Kein Bereich gesetzt"
|
||||
error_list.append(error_msg)
|
||||
errors += 1
|
||||
_logger.warning(error_msg)
|
||||
continue
|
||||
|
||||
# Force-Sync: Zentrale Doku-Seite überschreiben
|
||||
if self.force_sync and equipment.wiki_doku_id:
|
||||
doku_page_id = equipment._get_wiki_doku_page_id()
|
||||
doku_content = equipment._generate_wiki_doku_page_content()
|
||||
dokuwiki_client = self.env['dokuwiki.client']
|
||||
dokuwiki_client.create_page(
|
||||
doku_page_id,
|
||||
doku_content,
|
||||
f"Überschrieben von Massen-Sync: {equipment.name}"
|
||||
)
|
||||
_logger.info(f"Zentrale Doku-Seite überschrieben: {doku_page_id}")
|
||||
|
||||
# Standard-Synchronisation
|
||||
equipment.sync_to_dokuwiki()
|
||||
success += 1
|
||||
_logger.info(f"✓ {equipment.name} synchronisiert")
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"{equipment.name}: {str(e)}"
|
||||
error_list.append(error_msg)
|
||||
errors += 1
|
||||
_logger.error(f"✗ {error_msg}")
|
||||
|
||||
# Statistik speichern
|
||||
self.write({
|
||||
'total_count': total,
|
||||
'success_count': success,
|
||||
'error_count': errors,
|
||||
'error_messages': '\n'.join(error_list) if error_list else 'Keine Fehler',
|
||||
})
|
||||
|
||||
# Ergebnis-View anzeigen
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Wiki-Synchronisation Ergebnis',
|
||||
'res_model': 'equipment.wiki.sync.wizard',
|
||||
'view_mode': 'form',
|
||||
'res_id': self.id,
|
||||
'target': 'new',
|
||||
'context': {'show_result': True},
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Wizard Form View -->
|
||||
<record id="equipment_wiki_sync_wizard_form" model="ir.ui.view">
|
||||
<field name="name">equipment.wiki.sync.wizard.form</field>
|
||||
<field name="model">equipment.wiki.sync.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Wiki-Synchronisation">
|
||||
<group invisible="context.get('show_result', False)">
|
||||
<group>
|
||||
<field name="sync_mode" widget="radio"/>
|
||||
<field name="ows_area_id" invisible="sync_mode != 'area'" required="sync_mode == 'area'"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="force_sync"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<!-- Ergebnis-Anzeige -->
|
||||
<group invisible="not context.get('show_result', False)">
|
||||
<group>
|
||||
<field name="total_count"/>
|
||||
<field name="success_count"/>
|
||||
<field name="error_count"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="error_messages" widget="text" colspan="2" invisible="error_count == 0"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<footer>
|
||||
<button string="Synchronisieren"
|
||||
name="action_sync_equipment"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
invisible="context.get('show_result', False)"/>
|
||||
<button string="Schließen"
|
||||
special="cancel"
|
||||
class="btn-secondary"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Menu-Action -->
|
||||
<record id="action_equipment_wiki_sync_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Wiki-Synchronisation</field>
|
||||
<field name="res_model">equipment.wiki.sync.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{}</field>
|
||||
</record>
|
||||
|
||||
<!-- Menu-Eintrag unter Wartung → Konfiguration -->
|
||||
<menuitem id="menu_equipment_wiki_sync"
|
||||
name="Wiki-Synchronisation"
|
||||
parent="maintenance.menu_maintenance_configuration"
|
||||
action="action_equipment_wiki_sync_wizard"
|
||||
sequence="99"/>
|
||||
</odoo>
|
||||
Loading…
Reference in New Issue
Block a user