changes
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
from . import models
|
||||
@@ -0,0 +1,56 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
{
|
||||
'name': 'Fusion Plating — Maintenance Bridge',
|
||||
'version': '19.0.1.0.0',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'Bridge standard Odoo Maintenance with Fusion Plating equipment, '
|
||||
'plans, checklists, and sensor integration.',
|
||||
'description': """
|
||||
Fusion Plating — Maintenance Bridge
|
||||
====================================
|
||||
|
||||
Extends Odoo's standard Maintenance module for electroless nickel plating
|
||||
and metal finishing operations. Replaces Steelhead Software CMMS.
|
||||
|
||||
* Maintenance plans (templates linked to equipment categories)
|
||||
* Checklist nodes (individual items within a plan)
|
||||
* Labour cost tracking on maintenance events
|
||||
* "From last maintenance" recurrence mode
|
||||
* Equipment linked to Fusion Plating tanks and facilities
|
||||
* Optional sensor measurement bridge (soft dependency)
|
||||
|
||||
Part of the Fusion Plating product family by Nexa Systems Inc.
|
||||
|
||||
Copyright (c) 2026 Nexa Systems Inc. All rights reserved.
|
||||
""",
|
||||
'author': 'Nexa Systems Inc.',
|
||||
'website': 'https://www.nexasystems.ca',
|
||||
'maintainer': 'Nexa Systems Inc.',
|
||||
'support': 'support@nexasystems.ca',
|
||||
'license': 'OPL-1',
|
||||
'price': 0.00,
|
||||
'currency': 'CAD',
|
||||
'depends': [
|
||||
'fusion_plating',
|
||||
'maintenance',
|
||||
],
|
||||
'data': [
|
||||
'security/fp_maintenance_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'data/fp_maintenance_stage_data.xml',
|
||||
'data/fp_maintenance_sequence_data.xml',
|
||||
'data/fp_equipment_category_data.xml',
|
||||
'views/fp_maintenance_plan_views.xml',
|
||||
'views/fp_maintenance_node_views.xml',
|
||||
'views/maintenance_request_views.xml',
|
||||
'views/maintenance_equipment_views.xml',
|
||||
'views/fp_maintenance_dashboard_views.xml',
|
||||
'views/fp_maintenance_menu.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': False,
|
||||
'auto_install': False,
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- Seed equipment categories from Steelhead -->
|
||||
<record id="equip_cat_al_tanks" model="maintenance.equipment.category">
|
||||
<field name="name">AL Tanks</field>
|
||||
</record>
|
||||
|
||||
<record id="equip_cat_specialty_tanks" model="maintenance.equipment.category">
|
||||
<field name="name">Specialty Tanks</field>
|
||||
</record>
|
||||
|
||||
<record id="equip_cat_steel_tanks" model="maintenance.equipment.category">
|
||||
<field name="name">Steel Tanks</field>
|
||||
</record>
|
||||
|
||||
<record id="equip_cat_waste_water" model="maintenance.equipment.category">
|
||||
<field name="name">Waste Water</field>
|
||||
</record>
|
||||
|
||||
<record id="equip_cat_waste_water_treatment" model="maintenance.equipment.category">
|
||||
<field name="name">Waste Water Treatment</field>
|
||||
</record>
|
||||
|
||||
<record id="equip_cat_common" model="maintenance.equipment.category">
|
||||
<field name="name">common</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="seq_fp_maintenance_plan" model="ir.sequence">
|
||||
<field name="name">Maintenance Plan</field>
|
||||
<field name="code">fp.maintenance.plan</field>
|
||||
<field name="prefix">MPLAN/</field>
|
||||
<field name="padding">4</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
|
||||
<!-- Override standard stages to match Steelhead lifecycle -->
|
||||
<record id="maintenance.stage_0" model="maintenance.stage">
|
||||
<field name="name">New</field>
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="fold" eval="False"/>
|
||||
<field name="done" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="stage_active" model="maintenance.stage">
|
||||
<field name="name">Active</field>
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="fold" eval="False"/>
|
||||
<field name="done" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="stage_completed" model="maintenance.stage">
|
||||
<field name="name">Completed</field>
|
||||
<field name="sequence" eval="3"/>
|
||||
<field name="fold" eval="True"/>
|
||||
<field name="done" eval="True"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
from . import fp_maintenance_plan
|
||||
from . import fp_maintenance_node
|
||||
from . import fp_maintenance_label
|
||||
from . import maintenance_request
|
||||
from . import maintenance_equipment
|
||||
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class FpMaintenanceLabel(models.Model):
|
||||
"""Simple tag model for equipment labels."""
|
||||
_name = 'fp.maintenance.label'
|
||||
_description = 'Fusion Plating — Equipment Label'
|
||||
_order = 'name'
|
||||
|
||||
name = fields.Char(string='Name', required=True)
|
||||
color = fields.Integer(string='Colour')
|
||||
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique(name)', 'Label name must be unique.'),
|
||||
]
|
||||
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class FpMaintenanceNode(models.Model):
|
||||
"""Maintenance checklist item.
|
||||
|
||||
Individual task or check within a maintenance plan.
|
||||
Auto-numbered on creation.
|
||||
"""
|
||||
_name = 'fp.maintenance.node'
|
||||
_description = 'Fusion Plating — Maintenance Node'
|
||||
_order = 'number desc'
|
||||
|
||||
name = fields.Char(
|
||||
string='Name',
|
||||
required=True,
|
||||
)
|
||||
number = fields.Integer(
|
||||
string='Number',
|
||||
readonly=True,
|
||||
copy=False,
|
||||
)
|
||||
plan_id = fields.Many2one(
|
||||
'fp.maintenance.plan',
|
||||
string='Plan',
|
||||
ondelete='set null',
|
||||
)
|
||||
active = fields.Boolean(default=True)
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
string='Company',
|
||||
default=lambda self: self.env.company,
|
||||
)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
for vals in vals_list:
|
||||
if not vals.get('number'):
|
||||
last = self.sudo().search([], order='number desc', limit=1)
|
||||
vals['number'] = (last.number if last else 0) + 1
|
||||
return super().create(vals_list)
|
||||
@@ -0,0 +1,65 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class FpMaintenancePlan(models.Model):
|
||||
"""Maintenance plan template.
|
||||
|
||||
Groups checklist nodes and links to an equipment category.
|
||||
Plans are selected when creating maintenance events.
|
||||
"""
|
||||
_name = 'fp.maintenance.plan'
|
||||
_description = 'Fusion Plating — Maintenance Plan'
|
||||
_inherit = ['mail.thread']
|
||||
_order = 'name'
|
||||
|
||||
name = fields.Char(
|
||||
string='Name',
|
||||
required=True,
|
||||
tracking=True,
|
||||
help='e.g. "Tank A-10 Nickel Nichem HP 1170 - Daily Titration"',
|
||||
)
|
||||
equipment_category_id = fields.Many2one(
|
||||
'maintenance.equipment.category',
|
||||
string='Equipment Type',
|
||||
ondelete='set null',
|
||||
tracking=True,
|
||||
)
|
||||
description = fields.Html(string='Description')
|
||||
default_assignee_id = fields.Many2one(
|
||||
'res.users',
|
||||
string='Default Assignee',
|
||||
)
|
||||
node_ids = fields.One2many(
|
||||
'fp.maintenance.node',
|
||||
'plan_id',
|
||||
string='Checklist Items',
|
||||
)
|
||||
node_count = fields.Integer(
|
||||
string='Items',
|
||||
compute='_compute_node_count',
|
||||
)
|
||||
active = fields.Boolean(default=True)
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
string='Company',
|
||||
default=lambda self: self.env.company,
|
||||
)
|
||||
|
||||
def _compute_node_count(self):
|
||||
for plan in self:
|
||||
plan.node_count = len(plan.node_ids)
|
||||
|
||||
def action_view_nodes(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': f'Items — {self.name}',
|
||||
'res_model': 'fp.maintenance.node',
|
||||
'view_mode': 'list,form',
|
||||
'domain': [('plan_id', '=', self.id)],
|
||||
'context': {'default_plan_id': self.id},
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class MaintenanceEquipment(models.Model):
|
||||
"""Extend standard maintenance.equipment with plating links."""
|
||||
_inherit = 'maintenance.equipment'
|
||||
|
||||
x_fc_tank_id = fields.Many2one(
|
||||
'fusion.plating.tank',
|
||||
string='Plating Tank',
|
||||
help='Link this equipment to a Fusion Plating tank.',
|
||||
)
|
||||
x_fc_facility_id = fields.Many2one(
|
||||
'fusion.plating.facility',
|
||||
string='Facility',
|
||||
)
|
||||
x_fc_location_name = fields.Char(
|
||||
string='Sub-Location',
|
||||
help='e.g. "PLANT1.BoilerRoom", "PLANT1.TankLine"',
|
||||
)
|
||||
x_fc_label_ids = fields.Many2many(
|
||||
'fp.maintenance.label',
|
||||
'fp_maintenance_equipment_label_rel',
|
||||
'equipment_id',
|
||||
'label_id',
|
||||
string='Labels',
|
||||
)
|
||||
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MaintenanceRequest(models.Model):
|
||||
"""Extend standard maintenance.request with plating-specific fields."""
|
||||
_inherit = 'maintenance.request'
|
||||
|
||||
x_fc_plan_id = fields.Many2one(
|
||||
'fp.maintenance.plan',
|
||||
string='Plan',
|
||||
)
|
||||
x_fc_node_id = fields.Many2one(
|
||||
'fp.maintenance.node',
|
||||
string='Checklist Item',
|
||||
)
|
||||
x_fc_labour_cost = fields.Monetary(
|
||||
string='Labour Cost',
|
||||
currency_field='x_fc_currency_id',
|
||||
)
|
||||
x_fc_currency_id = fields.Many2one(
|
||||
'res.currency',
|
||||
string='Currency',
|
||||
default=lambda self: self.env.company.currency_id,
|
||||
)
|
||||
x_fc_completed_at = fields.Datetime(
|
||||
string='Completed At',
|
||||
readonly=True,
|
||||
)
|
||||
x_fc_from_last = fields.Boolean(
|
||||
string='From Last Maintenance',
|
||||
help='When checked, the next recurrence is scheduled relative to '
|
||||
'completion date instead of a fixed calendar interval.',
|
||||
)
|
||||
x_fc_recurrence_days = fields.Integer(
|
||||
string='Recurrence Days',
|
||||
help='Number of days after completion to schedule the next event '
|
||||
'(only used with "From Last Maintenance").',
|
||||
)
|
||||
|
||||
def write(self, vals):
|
||||
res = super().write(vals)
|
||||
if 'stage_id' in vals:
|
||||
for request in self:
|
||||
if request.stage_id.done and not request.x_fc_completed_at:
|
||||
request.x_fc_completed_at = fields.Datetime.now()
|
||||
self._maybe_schedule_from_last(request)
|
||||
elif not request.stage_id.done:
|
||||
request.x_fc_completed_at = False
|
||||
return res
|
||||
|
||||
def _maybe_schedule_from_last(self, request):
|
||||
"""Schedule next maintenance from completion date."""
|
||||
if not request.x_fc_from_last or not request.x_fc_recurrence_days:
|
||||
return
|
||||
next_date = fields.Datetime.now() + timedelta(
|
||||
days=request.x_fc_recurrence_days,
|
||||
)
|
||||
request.copy({
|
||||
'schedule_date': next_date,
|
||||
'x_fc_completed_at': False,
|
||||
'stage_id': self.env['maintenance.stage'].search(
|
||||
[('done', '=', False)], order='sequence', limit=1,
|
||||
).id,
|
||||
})
|
||||
_logger.info(
|
||||
'Scheduled next from-last maintenance for %s on %s',
|
||||
request.name, next_date,
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="fp_maintenance_plan_company_rule" model="ir.rule">
|
||||
<field name="name">Maintenance Plan: multi-company</field>
|
||||
<field name="model_id" ref="model_fp_maintenance_plan"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">[('company_id', 'in', company_ids + [False])]</field>
|
||||
</record>
|
||||
|
||||
<record id="fp_maintenance_node_company_rule" model="ir.rule">
|
||||
<field name="name">Maintenance Node: multi-company</field>
|
||||
<field name="model_id" ref="model_fp_maintenance_node"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">[('company_id', 'in', company_ids + [False])]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,10 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_fp_maintenance_plan_operator,fp.maintenance.plan.operator,model_fp_maintenance_plan,fusion_plating.group_fusion_plating_operator,1,0,0,0
|
||||
access_fp_maintenance_plan_supervisor,fp.maintenance.plan.supervisor,model_fp_maintenance_plan,fusion_plating.group_fusion_plating_supervisor,1,1,1,0
|
||||
access_fp_maintenance_plan_manager,fp.maintenance.plan.manager,model_fp_maintenance_plan,fusion_plating.group_fusion_plating_manager,1,1,1,1
|
||||
access_fp_maintenance_node_operator,fp.maintenance.node.operator,model_fp_maintenance_node,fusion_plating.group_fusion_plating_operator,1,0,0,0
|
||||
access_fp_maintenance_node_supervisor,fp.maintenance.node.supervisor,model_fp_maintenance_node,fusion_plating.group_fusion_plating_supervisor,1,1,1,0
|
||||
access_fp_maintenance_node_manager,fp.maintenance.node.manager,model_fp_maintenance_node,fusion_plating.group_fusion_plating_manager,1,1,1,1
|
||||
access_fp_maintenance_label_operator,fp.maintenance.label.operator,model_fp_maintenance_label,fusion_plating.group_fusion_plating_operator,1,0,0,0
|
||||
access_fp_maintenance_label_supervisor,fp.maintenance.label.supervisor,model_fp_maintenance_label,fusion_plating.group_fusion_plating_supervisor,1,1,1,0
|
||||
access_fp_maintenance_label_manager,fp.maintenance.label.manager,model_fp_maintenance_label,fusion_plating.group_fusion_plating_manager,1,1,1,1
|
||||
|
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Dashboard: Active Events -->
|
||||
<record id="action_fp_maintenance_active" model="ir.actions.act_window">
|
||||
<field name="name">Active Events</field>
|
||||
<field name="res_model">maintenance.request</field>
|
||||
<field name="view_mode">list,kanban,form,calendar</field>
|
||||
<field name="domain">[('archive', '=', False), ('stage_id.done', '=', False)]</field>
|
||||
<field name="context">{'search_default_group_stage': 1}</field>
|
||||
</record>
|
||||
|
||||
<!-- Dashboard: Completed Events -->
|
||||
<record id="action_fp_maintenance_completed" model="ir.actions.act_window">
|
||||
<field name="name">Completed Events</field>
|
||||
<field name="res_model">maintenance.request</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="domain">[('stage_id.done', '=', True)]</field>
|
||||
<field name="context">{}</field>
|
||||
</record>
|
||||
|
||||
<!-- Dashboard: All Events -->
|
||||
<record id="action_fp_maintenance_all" model="ir.actions.act_window">
|
||||
<field name="name">All Events</field>
|
||||
<field name="res_model">maintenance.request</field>
|
||||
<field name="view_mode">list,kanban,form,calendar</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a maintenance event
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Dashboard: Equipment -->
|
||||
<record id="action_fp_maintenance_equipment" model="ir.actions.act_window">
|
||||
<field name="name">Equipment</field>
|
||||
<field name="res_model">maintenance.equipment</field>
|
||||
<field name="view_mode">list,kanban,form</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Maintenance parent menu under Plating root ===== -->
|
||||
<menuitem id="menu_fp_maintenance"
|
||||
name="Maintenance"
|
||||
parent="fusion_plating.menu_fp_root"
|
||||
sequence="22"
|
||||
groups="fusion_plating.group_fusion_plating_operator"/>
|
||||
|
||||
<menuitem id="menu_fp_maintenance_active"
|
||||
name="Active Events"
|
||||
parent="menu_fp_maintenance"
|
||||
action="action_fp_maintenance_active"
|
||||
sequence="5"/>
|
||||
|
||||
<menuitem id="menu_fp_maintenance_plans"
|
||||
name="Plans"
|
||||
parent="menu_fp_maintenance"
|
||||
action="action_fp_maintenance_plan"
|
||||
sequence="10"/>
|
||||
|
||||
<menuitem id="menu_fp_maintenance_nodes"
|
||||
name="Checklist Items"
|
||||
parent="menu_fp_maintenance"
|
||||
action="action_fp_maintenance_node"
|
||||
sequence="20"/>
|
||||
|
||||
<menuitem id="menu_fp_maintenance_all"
|
||||
name="All Events"
|
||||
parent="menu_fp_maintenance"
|
||||
action="action_fp_maintenance_all"
|
||||
sequence="30"/>
|
||||
|
||||
<menuitem id="menu_fp_maintenance_completed"
|
||||
name="Completed Events"
|
||||
parent="menu_fp_maintenance"
|
||||
action="action_fp_maintenance_completed"
|
||||
sequence="35"/>
|
||||
|
||||
<menuitem id="menu_fp_maintenance_equipment"
|
||||
name="Equipment"
|
||||
parent="menu_fp_maintenance"
|
||||
action="action_fp_maintenance_equipment"
|
||||
sequence="40"/>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Node List ===== -->
|
||||
<record id="view_fp_maintenance_node_list" model="ir.ui.view">
|
||||
<field name="name">fp.maintenance.node.list</field>
|
||||
<field name="model">fp.maintenance.node</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Checklist Items" default_order="number desc">
|
||||
<field name="name"/>
|
||||
<field name="number"/>
|
||||
<field name="plan_id"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Node Form ===== -->
|
||||
<record id="view_fp_maintenance_node_form" model="ir.ui.view">
|
||||
<field name="name">fp.maintenance.node.form</field>
|
||||
<field name="model">fp.maintenance.node</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Checklist Item">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="number" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="plan_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Window Action ===== -->
|
||||
<record id="action_fp_maintenance_node" model="ir.actions.act_window">
|
||||
<field name="name">Checklist Items</field>
|
||||
<field name="res_model">fp.maintenance.node</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a checklist item
|
||||
</p>
|
||||
<p>Checklist items are individual tasks within a maintenance plan.</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ===== Plan Form ===== -->
|
||||
<record id="view_fp_maintenance_plan_form" model="ir.ui.view">
|
||||
<field name="name">fp.maintenance.plan.form</field>
|
||||
<field name="model">fp.maintenance.plan</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Maintenance Plan">
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" icon="fa-list-ol"
|
||||
type="object" name="action_view_nodes"
|
||||
invisible="node_count == 0">
|
||||
<field name="node_count" widget="statinfo" string="Items"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" placeholder="e.g. Tank A-10 Daily Titration"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="equipment_category_id" string="Equipment Type"/>
|
||||
<field name="default_assignee_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Description" name="description">
|
||||
<field name="description"/>
|
||||
</page>
|
||||
<page string="Checklist Items" name="nodes">
|
||||
<field name="node_ids">
|
||||
<list editable="bottom">
|
||||
<field name="number" readonly="1"/>
|
||||
<field name="name"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<chatter/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Plan List ===== -->
|
||||
<record id="view_fp_maintenance_plan_list" model="ir.ui.view">
|
||||
<field name="name">fp.maintenance.plan.list</field>
|
||||
<field name="model">fp.maintenance.plan</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Maintenance Plans" default_order="name">
|
||||
<field name="name"/>
|
||||
<field name="equipment_category_id" string="Equipment Type"/>
|
||||
<field name="default_assignee_id"/>
|
||||
<field name="node_count" string="Items"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Plan Search ===== -->
|
||||
<record id="view_fp_maintenance_plan_search" model="ir.ui.view">
|
||||
<field name="name">fp.maintenance.plan.search</field>
|
||||
<field name="model">fp.maintenance.plan</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="equipment_category_id"/>
|
||||
<group>
|
||||
<filter string="Equipment Type" name="group_category"
|
||||
context="{'group_by': 'equipment_category_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== Window Action ===== -->
|
||||
<record id="action_fp_maintenance_plan" model="ir.actions.act_window">
|
||||
<field name="name">Maintenance Plans</field>
|
||||
<field name="res_model">fp.maintenance.plan</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
<field name="search_view_id" ref="view_fp_maintenance_plan_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a maintenance plan
|
||||
</p>
|
||||
<p>Plans are templates for recurring maintenance tasks linked to equipment types.</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Extend maintenance.equipment form with plating links -->
|
||||
<record id="view_maintenance_equipment_form_fp" model="ir.ui.view">
|
||||
<field name="name">maintenance.equipment.form.fp.bridge</field>
|
||||
<field name="model">maintenance.equipment</field>
|
||||
<field name="inherit_id" ref="maintenance.hr_equipment_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath expr="//field[@name='category_id']" position="after">
|
||||
<field name="x_fc_tank_id"/>
|
||||
<field name="x_fc_facility_id"/>
|
||||
<field name="x_fc_location_name"
|
||||
placeholder="e.g. PLANT1.TankLine"/>
|
||||
<field name="x_fc_label_ids" widget="many2many_tags"
|
||||
options="{'color_field': 'color'}"/>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Extend maintenance.request form with plating fields -->
|
||||
<record id="view_maintenance_request_form_fp" model="ir.ui.view">
|
||||
<field name="name">maintenance.request.form.fp.bridge</field>
|
||||
<field name="model">maintenance.request</field>
|
||||
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath expr="//field[@name='equipment_id'][not(ancestor::kanban)]" position="after">
|
||||
<field name="x_fc_plan_id"/>
|
||||
<field name="x_fc_node_id"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='schedule_end']" position="after">
|
||||
<field name="x_fc_completed_at" readonly="1"/>
|
||||
<field name="x_fc_labour_cost"/>
|
||||
<field name="x_fc_currency_id" invisible="1"/>
|
||||
<field name="x_fc_from_last"/>
|
||||
<field name="x_fc_recurrence_days"
|
||||
invisible="not x_fc_from_last"/>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Extend maintenance.request list with plating columns -->
|
||||
<record id="view_maintenance_request_list_fp" model="ir.ui.view">
|
||||
<field name="name">maintenance.request.list.fp.bridge</field>
|
||||
<field name="model">maintenance.request</field>
|
||||
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath expr="//field[@name='stage_id']" position="before">
|
||||
<field name="x_fc_plan_id" optional="show"/>
|
||||
<field name="x_fc_node_id" optional="show"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='stage_id']" position="after">
|
||||
<field name="x_fc_completed_at" optional="show"/>
|
||||
<field name="x_fc_labour_cost" optional="hide"/>
|
||||
<field name="x_fc_currency_id" column_invisible="1"/>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user