Add odex25_maintenance
This commit is contained in:
parent
3a3f834c54
commit
4755d7ddc4
|
|
@ -1,2 +1,2 @@
|
||||||
# odex25-standard-moduless
|
# odex25-standard-modules
|
||||||
This Repo contains general standard modules for all projects.
|
This Repo contains general standard modules for all projects.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
from . import models
|
||||||
|
from . import wizard
|
||||||
|
from . import reports
|
||||||
|
from . import controllers
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
'name':'Maintenance Custom ',
|
||||||
|
'version':'1.0',
|
||||||
|
'summary':'Maintenance Custom system',
|
||||||
|
'sequence': 1,
|
||||||
|
'description':
|
||||||
|
"""
|
||||||
|
""",
|
||||||
|
'depends':['sale','purchase_requisition_custom', 'maintenance','hr_maintenance'],
|
||||||
|
'data':[
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
'data/ir_sequences_data.xml',
|
||||||
|
'security/groups.xml',
|
||||||
|
'views/maintenance_view.xml',
|
||||||
|
'views/maintenance_asset.xml',
|
||||||
|
'views/maintenance_checklist.xml',
|
||||||
|
'views/menu_security_cus.xml',
|
||||||
|
'wizard/maintenance_report_wiz_view.xml',
|
||||||
|
'reports/equipment_report.xml',
|
||||||
|
'reports/spare_part_report.xml',
|
||||||
|
'reports/general_maintenance_report.xml',
|
||||||
|
'reports/report_maintenance_request.xml',
|
||||||
|
'reports/maintenance_report.xml',
|
||||||
|
'reports/maintenance_team_report.xml',
|
||||||
|
],
|
||||||
|
'qweb': ['static/src/xml/*.xml'],
|
||||||
|
'installable':
|
||||||
|
True,
|
||||||
|
'application':
|
||||||
|
True,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import service
|
||||||
|
|
@ -0,0 +1,170 @@
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import request
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
from passlib.context import CryptContext
|
||||||
|
import json
|
||||||
|
import xmlrpc.client
|
||||||
|
|
||||||
|
url = 'http://localhost:8069'
|
||||||
|
db = 'laundry'
|
||||||
|
#db = 'test13'
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'product' : {
|
||||||
|
'model' : 'product.product', 'field' : ['lst_price', 'name',]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
class Service(http.Controller):
|
||||||
|
|
||||||
|
@http.route('/hello', auth='public')
|
||||||
|
def hello(self):
|
||||||
|
return '<h1>Hello Optimum !!</h1>'
|
||||||
|
|
||||||
|
@http.route('/user/create', auth='public')
|
||||||
|
def user_create(self):
|
||||||
|
user_data = dict(
|
||||||
|
name=request.params.get('name'),
|
||||||
|
login=request.params.get('login'),
|
||||||
|
password=request.params.get('password'),
|
||||||
|
#odoobot_state='not_initialized'
|
||||||
|
)
|
||||||
|
user_model = request.env['res.users']
|
||||||
|
search_res = user_model.sudo().search([('login','=',user_data['login'])])
|
||||||
|
if not search_res :
|
||||||
|
obj = user_model.sudo().create(user_data)
|
||||||
|
res = {
|
||||||
|
'code' : 1,
|
||||||
|
'message' : 'A new User Created Successfully',
|
||||||
|
'result' : {
|
||||||
|
'user_id' : obj.id ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else :
|
||||||
|
res = {
|
||||||
|
'code' : -1,
|
||||||
|
'message' : 'Login name is exist',
|
||||||
|
}
|
||||||
|
return json.dumps(res)
|
||||||
|
|
||||||
|
|
||||||
|
@http.route('/user/check', auth='public')
|
||||||
|
def check_user(self):
|
||||||
|
username = request.params.get('login')
|
||||||
|
password = request.params.get('password')
|
||||||
|
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
|
||||||
|
uid = common.authenticate(db, username, password, {})
|
||||||
|
if uid :
|
||||||
|
res = {
|
||||||
|
'code' : 2,
|
||||||
|
'message' : 'Login Sucessfuly',
|
||||||
|
'result' : {
|
||||||
|
'user_id' : uid ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
res = {
|
||||||
|
'code' : -2,
|
||||||
|
'message' : 'Wrong Login/Password',
|
||||||
|
'result' : {
|
||||||
|
#'user_id' : obj.id ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json.dumps(res)
|
||||||
|
|
||||||
|
|
||||||
|
@http.route('/product/all', auth='public')
|
||||||
|
def all_product(self):
|
||||||
|
product_model = request.env['product.template']
|
||||||
|
res = product_model.sudo().search_read([],['name'])
|
||||||
|
if res :
|
||||||
|
result = {
|
||||||
|
'code' : 3,
|
||||||
|
'message' : 'Request Done',
|
||||||
|
'result' : res
|
||||||
|
}
|
||||||
|
else :
|
||||||
|
result = {
|
||||||
|
'code' : -3,
|
||||||
|
'message' : 'No products',
|
||||||
|
'result' : []
|
||||||
|
}
|
||||||
|
return json.dumps(result)
|
||||||
|
|
||||||
|
|
||||||
|
@http.route('/product/get', auth='public')
|
||||||
|
def get_product(self):
|
||||||
|
product_id = request.params.get('product_id')
|
||||||
|
product_model = request.env['product.template']
|
||||||
|
res = product_model.sudo().search_read([('id', '=' , product_id)],['lst_price', 'name'])
|
||||||
|
result = {}
|
||||||
|
if res :
|
||||||
|
result['code'] = 4
|
||||||
|
result['message'] = 'Request Done'
|
||||||
|
else :
|
||||||
|
result['code'] = 4
|
||||||
|
result['message'] = 'No product'
|
||||||
|
result['result'] = res
|
||||||
|
return json.dumps(result)
|
||||||
|
|
||||||
|
|
||||||
|
@http.route('/variant/all', auth='public')
|
||||||
|
def all_vars(self):
|
||||||
|
product_model = request.env['product.attribute.value']
|
||||||
|
res = product_model.sudo().search_read([],['name'])
|
||||||
|
if res :
|
||||||
|
result = {
|
||||||
|
'code' : 4,
|
||||||
|
'message' : 'Request Done',
|
||||||
|
'result' : res
|
||||||
|
}
|
||||||
|
else :
|
||||||
|
result = {
|
||||||
|
'code' : -4,
|
||||||
|
'message' : 'No Records',
|
||||||
|
'result' : []
|
||||||
|
}
|
||||||
|
return json.dumps(result)
|
||||||
|
|
||||||
|
|
||||||
|
@http.route('/product_var/all', auth='public')
|
||||||
|
def all_product_var(self):
|
||||||
|
product_model = request.env['product.template.attribute.value']
|
||||||
|
res = product_model.sudo().search_read([],['price_extra', 'product_tmpl_id', 'product_attribute_value_id'])
|
||||||
|
if res :
|
||||||
|
result = {
|
||||||
|
'code' : 4,
|
||||||
|
'message' : 'Request Done',
|
||||||
|
'result' : res
|
||||||
|
}
|
||||||
|
else :
|
||||||
|
result = {
|
||||||
|
'code' : -4,
|
||||||
|
'message' : 'No Records',
|
||||||
|
'result' : []
|
||||||
|
}
|
||||||
|
return json.dumps(result)
|
||||||
|
|
||||||
|
|
||||||
|
@http.route('/product_var/get', auth='public')
|
||||||
|
def get_product_var(self):
|
||||||
|
cond = []
|
||||||
|
product_tmpl_id = request.params.get('product_id')
|
||||||
|
product_attribute_value_id = request.params.get('var_id')
|
||||||
|
product_model = request.env['product.template.attribute.value']
|
||||||
|
if product_tmpl_id : cond += [('product_tmpl_id', '=' ,int(product_tmpl_id) )]
|
||||||
|
if product_attribute_value_id : cond += [('product_attribute_value_id', '=' ,int(product_attribute_value_id) )]
|
||||||
|
res = product_model.sudo().search_read(cond,['price_extra', 'product_tmpl_id', 'product_attribute_value_id'])
|
||||||
|
if res :
|
||||||
|
result = {
|
||||||
|
'code' : 4,
|
||||||
|
'message' : 'Request Done',
|
||||||
|
'result' : res
|
||||||
|
}
|
||||||
|
else :
|
||||||
|
result = {
|
||||||
|
'code' : -4,
|
||||||
|
'message' : 'No Records',
|
||||||
|
'result' : []
|
||||||
|
}
|
||||||
|
return json.dumps(result)
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0">
|
||||||
|
|
||||||
|
<!-- Sequences for maintenance request -->
|
||||||
|
<record id="seq_maintenance_request" model="ir.sequence">
|
||||||
|
<field name="name">Maintenance Request</field>
|
||||||
|
<field name="code">maintenance.request</field>
|
||||||
|
<field name="prefix">M</field>
|
||||||
|
<field name="padding">5</field>
|
||||||
|
<field name="company_id" eval="False"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="maintenance_summary" model="maintenance.summary">
|
||||||
|
<field name="name">Maintenance Summary</field>
|
||||||
|
<field name="order_chart">Maintenance Order</field>
|
||||||
|
<field name="priority_chart">Orders Priority</field>
|
||||||
|
<field name="planned_chart">Planned Maintenacne</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,4 @@
|
||||||
|
from . import maintenance
|
||||||
|
from . import maintenance_asset
|
||||||
|
from . import maintenance_checklist
|
||||||
|
from . import maintenance_checklist_line
|
||||||
|
|
@ -0,0 +1,659 @@
|
||||||
|
from odoo import _, api, fields, models
|
||||||
|
from datetime import datetime, timedelta, time
|
||||||
|
from odoo.exceptions import RedirectWarning, UserError, ValidationError, AccessError
|
||||||
|
from lxml import etree
|
||||||
|
import simplejson # If not installed, you have to install it by executing pip install simplejson
|
||||||
|
|
||||||
|
from odoo.tools import get_lang
|
||||||
|
|
||||||
|
|
||||||
|
class MaintenanceFailure(models.Model):
|
||||||
|
_name = 'maintenance.failure'
|
||||||
|
|
||||||
|
name = fields.Char('Name', required=True)
|
||||||
|
user_ids = fields.Many2many('res.users', 'failure_supervisor_rel', string='Engineers')
|
||||||
|
|
||||||
|
|
||||||
|
class MaintenanceSpare(models.Model):
|
||||||
|
_name = 'maintenance.request.spare'
|
||||||
|
|
||||||
|
spare_id = fields.Many2one('product.template', string='Spare', domain=[('is_spare', '=', True)])
|
||||||
|
quantity = fields.Integer('Quantity')
|
||||||
|
cost = fields.Float('Cost')
|
||||||
|
request_id = fields.Many2one('maintenance.request', string='Related Request')
|
||||||
|
total = fields.Float('Total', readonly=True, compute='_compute')
|
||||||
|
|
||||||
|
@api.depends('quantity', 'cost')
|
||||||
|
def _compute(self):
|
||||||
|
for rec in self:
|
||||||
|
rec.total = rec.cost * rec.quantity
|
||||||
|
|
||||||
|
@api.onchange('spare_id')
|
||||||
|
def onchange_spare(self):
|
||||||
|
self.cost = self.spare_id.standard_price
|
||||||
|
|
||||||
|
|
||||||
|
class MaintenanceSpare(models.Model):
|
||||||
|
_name = 'maintenance.rootfailure'
|
||||||
|
|
||||||
|
name = fields.Char('Description')
|
||||||
|
|
||||||
|
|
||||||
|
class MaintenanceRequestTask(models.Model):
|
||||||
|
_name = 'maintenance.request.task'
|
||||||
|
|
||||||
|
name = fields.Char('name')
|
||||||
|
employee_id = fields.Many2one('hr.employee', string='Employee')
|
||||||
|
time = fields.Float('Executing Time')
|
||||||
|
duration = fields.Float('Duration')
|
||||||
|
is_done = fields.Boolean('Complete ?')
|
||||||
|
request_id = fields.Many2one('maintenance.request', 'Maintenance Request')
|
||||||
|
|
||||||
|
|
||||||
|
# inherit purchase request
|
||||||
|
class PurchaseOrder(models.Model):
|
||||||
|
_inherit = 'purchase.order'
|
||||||
|
maintenance_id = fields.Many2one('maintenance.request', )
|
||||||
|
|
||||||
|
# end
|
||||||
|
|
||||||
|
class MaintenanceEquipmentRequest(models.Model):
|
||||||
|
_inherit = 'maintenance.request'
|
||||||
|
# todo start
|
||||||
|
partner_id = fields.Many2one(comodel_name='res.partner', string='Partner',
|
||||||
|
)
|
||||||
|
product_category_ids = fields.Many2many('product.category', string='Items Categories')
|
||||||
|
# todo end
|
||||||
|
code = fields.Char('Request No', default='/')
|
||||||
|
# todo start
|
||||||
|
line_ids = fields.One2many(comodel_name='matrial.line', inverse_name='request_id', string='')
|
||||||
|
# todo end
|
||||||
|
failure_id = fields.Many2one('maintenance.failure', string='Failure Type')
|
||||||
|
tool_ids = fields.Many2many('product.template', 'maintenance_tool_rel', string="Tools",
|
||||||
|
domain=[('is_tool', '=', True)])
|
||||||
|
spare_ids = fields.One2many('maintenance.request.spare', 'request_id', string="Spares")
|
||||||
|
maintenance_team_id = fields.Many2one('maintenance.team', string='Team', check_company=True, )
|
||||||
|
stage_type = fields.Selection(string='Stage Type', related='stage_id.stage_type')
|
||||||
|
team_type = fields.Selection([('in', 'Internal Team'), ('out', 'Outsite Entity')], 'Team Type')
|
||||||
|
out_entity_id = fields.Many2one('res.partner', 'Entity', domain=[('is_company', '=', True)])
|
||||||
|
request_date = fields.Datetime('Request Date', tracking=True, default=fields.Datetime.now,
|
||||||
|
help="Date requested for the maintenance to happen")
|
||||||
|
dis_employee_ids = fields.Many2many('hr.employee', 'dis_req_member_rel', string='Team Members')
|
||||||
|
employee_ids = fields.Many2many('hr.employee', 'req_member_rel', string='Team Members')
|
||||||
|
employee_id = fields.Many2one('hr.employee', string='Employee')
|
||||||
|
failure_desc = fields.Text('Failure Description')
|
||||||
|
failure_cause_id = fields.Many2one('maintenance.rootfailure', string='Failure Root Cause')
|
||||||
|
maintenance_work = fields.Text('Maintenance works')
|
||||||
|
dis_priority = fields.Selection([('3', 'A'), ('2', 'B'), ('1', 'C')], string='Priority')
|
||||||
|
priority = fields.Selection([('0', 'Very Low'), ('1', 'Low'), ('2', 'Normal'), ('3', 'High')], string='Priority')
|
||||||
|
maintenance_time = fields.Float('Maintenance Duration')
|
||||||
|
estimated_time = fields.Float('Estimated Duration')
|
||||||
|
task_ids = fields.One2many('maintenance.request.task', 'request_id', string='Tasks')
|
||||||
|
attachment = fields.Binary(string="Instruction Document", attachment=True)
|
||||||
|
done_time = fields.Datetime('Complete Time')
|
||||||
|
start_time = fields.Datetime('Maintenance Begin Time')
|
||||||
|
entry_source = fields.Selection(
|
||||||
|
[('request', 'Request Order'), ('order', 'Order Request'), ('job', 'Equipment Job')], string='Source',
|
||||||
|
default='request')
|
||||||
|
machine_status = fields.Selection(
|
||||||
|
[('out_service', 'Out of Service'), ('part', 'Partially effect'), ('in_service', 'In Service')],
|
||||||
|
string='Machine Status')
|
||||||
|
maintenance_category = fields.Selection([('planned', 'Planned'), ('unplanned', 'Unplanned')],
|
||||||
|
string="Maintenance category ")
|
||||||
|
down_time = fields.Float('Down Time')
|
||||||
|
purchase_create = fields.Boolean(string='Purchase_create')
|
||||||
|
product_loss = fields.Float('losses of production')
|
||||||
|
acquisition_date = fields.Date(string='Acquisition Date')
|
||||||
|
department_id = fields.Many2one('hr.department', string='Department', related='employee_id.department_id',
|
||||||
|
readonly=True, store=True)
|
||||||
|
purchase_order_count = fields.Integer(compute='_compute_purchase_order_count')
|
||||||
|
vendor_id = fields.Many2one(
|
||||||
|
comodel_name='res.partner',
|
||||||
|
string='Vendor',
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
purchase_order_id = fields.Many2one(
|
||||||
|
string='Purchase Order',
|
||||||
|
comodel_name='purchase.order',
|
||||||
|
ondelete='restrict',
|
||||||
|
)
|
||||||
|
|
||||||
|
# todo start
|
||||||
|
def create_purchase_request(self):
|
||||||
|
for rec in self:
|
||||||
|
product_list = []
|
||||||
|
for line in rec.line_ids:
|
||||||
|
product_list.append((0, 6, {
|
||||||
|
'product_id': line.product_id.id,
|
||||||
|
'name': line.name,
|
||||||
|
'price_unit': line.price_unit,
|
||||||
|
'product_qty': line.qty,
|
||||||
|
'product_uom': line.uom_id.id,
|
||||||
|
'account_analytic_id': line.account_id.id,
|
||||||
|
}))
|
||||||
|
create_purchase = self.env['purchase.order'].create({
|
||||||
|
'name': rec.name,
|
||||||
|
'partner_id': rec.partner_id.id,
|
||||||
|
'order_line': product_list,
|
||||||
|
'maintenance_id': rec.id
|
||||||
|
})
|
||||||
|
rec.purchase_order_id = create_purchase.id
|
||||||
|
return create_purchase
|
||||||
|
|
||||||
|
def _compute_purchase_order_count(self):
|
||||||
|
for po in self:
|
||||||
|
items = self.env['purchase.order'].search([
|
||||||
|
('name', '=', self.name),
|
||||||
|
])
|
||||||
|
po.purchase_order_count = len(items)
|
||||||
|
|
||||||
|
def to_open_maintenance_purchase_order(self):
|
||||||
|
xmlid = "purchase.purchase_rfq"
|
||||||
|
action = self.env["ir.actions.act_window"]._for_xml_id(xmlid)
|
||||||
|
action["domain"] = [('maintenance_id', '=', self.id)]
|
||||||
|
action['context']= {'create': False,'edit':False}
|
||||||
|
# action["views"] = [(self.env.ref("purchase.purchase_order_form").id, "form")]
|
||||||
|
return action
|
||||||
|
|
||||||
|
# return {'name': _('Maintenance Purchase Orders'),
|
||||||
|
# 'type': 'ir.actions.act_window',
|
||||||
|
# 'res_model': 'purchase.order',
|
||||||
|
# 'view_mode': 'tree',
|
||||||
|
# 'domain': [('maintenance_id', '=', self.id)],
|
||||||
|
# 'context': "{'create': False,'edit':True}"
|
||||||
|
# # 'target': 'new'
|
||||||
|
# }
|
||||||
|
|
||||||
|
def request_order_creation(self):
|
||||||
|
for rec in self:
|
||||||
|
if not self.env.user.has_group('maintenance_custom.maintenance_order_stage_visibility_stage_group'):
|
||||||
|
raise UserError(_('You cannot Make This Order Please Contact Your Administrator To Make Your Order'))
|
||||||
|
else:
|
||||||
|
res = self.env['maintenance.stage'].search([('stage_type', '=', 'confirm')])
|
||||||
|
if res:
|
||||||
|
rec.stage_id = res
|
||||||
|
|
||||||
|
def maintenance_order_creation(self):
|
||||||
|
for rec in self:
|
||||||
|
if not self.env.user.has_group('maintenance_custom.request_order_stage'):
|
||||||
|
raise UserError(_('You cannot Make This Order Please Contact Your Administrator To Make Your Order'))
|
||||||
|
else:
|
||||||
|
res = self.env['maintenance.stage'].search([('stage_type', '=', 'for_order')])
|
||||||
|
if res:
|
||||||
|
rec.stage_id = res
|
||||||
|
|
||||||
|
def maintenance_order_done(self):
|
||||||
|
for rec in self:
|
||||||
|
if not self.env.user.has_group('maintenance_custom.maintenance_order_done'):
|
||||||
|
raise UserError(_('You cannot Make This Order Please Contact Your Administrator To Make Your Order'))
|
||||||
|
else:
|
||||||
|
res = self.env['maintenance.stage'].search([('stage_type', '=', 'repair_done')])
|
||||||
|
if res:
|
||||||
|
rec.stage_id = res
|
||||||
|
|
||||||
|
def maintenance_order_cancel(self):
|
||||||
|
for rec in self:
|
||||||
|
if not self.env.user.has_group('maintenance_custom.maintenance_order_stage_cancel_visibility_stage_group'):
|
||||||
|
raise UserError(_('You cannot Make Cancel For This Order Please Contact Your Administrator'))
|
||||||
|
else:
|
||||||
|
res = self.env['maintenance.stage'].search([('stage_type', '=', 'cancel')])
|
||||||
|
if res:
|
||||||
|
rec.stage_id = res
|
||||||
|
|
||||||
|
def order_set_to_draft(self):
|
||||||
|
for rec in self:
|
||||||
|
if not self.env.user.has_group('maintenance_custom.maintenance_order_set_to_draft'):
|
||||||
|
raise UserError(_('You cannot Make Set To Draft Please Contact Your Administrator'))
|
||||||
|
else:
|
||||||
|
res = self.env['maintenance.stage'].search([('stage_type', '=', 'draft')])
|
||||||
|
if res:
|
||||||
|
rec.stage_id = res
|
||||||
|
|
||||||
|
def get_po(self):
|
||||||
|
self.ensure_one()
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'name': 'Purchase Request',
|
||||||
|
'view_mode': 'tree,form',
|
||||||
|
'res_model': 'purchase.request',
|
||||||
|
'domain': [('maintenance_id', '=', self.id)],
|
||||||
|
'context': "{'create': False}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# todo end
|
||||||
|
|
||||||
|
@api.onchange('stage_id')
|
||||||
|
def _onchange_stage_id(self):
|
||||||
|
print("iam here=================", self.stage_id.sequence)
|
||||||
|
now = datetime.now()
|
||||||
|
if self.stage_id.stage_type == 'confirm':
|
||||||
|
self.request_date = now
|
||||||
|
# self.fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False)
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
|
||||||
|
"""
|
||||||
|
Overrides orm field_view_get.
|
||||||
|
@return: Dictionary of Fields, arch and toolbar.
|
||||||
|
"""
|
||||||
|
|
||||||
|
res = super(MaintenanceEquipmentRequest, self).fields_view_get(view_id=view_id, view_type=view_type,
|
||||||
|
toolbar=toolbar, submenu=submenu)
|
||||||
|
# if doc.xpath("//field[@name='city_id']")
|
||||||
|
if self.env.context: # Check for context value
|
||||||
|
doc = etree.XML(res['arch']) # Get the view architecture of record
|
||||||
|
if view_type == 'form': # Applies only if it is form view
|
||||||
|
for node in doc.xpath("//field"): # Get all the fields navigating through xpath
|
||||||
|
modifiers = simplejson.loads(node.get("modifiers")) # Get all the existing modifiers of each field
|
||||||
|
modifiers['readonly'] = False # Add readonly=True attribute in modifier for each field
|
||||||
|
node.set('modifiers',
|
||||||
|
simplejson.dumps(modifiers)) # Now, set the newly added modifiers to the field
|
||||||
|
res['arch'] = etree.tostring(doc) # Update the view architecture of record with new architecture
|
||||||
|
return res
|
||||||
|
|
||||||
|
@api.onchange('dis_employee_ids', 'user_id', 'team_type')
|
||||||
|
def onchange_members(self):
|
||||||
|
member_ids = []
|
||||||
|
if self.user_id:
|
||||||
|
res = self.env.get('hr.employee').search([('user_id', '=', self.user_id.id)])
|
||||||
|
if res: member_ids.append(res[0].id)
|
||||||
|
if self.dis_employee_ids and self.team_type == 'in':
|
||||||
|
member_ids += self.dis_employee_ids.ids
|
||||||
|
self.employee_ids = [(6, 0, member_ids)]
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
vals['code'] = self.env['ir.sequence'].next_by_code('maintenance.request') or _('New')
|
||||||
|
if 'dis_priority' in vals:
|
||||||
|
vals['priority'] = vals['dis_priority']
|
||||||
|
obj = super(MaintenanceEquipmentRequest, self).create(vals)
|
||||||
|
obj.onchange_members()
|
||||||
|
return obj
|
||||||
|
|
||||||
|
# @api.onchange('failure_id','maintenance_type')
|
||||||
|
# def onchange_failure(self):
|
||||||
|
# domain = [('id','>','0')]
|
||||||
|
# if self.maintenance_type == 'corrective':
|
||||||
|
# dom = self.failure_id and self.failure_id.user_ids.ids or []
|
||||||
|
# domain = [('id', 'in', dom)]
|
||||||
|
# return {
|
||||||
|
# 'value' : {'user_id' : False},
|
||||||
|
# 'domain' : {
|
||||||
|
# 'user_id' : domain
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
def write(self, vals):
|
||||||
|
stage = self.env.get('maintenance.stage')
|
||||||
|
user = self.env.user
|
||||||
|
user_id = user.id
|
||||||
|
if 'dis_priority' in vals:
|
||||||
|
vals['priority'] = vals['dis_priority']
|
||||||
|
if 'stage_id' in vals:
|
||||||
|
new_value = vals['stage_id']
|
||||||
|
old = self.stage_id
|
||||||
|
new = stage.browse(new_value)
|
||||||
|
|
||||||
|
if old.sequence > new.sequence:
|
||||||
|
if old.pre_stage_ids.ids and new_value not in old.pre_stage_ids.ids:
|
||||||
|
raise UserError(_('You cannot use return back to this stage.'))
|
||||||
|
else:
|
||||||
|
if self.stage_id.next_stage_ids and new_value not in self.stage_id.next_stage_ids.ids:
|
||||||
|
raise UserError(_('You cannot use go forword to this stage.'))
|
||||||
|
|
||||||
|
if new.stage_type == 'confirm':
|
||||||
|
if 'employee_id' in vals:
|
||||||
|
em = vals['employee_id']
|
||||||
|
em_id = self.env.get('hr.employee').browse(em)
|
||||||
|
if user_id != em_id.user_id.id:
|
||||||
|
raise UserError(_('You cannot use confrim this request,only requester can perform this action'))
|
||||||
|
else:
|
||||||
|
em_id = self.employee_id
|
||||||
|
if em_id and user_id != em_id.user_id.id:
|
||||||
|
raise UserError(_('You cannot use confrim this request,only requester can perform this action'))
|
||||||
|
now = datetime.now()
|
||||||
|
self.write({'request_date': now})
|
||||||
|
|
||||||
|
if new.stage_type == 'for_order':
|
||||||
|
if self.user_id and self.user_id.id != user_id:
|
||||||
|
raise UserError(_('Only user who create the work order can perform this action'))
|
||||||
|
teams = self.maintenance_team_id.member_ids.ids
|
||||||
|
print("tems================", teams)
|
||||||
|
if user_id not in teams:
|
||||||
|
print("in here===========")
|
||||||
|
raise UserError(_('Only team members for current department team can perform this action'))
|
||||||
|
# if 'equipment_id' in vals:
|
||||||
|
# equipment = vals['equipment_id']
|
||||||
|
# equipment_id = self.env.get('maintenance.equipment').browse(equipment)
|
||||||
|
# if user_id not in equipment_id.maintenance_team_id.member_ids.ids:
|
||||||
|
# raise UserError(_('Only team members can perform this action'))
|
||||||
|
# else:
|
||||||
|
|
||||||
|
# if self.equipment_id and user_id not in self.equipment_id.maintenance_team_id.member_ids.ids:
|
||||||
|
# raise UserError(_('Only team members can perform this action'))
|
||||||
|
self.write({'user_id': user_id})
|
||||||
|
|
||||||
|
if new.stage_type == 'repair_done':
|
||||||
|
if 'user_id' in vals:
|
||||||
|
usr = vals['user_id']
|
||||||
|
usr_id = self.env.get('res.users').browse(usr)
|
||||||
|
# teams = self.env.get('maintenance.team').search([('department_id','=',self.department_id.id)]).member_ids.ids
|
||||||
|
if usr_id and usr_id.id != user_id:
|
||||||
|
raise UserError(
|
||||||
|
_('You cannot use process this request,only supervisor can perform this action'))
|
||||||
|
else:
|
||||||
|
usr_id = self.user_id
|
||||||
|
if usr_id and usr_id.id != user_id:
|
||||||
|
raise UserError(
|
||||||
|
_('You cannot use process this request,only supervisor can perform this action'))
|
||||||
|
|
||||||
|
if new.stage_type == 'request_done':
|
||||||
|
if 'employee_id' in vals:
|
||||||
|
em = vals['employee_id']
|
||||||
|
em_id = self.env.get('hr.employee').browse(em)
|
||||||
|
if user_id != em_id.user_id.id:
|
||||||
|
raise UserError(_('You cannot confirm this request,only requester can perform this action'))
|
||||||
|
else:
|
||||||
|
em_id = self.employee_id
|
||||||
|
if em_id and user_id != em_id.user_id.id:
|
||||||
|
raise UserError(_('You cannot confrim this request,only requester can perform this action'))
|
||||||
|
return super(MaintenanceEquipmentRequest, self).write(vals)
|
||||||
|
|
||||||
|
|
||||||
|
# add new class
|
||||||
|
class MatrialMaintenanceRequest(models.Model):
|
||||||
|
_name = 'matrial.line'
|
||||||
|
_description = 'Matrial maintenacerequest line'
|
||||||
|
|
||||||
|
# for test
|
||||||
|
account_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=False, )
|
||||||
|
request_id = fields.Many2one(comodel_name='maintenance.request', string='Request Ref.')
|
||||||
|
product_id = fields.Many2one(comodel_name='product.product', string='Item')
|
||||||
|
qty = fields.Integer(string='Qty')
|
||||||
|
name = fields.Char(string='Descrption')
|
||||||
|
price_unit = fields.Float(string='Unit Price', digits='Product Price')
|
||||||
|
uom_id = fields.Many2one('uom.uom', related='product_id.uom_id', string='Unit of Measure')
|
||||||
|
sum_total = fields.Float(string="sum_total")
|
||||||
|
|
||||||
|
@api.onchange('qty', 'price_unit')
|
||||||
|
def total_sum_lines(self):
|
||||||
|
sum_total = 0
|
||||||
|
# for line in self.line_ids:
|
||||||
|
if self.price_unit and self.qty:
|
||||||
|
self.sum_total = self.qty * self.price_unit
|
||||||
|
|
||||||
|
# get price for product
|
||||||
|
def _product_id_change(self):
|
||||||
|
if not self.product_id:
|
||||||
|
return
|
||||||
|
|
||||||
|
product_lang = self.product_id.with_context(
|
||||||
|
lang=get_lang(self.env, self.partner_id.lang).code,
|
||||||
|
partner_id=self.partner_id.id,
|
||||||
|
company_id=self.company_id.id,
|
||||||
|
)
|
||||||
|
self.name = self._get_product_purchase_description(product_lang)
|
||||||
|
|
||||||
|
@api.constrains('qty')
|
||||||
|
def qty_validation(self):
|
||||||
|
for rec in self:
|
||||||
|
if rec.qty <= 0:
|
||||||
|
raise ValidationError(_("Item Quantity MUST be at Least ONE!"))
|
||||||
|
|
||||||
|
|
||||||
|
# end
|
||||||
|
|
||||||
|
class MaintenanceStage(models.Model):
|
||||||
|
_inherit = 'maintenance.stage'
|
||||||
|
|
||||||
|
for_order = fields.Boolean('use for Order ?')
|
||||||
|
stage_type = fields.Selection([
|
||||||
|
('draft', 'Draft'),
|
||||||
|
('confirm', 'Confirm'),
|
||||||
|
('for_order', 'Orders'),
|
||||||
|
('repair_done', 'Repair Done'),
|
||||||
|
('cancel', 'Cancel'),
|
||||||
|
])
|
||||||
|
|
||||||
|
next_stage_ids = fields.Many2many(
|
||||||
|
string='Next Stage',
|
||||||
|
comodel_name='maintenance.stage',
|
||||||
|
relation='model_request_next_rel',
|
||||||
|
column1='request_id',
|
||||||
|
column2='stage_id',
|
||||||
|
)
|
||||||
|
|
||||||
|
pre_stage_ids = fields.Many2many(
|
||||||
|
string='Previous Stage',
|
||||||
|
comodel_name='maintenance.stage',
|
||||||
|
relation='model_request_pre_rel',
|
||||||
|
column1='request_id',
|
||||||
|
column2='stage_id',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Product(models.Model):
|
||||||
|
_inherit = 'product.template'
|
||||||
|
|
||||||
|
is_spare = fields.Boolean('Spare')
|
||||||
|
is_tool = fields.Boolean('Tools')
|
||||||
|
|
||||||
|
|
||||||
|
class EquipmentMaintenaceTasks(models.Model):
|
||||||
|
_name = 'maintenance.equipment.task'
|
||||||
|
|
||||||
|
job_id = fields.Many2one('maintenance.equipment.job', string='Related Maintenance Job')
|
||||||
|
jobs_id = fields.Many2one('maintenance.equipments.jobs', string='Related Maintenance Job')
|
||||||
|
name = fields.Char('Decription')
|
||||||
|
sequence = fields.Integer('Sequence')
|
||||||
|
|
||||||
|
|
||||||
|
class EquipmentMaintenaceJob(models.Model):
|
||||||
|
_name = 'maintenance.equipment.job'
|
||||||
|
|
||||||
|
name = fields.Char('Decription')
|
||||||
|
equipment_id = fields.Many2one('maintenance.equipment', string='Equipment')
|
||||||
|
start_date = fields.Date('Maintenance Begin Date')
|
||||||
|
next_action_date = fields.Date('Next Preventive')
|
||||||
|
period = fields.Integer('Preventive Maintenance Frequency')
|
||||||
|
period_type = fields.Selection([('hour', 'By Hour'), ('day', 'Daily'), ('weekly', 'Weekly'),('month', 'Monthly'), ('year', 'Yearly')])
|
||||||
|
maintenance_time = fields.Float('Maintenance Duration')
|
||||||
|
user_id = fields.Many2one('res.users', string='supervisor')
|
||||||
|
active = fields.Boolean('Active', default=True)
|
||||||
|
task_ids = fields.One2many('maintenance.equipment.task', 'job_id', string='Tasks')
|
||||||
|
attachment = fields.Binary(string="Instruction Document", attachment=True)
|
||||||
|
|
||||||
|
@api.onchange('start_date')
|
||||||
|
def onchange_start_date(self):
|
||||||
|
self.next_action_date = self.start_date
|
||||||
|
|
||||||
|
def write(self, vals):
|
||||||
|
if 'start_date' in vals:
|
||||||
|
vals['next_action_date'] = vals['start_date']
|
||||||
|
return super(EquipmentMaintenaceJob, self).write(vals)
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
if 'start_date' in vals:
|
||||||
|
vals['next_action_date'] = vals['start_date']
|
||||||
|
return super(EquipmentMaintenaceJob, self).create(vals)
|
||||||
|
|
||||||
|
class EquipmentsMaintenacesJobs(models.Model):
|
||||||
|
_name = 'maintenance.equipments.jobs'
|
||||||
|
|
||||||
|
name = fields.Char('Decription')
|
||||||
|
equipments_id = fields.Many2many('maintenance.equipment', string='Equipments')
|
||||||
|
equipment_id = fields.Many2one('maintenance.equipment', string='Equipments')
|
||||||
|
start_date = fields.Date('Maintenance Begin Date')
|
||||||
|
next_action_date = fields.Date('Next Preventive')
|
||||||
|
period = fields.Integer('Preventive Maintenance Frequency')
|
||||||
|
period_type = fields.Selection([('hour', 'By Hour'), ('day', 'Daily'), ('weekly', 'Weekly'),('month', 'Monthly'), ('year', 'Yearly')])
|
||||||
|
maintenance_time = fields.Float('Maintenance Duration')
|
||||||
|
user_id = fields.Many2one('res.users', string='supervisor')
|
||||||
|
active = fields.Boolean('Active', default=True)
|
||||||
|
task_ids = fields.One2many('maintenance.equipment.task', 'jobs_id', string='Tasks')
|
||||||
|
attachment = fields.Binary(string="Instruction Document", attachment=True)
|
||||||
|
|
||||||
|
@api.onchange('start_date')
|
||||||
|
def onchange_start_date(self):
|
||||||
|
self.next_action_date = self.start_date
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
# Create a record in the current model
|
||||||
|
if 'start_date' in vals:
|
||||||
|
vals['next_action_date'] = vals['start_date']
|
||||||
|
job = super(EquipmentsMaintenacesJobs, self).create(vals)
|
||||||
|
ids= vals['equipments_id'][0][2]
|
||||||
|
equipments = self.env['maintenance.equipment'].browse(ids)
|
||||||
|
tasks = [(0, 0, {'name': t.name}) for t in job.task_ids]
|
||||||
|
for equipment in equipments:
|
||||||
|
equipment.write({
|
||||||
|
'job_ids': [(0, 0,{
|
||||||
|
'name':job.name,
|
||||||
|
'equipment_id':equipment.id,
|
||||||
|
'start_date':job.start_date,
|
||||||
|
'next_action_date':job.next_action_date,
|
||||||
|
'period':job.period,
|
||||||
|
'period_type':job.period_type,
|
||||||
|
'maintenance_time':job.maintenance_time,
|
||||||
|
'user_id':job.user_id.id,
|
||||||
|
'active':job.active,
|
||||||
|
'task_ids':tasks,
|
||||||
|
'attachment':job.attachment
|
||||||
|
})]})
|
||||||
|
return job
|
||||||
|
|
||||||
|
def write(self, vals):
|
||||||
|
if 'start_date' in vals:
|
||||||
|
vals['next_action_date'] = vals['start_date']
|
||||||
|
# ids = self.equipments_id.ids
|
||||||
|
# equipments = self.env['maintenance.equipment'].browse(ids)
|
||||||
|
# tasks = [(0, 0, {'name': t.name, 'job_id': self.id}) for t in self.task_ids]
|
||||||
|
# # Update related equipment records
|
||||||
|
# for equipment in equipments:
|
||||||
|
# equipment.write({
|
||||||
|
# 'job_ids': [(0,0, {
|
||||||
|
# 'name': self.name,
|
||||||
|
# 'equipment_id': equipment.id,
|
||||||
|
# 'start_date': self.start_date,
|
||||||
|
# 'next_action_date': self.next_action_date,
|
||||||
|
# 'period': self.period,
|
||||||
|
# 'period_type': self.period_type,
|
||||||
|
# 'maintenance_time': self.maintenance_time,
|
||||||
|
# 'user_id': self.user_id.id,
|
||||||
|
# 'active': self.active,
|
||||||
|
# 'task_ids': tasks,
|
||||||
|
# 'attachment': self.attachment
|
||||||
|
# })]})
|
||||||
|
return super(EquipmentsMaintenacesJobs, self).write(vals)
|
||||||
|
|
||||||
|
def creat_equi(self):
|
||||||
|
self.equipment_id.create_maintenance_jobs()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MaintenanceEquipment(models.Model):
|
||||||
|
_inherit = 'maintenance.equipment'
|
||||||
|
|
||||||
|
job_ids = fields.One2many('maintenance.equipment.job', 'equipment_id')
|
||||||
|
location2 = fields.Many2one('equipment.locations')
|
||||||
|
job_ids_for_equipments = fields.One2many('maintenance.equipments.jobs', 'equipments_id')
|
||||||
|
|
||||||
|
# This is cron job for maintenance request for only one equipment
|
||||||
|
def create_maintenance_job(self):
|
||||||
|
current_date = fields.Date.today()
|
||||||
|
job_model = self.env.get('maintenance.equipment.job')
|
||||||
|
res_job = job_model.search([('next_action_date', '=', current_date)])
|
||||||
|
order_model = self.env.get('maintenance.request')
|
||||||
|
res_stage = self.env.get('maintenance.stage').search([('stage_type', '=', 'for_order')], order='sequence')
|
||||||
|
stage_id = res_stage and res_stage[0].id or False
|
||||||
|
for job in res_job:
|
||||||
|
tasks = [(0, 0, {'name': t.name}) for t in job.task_ids]
|
||||||
|
res_order = order_model.create({
|
||||||
|
'name': job.name,
|
||||||
|
'user_id': job.user_id.id,
|
||||||
|
'stage_id': stage_id,
|
||||||
|
'maintenance_type': 'preventive',
|
||||||
|
'task_ids': tasks,
|
||||||
|
'attachment': job.attachment,
|
||||||
|
'entry_source': 'job',
|
||||||
|
'equipment_id': job.equipment_id.id,
|
||||||
|
'schedule_date': current_date,
|
||||||
|
})
|
||||||
|
#This is for maintenance request for group of equipments at the same time
|
||||||
|
def create_maintenance_jobs(self):
|
||||||
|
current_date = fields.Date.today()
|
||||||
|
jobs_model = self.env.get('maintenance.equipments.jobs')
|
||||||
|
res_job = jobs_model.search([('next_action_date', '=', current_date)])
|
||||||
|
order_model = self.env.get('maintenance.request')
|
||||||
|
res_stage = self.env.get('maintenance.stage').search([('stage_type', '=', 'for_order')], order='sequence')
|
||||||
|
stage_id = res_stage and res_stage[0].id or False
|
||||||
|
for job in res_job:
|
||||||
|
tasks = [(0, 0, {'name': t.name}) for t in job.task_ids]
|
||||||
|
for equipment in job.equipments_id:
|
||||||
|
res_order = order_model.create({
|
||||||
|
'name': job.name,
|
||||||
|
'user_id': job.user_id.id,
|
||||||
|
'stage_id': stage_id,
|
||||||
|
'maintenance_type': 'preventive',
|
||||||
|
'task_ids': tasks,
|
||||||
|
'attachment': job.attachment,
|
||||||
|
'entry_source': 'job',
|
||||||
|
'equipment_id': equipment.id,
|
||||||
|
'schedule_date': current_date,
|
||||||
|
})
|
||||||
|
|
||||||
|
class MaintenanceSummary(models.Model):
|
||||||
|
_name = 'maintenance.summary'
|
||||||
|
|
||||||
|
name = fields.Char('Description')
|
||||||
|
total_orders = fields.Integer('Total Orders', compute='_compute_total')
|
||||||
|
total_open = fields.Integer('Open', compute='_compute_total')
|
||||||
|
total_repair = fields.Integer('Repaired', compute='_compute_total')
|
||||||
|
total_close = fields.Integer('Closed', compute='_compute_total')
|
||||||
|
order_chart = fields.Char('Maintenance Orders')
|
||||||
|
priority_chart = fields.Char('Priority')
|
||||||
|
total_low = fields.Integer('Low', compute='_compute_total')
|
||||||
|
total_normal = fields.Integer('Normal', compute='_compute_total')
|
||||||
|
total_high = fields.Integer('High', compute='_compute_total')
|
||||||
|
planned_chart = fields.Char('Planned Maintenacne')
|
||||||
|
total_planned = fields.Integer('Planned', compute='_compute_total')
|
||||||
|
total_unplanned = fields.Integer('Un Planned', compute='_compute_total')
|
||||||
|
total_partially_effect = fields.Integer('Total Partiall Effect', compute='_compute_total')
|
||||||
|
total_downtime = fields.Integer('Total Downtime', compute='_compute_total')
|
||||||
|
total_outservice = fields.Integer('Total Out of Service', compute='_compute_total')
|
||||||
|
total_loss = fields.Integer('Loss of Production', compute='_compute_total')
|
||||||
|
|
||||||
|
def _compute_total(self):
|
||||||
|
order_model = self.env.get('maintenance.request')
|
||||||
|
stage_model = self.env.get('maintenance.stage')
|
||||||
|
stage_close = stage_model.search([('stage_type', '=', 'request_done')]).ids
|
||||||
|
stage_repair = stage_model.search([('stage_type', '=', 'repair_done')]).ids
|
||||||
|
stage_open = stage_model.search([('stage_type', 'not in', ['repair_done', 'request_done'])]).ids
|
||||||
|
self.total_orders = order_model.search_count([])
|
||||||
|
self.total_open = order_model.search_count([('stage_id', 'in', stage_open)])
|
||||||
|
self.total_repair = order_model.search_count([('stage_id', 'in', stage_repair)])
|
||||||
|
self.total_close = order_model.search_count([('stage_id', 'in', stage_close)])
|
||||||
|
self.total_low = order_model.search_count([('priority', '=', 1)])
|
||||||
|
self.total_normal = order_model.search_count([('priority', '=', 2)])
|
||||||
|
self.total_high = order_model.search_count([('priority', '=', 3)])
|
||||||
|
self.total_planned = order_model.search_count([('maintenance_category', '=', 'planned')])
|
||||||
|
self.total_unplanned = order_model.search_count(
|
||||||
|
['|', ('maintenance_category', '=', 'unplanned'), ('maintenance_category', '=', False)])
|
||||||
|
self.total_partially_effect = order_model.search_count([('machine_status', '=', 'part')])
|
||||||
|
self.total_outservice = order_model.search_count([('machine_status', '=', 'out_service')])
|
||||||
|
total_loss = 0
|
||||||
|
total_downtime = 0
|
||||||
|
for req in order_model.search([('machine_status', '=', 'part')]):
|
||||||
|
total_loss += req.product_loss
|
||||||
|
for req in order_model.search([('machine_status', '=', 'out_service')]):
|
||||||
|
total_downtime += req.down_time
|
||||||
|
self.total_downtime = total_downtime
|
||||||
|
self.total_loss = total_loss
|
||||||
|
|
||||||
|
class Locations(models.Model):
|
||||||
|
_name = 'equipment.locations'
|
||||||
|
|
||||||
|
name = fields.Char('Description')
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
class MaintenanceAsset(models.Model):
|
||||||
|
_inherit = 'maintenance.request'
|
||||||
|
|
||||||
|
asset_id = fields.Many2one(string="Asset",
|
||||||
|
comodel_name='account.asset',
|
||||||
|
required=False)
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
class MaintenanceChecklist(models.Model):
|
||||||
|
_inherit = 'maintenance.request'
|
||||||
|
|
||||||
|
checklist_lines = fields.One2many(
|
||||||
|
comodel_name='checklist.line',
|
||||||
|
inverse_name='checklist_id',
|
||||||
|
string='Checklist',
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class MaintenanceChecklistLines(models.Model):
|
||||||
|
_name = 'checklist.line'
|
||||||
|
_description = 'Inspection Checklist For Maintenance Lines'
|
||||||
|
|
||||||
|
|
||||||
|
name = fields.Char(
|
||||||
|
string='Name',
|
||||||
|
required=True)
|
||||||
|
description = fields.Char(
|
||||||
|
string='Description',
|
||||||
|
required=False)
|
||||||
|
checklist_id = fields.Many2one(
|
||||||
|
comodel_name='maintenance.request',
|
||||||
|
string='',
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
from . import general_maintenance_report
|
||||||
|
|
@ -0,0 +1,242 @@
|
||||||
|
<odoo>
|
||||||
|
<template id="equipment_report">
|
||||||
|
<t t-call="web.html_container">
|
||||||
|
<t t-call="web.external_layout">
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.date_tb{
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date_th{
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
.date_tb div{
|
||||||
|
display: table-cell;
|
||||||
|
border-color: #888888;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
padding: 10px;
|
||||||
|
min-width:30px;
|
||||||
|
}
|
||||||
|
.date_th{
|
||||||
|
background-color: #dee2e6;
|
||||||
|
}
|
||||||
|
.box{
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align: center;
|
||||||
|
margin-top:10px;
|
||||||
|
width: 150px;
|
||||||
|
height: 100px;
|
||||||
|
min-width: 150px;
|
||||||
|
min-height: 100px;
|
||||||
|
max-width: 150px;
|
||||||
|
max-height: 100px;
|
||||||
|
color:white;
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
.box-title{
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-content{
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.main-box-container, date_th{
|
||||||
|
margin:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-container{
|
||||||
|
|
||||||
|
}
|
||||||
|
.main-box-container .left{
|
||||||
|
float: left;
|
||||||
|
margin-top:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-box-container .right{
|
||||||
|
margin-left:300px;
|
||||||
|
}
|
||||||
|
.main-box-container .row{
|
||||||
|
display: table;
|
||||||
|
border-spacing: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-box-container .row .box{
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data_tb{
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
.data_tb th, #filters_tb th{
|
||||||
|
background-color: #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data_tb td , .data_tb th{
|
||||||
|
border-color: #888888;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 10px;
|
||||||
|
min-width:30px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters_tb, #filters_tb th, #filters_tb td{
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align : center;
|
||||||
|
padding : 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters_tb th, #filters_tb td{
|
||||||
|
min-width: 150px;
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zooba{
|
||||||
|
background-color:#66CDAA;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.over{
|
||||||
|
background-color:#DC143C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high{
|
||||||
|
background-color:red;
|
||||||
|
}
|
||||||
|
.open{
|
||||||
|
background-color:#FFD700;
|
||||||
|
}
|
||||||
|
.closed{
|
||||||
|
background-color:#228B22 ;
|
||||||
|
}
|
||||||
|
.total_work_order{
|
||||||
|
background-color:#87CEFA ;
|
||||||
|
}
|
||||||
|
.plan{
|
||||||
|
background-color:#6495ED ;
|
||||||
|
}
|
||||||
|
.hours{
|
||||||
|
background-color:#1E90FF ;
|
||||||
|
}
|
||||||
|
.cost{
|
||||||
|
background-color:#663399 ;
|
||||||
|
}
|
||||||
|
.downtime{
|
||||||
|
background-color:#9370DB ;
|
||||||
|
}
|
||||||
|
.loss{
|
||||||
|
background-color:#4B0082 ;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<table id="filters_tb">
|
||||||
|
<tr>
|
||||||
|
<th>Date From</th>
|
||||||
|
<th>Date To</th>
|
||||||
|
<th>Equipment</th>
|
||||||
|
<th>Category</th>
|
||||||
|
<th>Opreater</th>
|
||||||
|
<th>Spare Part</th>
|
||||||
|
<th>Machine Status</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span t-esc="time_from" /></td>
|
||||||
|
<td><span t-esc="time_to" /> </td>
|
||||||
|
<td><span t-esc="filters.get('equipment_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('category_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('user_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('spare_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('machine_status', 'ALL')" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="main-box-container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title">TOTAL EQUIPMENT</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_equipment']" /></div>
|
||||||
|
</div>
|
||||||
|
<!--div class="box total_work_order">
|
||||||
|
<div class="box-title">TOTAL Requests</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_orders']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box total_work_order">
|
||||||
|
<div class="box-title">TOTAL WORK ORDERS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_orders']" /></div>
|
||||||
|
</div-->
|
||||||
|
<div class="box high">
|
||||||
|
<div class="box-title">HIGH PRIORITY</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_high']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box open">
|
||||||
|
<div class="box-title">OPEN ORDERS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_open']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box closed">
|
||||||
|
<div class="box-title">CLOSED ORDERS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_colse']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box plan">
|
||||||
|
<div class="box-title">PLANNED VS UNPLANNED</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_planned']" />%</div>
|
||||||
|
</div>
|
||||||
|
<div class="box downtime">
|
||||||
|
<div class="box-title">TOTAL DOWNTIME</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_downtime']" /> H</div>
|
||||||
|
</div>
|
||||||
|
<div class="box loss">
|
||||||
|
<div class="box-title">TOTAL LOSSES</div>
|
||||||
|
<br />
|
||||||
|
<div class="box-content"><span t-esc="total['total_loss']" /> Units</div>
|
||||||
|
</div>
|
||||||
|
<div class="box cost">
|
||||||
|
<div class="box-title">Repair COST</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_cost']" /> SDG</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="data_tb">
|
||||||
|
<tr>
|
||||||
|
<th>NO</th>
|
||||||
|
<th>EQUIPMENT</th>
|
||||||
|
<th>Vendor</th>
|
||||||
|
<th>Opreater</th>
|
||||||
|
<th>Category</th>
|
||||||
|
<th>Corrective Maintenance</th>
|
||||||
|
<th>Preventive Maintenance</th>
|
||||||
|
<th>Machine Status</th>
|
||||||
|
<th>Down-Time</th>
|
||||||
|
<th>Losses</th>
|
||||||
|
<th>Cost</th>
|
||||||
|
</tr>
|
||||||
|
<t t-foreach="docs" t-as="o">
|
||||||
|
<tr>
|
||||||
|
<td><span t-esc="o_index+1"/></td>
|
||||||
|
<td><span t-esc="o['name']"/></td>
|
||||||
|
<td><span t-esc="o['vendor']"/></td>
|
||||||
|
<td><span t-esc="o['opreater']"/></td>
|
||||||
|
<td><span t-esc="o['category']"/></td>
|
||||||
|
<td><span t-esc="o['corrective']"/></td>
|
||||||
|
<td><span t-esc="o['preventive']"/></td>
|
||||||
|
<td><span t-esc="o['machine_status']"/></td>
|
||||||
|
<td><span t-esc="o['down_time']"/></td>
|
||||||
|
<td><span t-esc="o['loss']"/></td>
|
||||||
|
<td><span t-esc="o['cost']"/></td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,189 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
|
||||||
|
|
||||||
|
def to_str(array):
|
||||||
|
return ",".join(str(i) for i in array)
|
||||||
|
|
||||||
|
|
||||||
|
class GeneralMaintenanceReport(models.AbstractModel):
|
||||||
|
_name = 'report.maintenance_custom.general_maintenance_report'
|
||||||
|
@api.model
|
||||||
|
def _get_report_values(self, docids, data=None):
|
||||||
|
report_obj = self.env['ir.actions.report']
|
||||||
|
report = report_obj._get_report_from_name('maintenance_custom.general_maintenance_report')
|
||||||
|
rec_ids = data['form']['rec_ids']
|
||||||
|
docs = self.env.get(report.model).search([('id' , 'in', rec_ids)])
|
||||||
|
docargs = {
|
||||||
|
'doc_ids': docids,
|
||||||
|
'doc_model': report.model,
|
||||||
|
'docs': docs,
|
||||||
|
}
|
||||||
|
docargs.update(data['form'])
|
||||||
|
return docargs
|
||||||
|
|
||||||
|
|
||||||
|
class SparePartReport(models.AbstractModel):
|
||||||
|
_name = 'report.maintenance_custom.spare_part_report'
|
||||||
|
|
||||||
|
def _get_spare_data(self,order_ids,spare_ids,spare_categ_ids):
|
||||||
|
cond = ""
|
||||||
|
if spare_ids:
|
||||||
|
cond += " AND spare_id in (%s)"%(to_str(spare_ids),)
|
||||||
|
if spare_categ_ids:
|
||||||
|
cond += " AND categ_id in (%s)"%(to_str(spare_categ_ids),)
|
||||||
|
query = '''
|
||||||
|
select
|
||||||
|
spare_id as spare_id ,p.name as name, count(request_id) as order_count ,
|
||||||
|
sum(down_time) as down_time , sum(product_loss) as loss, sum(quantity * cost) as cost,
|
||||||
|
sum(quantity) as consume , cat.name as category
|
||||||
|
from maintenance_request_spare sp
|
||||||
|
join maintenance_request req on sp.request_id = req.id
|
||||||
|
join product_template p on p.id = spare_id
|
||||||
|
join product_category cat on cat.id = p.categ_id
|
||||||
|
where request_id in (%s) %s
|
||||||
|
group by spare_id, p.id, cat.id
|
||||||
|
'''%(to_str(order_ids),cond)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
res = self.env.cr.dictfetchall()
|
||||||
|
spare_model = self.env.get('product.template')
|
||||||
|
for rec in res:
|
||||||
|
sn = spare_model.browse(rec['spare_id']).barcode or '-'
|
||||||
|
qty = spare_model.browse(rec['spare_id']).qty_available
|
||||||
|
rec.update({'sn' : sn , 'stock' : qty})
|
||||||
|
return res
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _get_report_values(self, docids, data=None):
|
||||||
|
report_obj = self.env['ir.actions.report']
|
||||||
|
report = report_obj._get_report_from_name('maintenance_custom.spare_part_report')
|
||||||
|
rec_ids = data['form']['rec_ids']
|
||||||
|
spare_categ_ids = data['form']['spare_categ_ids']
|
||||||
|
spare_ids = data['form']['spare_ids']
|
||||||
|
docs = self._get_spare_data(rec_ids,spare_ids,spare_categ_ids)
|
||||||
|
docargs = {
|
||||||
|
'doc_ids': docids,
|
||||||
|
'doc_model': report.model,
|
||||||
|
'docs': docs,
|
||||||
|
}
|
||||||
|
docargs.update(data['form'])
|
||||||
|
return docargs
|
||||||
|
|
||||||
|
class EquipmentReport(models.AbstractModel):
|
||||||
|
_name = 'report.maintenance_custom.equipment_report'
|
||||||
|
|
||||||
|
def _get_data(self,order_ids,equipment_ids=None,category_ids=None):
|
||||||
|
cond = ""
|
||||||
|
if equipment_ids:
|
||||||
|
cond += " AND eq.id in (%s)"%(to_str(equipment_ids),)
|
||||||
|
if category_ids:
|
||||||
|
cond += " AND categ.id in (%s)"%(to_str(category_ids),)
|
||||||
|
order_str = ','.join(str(i) for i in order_ids)
|
||||||
|
query = '''
|
||||||
|
SELECT
|
||||||
|
eq.id as equipment_id , eq.name , vendor_partner.name as vendor , op_partner.name as opreater , categ.name as category,
|
||||||
|
sum(req.down_time) as down_time , sum(req.product_loss) as loss,
|
||||||
|
count(corrective.id) as corrective, count(preventive.id) as preventive
|
||||||
|
FROM maintenance_equipment eq
|
||||||
|
LEFT JOIN res_partner vendor_partner on vendor_partner.id = eq.partner_id
|
||||||
|
LEFT JOIN res_users users on technician_user_id = users.id
|
||||||
|
LEFT JOIN res_partner op_partner on users.partner_id = op_partner.id
|
||||||
|
LEFT JOIN maintenance_equipment_category categ on categ.id = eq.category_id
|
||||||
|
LEFT JOIN maintenance_request req on req.equipment_id = eq.id and req.id in (%s)
|
||||||
|
LEFT JOIN maintenance_request preventive on preventive.id = req.id and preventive.maintenance_type = 'preventive'
|
||||||
|
LEFT JOIN maintenance_request corrective on corrective.id = req.id and corrective.maintenance_type = 'corrective'
|
||||||
|
WHERE 1 = 1 %s
|
||||||
|
GROUP BY eq.id , vendor_partner.id, op_partner.id , categ.id
|
||||||
|
'''%(order_str,cond)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
res = self.env.cr.dictfetchall()
|
||||||
|
done_stage = self.env.get('maintenance.stage').search([('stage_type', '=', 'request_done')])
|
||||||
|
done_ids = done_stage.ids
|
||||||
|
order_model = self.env.get('maintenance.request')
|
||||||
|
machine_status_dict = dict(
|
||||||
|
out_service='Out of Service',
|
||||||
|
part='Partially effect',
|
||||||
|
in_service='In Service'
|
||||||
|
)
|
||||||
|
for rec in res:
|
||||||
|
equipment_id = rec['equipment_id']
|
||||||
|
order_res = order_model.search([('equipment_id','=',equipment_id),('stage_id', 'not in', done_ids)],order='request_date')
|
||||||
|
machine_status = order_res and order_res[-1].machine_status or '-'
|
||||||
|
cost = 0
|
||||||
|
equ_order_res = order_model.search([('equipment_id','=',equipment_id),('id', 'in', order_ids)]).ids
|
||||||
|
order_spares = self.env.get('maintenance.request.spare').search([('request_id', 'in', equ_order_res)])
|
||||||
|
for line in order_spares:
|
||||||
|
cost += line.quantity * line.cost
|
||||||
|
rec.update({'machine_status' : machine_status_dict.get(machine_status, '-') , 'cost' : cost})
|
||||||
|
return res
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _get_report_values(self, docids, data=None):
|
||||||
|
report_obj = self.env['ir.actions.report']
|
||||||
|
report = report_obj._get_report_from_name('maintenance_custom.spare_part_report')
|
||||||
|
rec_ids = data['form']['rec_ids']
|
||||||
|
category_ids = data['form']['category_ids']
|
||||||
|
equipment_ids = data['form']['equipment_ids']
|
||||||
|
docs = self._get_data(rec_ids,equipment_ids,category_ids)
|
||||||
|
docargs = {
|
||||||
|
'doc_ids': docids,
|
||||||
|
'doc_model': report.model,
|
||||||
|
'docs': docs,
|
||||||
|
}
|
||||||
|
docargs.update(data['form'])
|
||||||
|
return docargs
|
||||||
|
|
||||||
|
class TeamReport(models.AbstractModel):
|
||||||
|
_name = 'report.maintenance_custom.maintenance_team_report'
|
||||||
|
|
||||||
|
def _get_data(self,order_ids,employee_ids=None,department_ids=None):
|
||||||
|
cond = ""
|
||||||
|
if employee_ids:
|
||||||
|
cond += " AND emp.id in (%s)"%(to_str(employee_ids),)
|
||||||
|
if department_ids:
|
||||||
|
cond += " AND dep.id in (%s)"%(to_str(department_ids),)
|
||||||
|
query = '''
|
||||||
|
SELECT emp.name as name , job.name as job , dep.name as department,
|
||||||
|
count(on_time.id) as on_time, count(over_due.id) as over_due,
|
||||||
|
sum(EXTRACT(EPOCH FROM work_hours.done_time-work_hours.start_time)/3600) as work_hours,
|
||||||
|
count(closed.id) as closed , count(opened.id) as opened
|
||||||
|
FROM hr_employee emp
|
||||||
|
LEFT JOIN req_member_rel rel on rel.hr_employee_id = emp.id and rel.maintenance_request_id in (%s)
|
||||||
|
LEFT JOIN hr_department dep on dep.id = emp.department_id
|
||||||
|
LEFT JOIN hr_job job on job.id = emp.job_id
|
||||||
|
LEFT JOIN maintenance_request on_time on on_time.id = rel.maintenance_request_id
|
||||||
|
AND on_time.duration > 0 AND on_time.done_time <= on_time.schedule_date + interval '1' HOUR * on_time.duration
|
||||||
|
LEFT JOIN maintenance_request over_due on over_due.id = rel.maintenance_request_id
|
||||||
|
AND over_due.duration > 0 AND over_due.done_time > over_due.schedule_date + interval '1' HOUR * over_due.duration
|
||||||
|
LEFT JOIN maintenance_request work_hours on work_hours.id = rel.maintenance_request_id
|
||||||
|
LEFT JOIN maintenance_request opened on opened.id = rel.maintenance_request_id and opened.stage_id not in (select id from maintenance_stage where stage_type = 'request_done' )
|
||||||
|
LEFT JOIN maintenance_request closed on closed.id = rel.maintenance_request_id and closed.stage_id in (select id from maintenance_stage where stage_type = 'request_done' )
|
||||||
|
WHERE 1 = 1 %s
|
||||||
|
group by emp.id, job.id , dep.id
|
||||||
|
'''%(to_str(order_ids),cond)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
res = self.env.cr.dictfetchall()
|
||||||
|
for rec in res:
|
||||||
|
if rec.get('work_hours'):
|
||||||
|
rec.update({
|
||||||
|
'work_hours' : round(rec['work_hours'] , 2),
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _get_report_values(self, docids, data=None):
|
||||||
|
report_obj = self.env['ir.actions.report']
|
||||||
|
report = report_obj._get_report_from_name('maintenance_custom.maintenance_team_report')
|
||||||
|
rec_ids = data['form']['rec_ids']
|
||||||
|
employee_ids = data['form']['employee_ids']
|
||||||
|
department_ids = data['form']['department_ids']
|
||||||
|
docs = self._get_data(rec_ids,employee_ids,department_ids)
|
||||||
|
docargs = {
|
||||||
|
'doc_ids': docids,
|
||||||
|
'doc_model': report.model,
|
||||||
|
'docs': docs,
|
||||||
|
}
|
||||||
|
docargs.update(data['form'])
|
||||||
|
return docargs
|
||||||
|
|
@ -0,0 +1,270 @@
|
||||||
|
<odoo>
|
||||||
|
<template id="general_maintenance_report">
|
||||||
|
<t t-call="web.html_container">
|
||||||
|
<t t-call="web.external_layout">
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.date_tb{
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date_th{
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
.date_tb div{
|
||||||
|
display: table-cell;
|
||||||
|
border-color: #888888;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
padding: 10px;
|
||||||
|
min-width:30px;
|
||||||
|
}
|
||||||
|
.date_th{
|
||||||
|
background-color: #dee2e6;
|
||||||
|
}
|
||||||
|
.box{
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align: center;
|
||||||
|
margin-top:10px;
|
||||||
|
width: 150px;
|
||||||
|
height: 100px;
|
||||||
|
min-width: 150px;
|
||||||
|
min-height: 100px;
|
||||||
|
max-width: 150px;
|
||||||
|
max-height: 100px;
|
||||||
|
color:white;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.box-title{
|
||||||
|
margin: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-content{
|
||||||
|
margin: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.main-box-container, date_th{
|
||||||
|
margin:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-container{
|
||||||
|
|
||||||
|
}
|
||||||
|
.main-box-container .left{
|
||||||
|
float: left;
|
||||||
|
margin-top:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-box-container .right{
|
||||||
|
margin-left:300px;
|
||||||
|
}
|
||||||
|
.main-box-container .row{
|
||||||
|
display: table;
|
||||||
|
border-spacing: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-box-container .row .box{
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data_tb{
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
.data_tb th, #filters_tb th{
|
||||||
|
background-color: #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data_tb td , .data_tb th{
|
||||||
|
border-color: #888888;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 10px;
|
||||||
|
min-width:30px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters_tb, #filters_tb th, #filters_tb td{
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align : center;
|
||||||
|
padding : 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters_tb th, #filters_tb td{
|
||||||
|
min-width: 150px;
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zooba{
|
||||||
|
background-color:#66CDAA;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.over{
|
||||||
|
background-color:#DC143C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high{
|
||||||
|
background-color:red;
|
||||||
|
}
|
||||||
|
.open{
|
||||||
|
background-color:#FFD700;
|
||||||
|
}
|
||||||
|
.closed{
|
||||||
|
background-color:#228B22 ;
|
||||||
|
}
|
||||||
|
.total_work_order{
|
||||||
|
background-color:#87CEFA ;
|
||||||
|
}
|
||||||
|
.plan{
|
||||||
|
background-color:#6495ED ;
|
||||||
|
}
|
||||||
|
.hours{
|
||||||
|
background-color:#1E90FF ;
|
||||||
|
}
|
||||||
|
.cost{
|
||||||
|
background-color:#663399 ;
|
||||||
|
}
|
||||||
|
.downtime{
|
||||||
|
background-color:#9370DB ;
|
||||||
|
}
|
||||||
|
.loss{
|
||||||
|
background-color:#4B0082 ;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<table id="filters_tb">
|
||||||
|
<tr>
|
||||||
|
<th>Date From</th>
|
||||||
|
<th>Date To</th>
|
||||||
|
<th>Equipment</th>
|
||||||
|
<th>Category</th>
|
||||||
|
<th>FAILURE TYPE</th>
|
||||||
|
<th>Supervisor</th>
|
||||||
|
<th>Team Member</th>
|
||||||
|
<th>Team Type</th>
|
||||||
|
<th>Spare Part</th>
|
||||||
|
<th>Machine Status</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span t-esc="time_from" /></td>
|
||||||
|
<td><span t-esc="time_to" /> </td>
|
||||||
|
<td><span t-esc="filters.get('equipment_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('category_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('failure_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('user_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('employee_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('team_type', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('spare_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('machine_status', 'ALL')" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="main-box-container">
|
||||||
|
<div class="">
|
||||||
|
<div class="row">
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title">TOTAL EQUIPMENT</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_equipment']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box total_work_order">
|
||||||
|
<div class="box-title">TOTAL WORK ORDERS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_orders']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box closed">
|
||||||
|
<div class="box-title">CLOSED ORDERS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_colse']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box open">
|
||||||
|
<div class="box-title">OPEN ORDERS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_open']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box over">
|
||||||
|
<div class="box-title">OVER DUUE TASKS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_over_due']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box high">
|
||||||
|
<div class="box-title">HIGH PRIORITY</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_high']" /></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title"><br />TOTAL STAFF<br /> </div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_members']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box plan">
|
||||||
|
<div class="box-title">PLANNED VS UNPLANNED</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_planned']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box hours">
|
||||||
|
<div class="box-title"> WORKING HOURS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_working_hours']" />H</div>
|
||||||
|
</div>
|
||||||
|
<div class="box cost">
|
||||||
|
<div class="box-title"><br />REPAIR COST<br /> </div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_cost']" /> SDG</div>
|
||||||
|
</div>
|
||||||
|
<div class="box downtime">
|
||||||
|
<div class="box-title">TOTAL DOWNTIME</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_downtime']" /> H</div>
|
||||||
|
</div>
|
||||||
|
<div class="box loss">
|
||||||
|
<div class="box-title"><br />TOTAL LOSSES <br /> </div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_loss']" /> Unit</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="data_tb">
|
||||||
|
<tr>
|
||||||
|
<th>JOB NO</th>
|
||||||
|
<th>DATE</th>
|
||||||
|
<th>EQUIPMENT</th>
|
||||||
|
<th>TITLE</th>
|
||||||
|
<th>MAINTENANCE Type</th>
|
||||||
|
<th>FAILURE TYPE</th>
|
||||||
|
<th>PRIORITY</th>
|
||||||
|
<th>ASSIGN STAFF</th>
|
||||||
|
<th>TEAM</th>
|
||||||
|
<th>MAN POWER</th>
|
||||||
|
<th>Machine Status</th>
|
||||||
|
<th>Down-Time</th>
|
||||||
|
<th>LOSSES</th>
|
||||||
|
<th>WORK Stage</th>
|
||||||
|
</tr>
|
||||||
|
<t t-foreach="docs" t-as="o">
|
||||||
|
<tr>
|
||||||
|
<td><span t-field="o.code"/></td>
|
||||||
|
<td><span t-field="o.request_date"/></td>
|
||||||
|
<td><span t-field="o.equipment_id.name"/></td>
|
||||||
|
<td><span t-field="o.name"/></td>
|
||||||
|
<td><span t-field="o.maintenance_type"/></td>
|
||||||
|
<td><span t-field="o.failure_id.name"/></td>
|
||||||
|
<td><span t-field="o.priority"/></td>
|
||||||
|
<td><span t-field="o.user_id.name"/></td>
|
||||||
|
<td>
|
||||||
|
<span t-if="o.team_type=='in'"><span t-field="o.team_type"/></span>
|
||||||
|
<span t-if="o.team_type=='out'"><span t-field="o.out_entity_id.name"/></span>
|
||||||
|
</td>
|
||||||
|
<td><span t-esc="len(o.employee_ids.ids)" /></td>
|
||||||
|
<td><span t-field="o.machine_status"/></td>
|
||||||
|
<td><span t-field="o.down_time"/></td>
|
||||||
|
<td><span t-field="o.product_loss"/></td>
|
||||||
|
<td><span t-field="o.stage_id.name"/></td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<report id="action_report_maintenance"
|
||||||
|
model="maintenance.request"
|
||||||
|
string="Maintenance Form"
|
||||||
|
report_type="qweb-pdf"
|
||||||
|
name="maintenance_custom.report_maintenance_request"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<report id="action_general_maintenance_report"
|
||||||
|
model="maintenance.request"
|
||||||
|
string="General Maintenance"
|
||||||
|
report_type="qweb-pdf"
|
||||||
|
name="maintenance_custom.general_maintenance_report"
|
||||||
|
menu="False"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<report id="action_spare_part_report"
|
||||||
|
model="maintenance.request"
|
||||||
|
string="Spare Parts"
|
||||||
|
report_type="qweb-pdf"
|
||||||
|
name="maintenance_custom.spare_part_report"
|
||||||
|
menu="False"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<report id="action_equipment_report"
|
||||||
|
model="maintenance.request"
|
||||||
|
string="Equipment"
|
||||||
|
report_type="qweb-pdf"
|
||||||
|
name="maintenance_custom.equipment_report"
|
||||||
|
menu="False"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<report id="action_maintenance_team_report"
|
||||||
|
model="maintenance.request"
|
||||||
|
string="Maintenance Team"
|
||||||
|
report_type="qweb-pdf"
|
||||||
|
name="maintenance_custom.maintenance_team_report"
|
||||||
|
menu="False"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
<odoo>
|
||||||
|
<template id="maintenance_team_report">
|
||||||
|
<t t-call="web.html_container">
|
||||||
|
<t t-call="web.external_layout">
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.date_tb{
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date_th{
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
.date_tb div{
|
||||||
|
display: table-cell;
|
||||||
|
border-color: #888888;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
padding: 10px;
|
||||||
|
min-width:30px;
|
||||||
|
}
|
||||||
|
.date_th{
|
||||||
|
background-color: #dee2e6;
|
||||||
|
}
|
||||||
|
.box{
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align: center;
|
||||||
|
margin-top:10px;
|
||||||
|
width: 150px;
|
||||||
|
height: 100px;
|
||||||
|
min-width: 150px;
|
||||||
|
min-height: 100px;
|
||||||
|
max-width: 150px;
|
||||||
|
max-height: 100px;
|
||||||
|
color:white;
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
.box-title{
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-content{
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.main-box-container, date_th{
|
||||||
|
margin:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-container{
|
||||||
|
|
||||||
|
}
|
||||||
|
.main-box-container .left{
|
||||||
|
float: left;
|
||||||
|
margin-top:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-box-container .right{
|
||||||
|
margin-left:300px;
|
||||||
|
}
|
||||||
|
.main-box-container .row{
|
||||||
|
display: table;
|
||||||
|
border-spacing: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-box-container .row .box{
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data_tb{
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
.data_tb th, #filters_tb th{
|
||||||
|
background-color: #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data_tb td , .data_tb th{
|
||||||
|
border-color: #888888;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 10px;
|
||||||
|
min-width:30px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters_tb, #filters_tb th, #filters_tb td{
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align : center;
|
||||||
|
padding : 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters_tb th, #filters_tb td{
|
||||||
|
min-width: 150px;
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zooba{
|
||||||
|
background-color:#66CDAA;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.over{
|
||||||
|
background-color:#DC143C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high{
|
||||||
|
background-color:red;
|
||||||
|
}
|
||||||
|
.open{
|
||||||
|
background-color:#FFD700;
|
||||||
|
}
|
||||||
|
.closed{
|
||||||
|
background-color:#228B22 ;
|
||||||
|
}
|
||||||
|
.total_work_order{
|
||||||
|
background-color:#87CEFA ;
|
||||||
|
}
|
||||||
|
.plan{
|
||||||
|
background-color:#6495ED ;
|
||||||
|
}
|
||||||
|
.hours{
|
||||||
|
background-color:#1E90FF ;
|
||||||
|
}
|
||||||
|
.cost{
|
||||||
|
background-color:#663399 ;
|
||||||
|
}
|
||||||
|
.downtime{
|
||||||
|
background-color:#9370DB ;
|
||||||
|
}
|
||||||
|
.loss{
|
||||||
|
background-color:#4B0082 ;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<table id="filters_tb">
|
||||||
|
<tr>
|
||||||
|
<th>Date From</th>
|
||||||
|
<th>Date To</th>
|
||||||
|
<th>Departments</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span t-esc="time_from" /></td>
|
||||||
|
<td><span t-esc="time_to" /> </td>
|
||||||
|
<td><span t-esc="filters.get('department_id', 'ALL')" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="main-box-container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title">TOTAL Tasks</div>
|
||||||
|
<br />
|
||||||
|
<div class="box-content"><span t-esc="total['total_orders']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box open">
|
||||||
|
<div class="box-title">OPEN ORDERS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_open']" /></div>
|
||||||
|
</div>
|
||||||
|
<!--div class="box closed">
|
||||||
|
<div class="box-title">DONE ON TIME</div>
|
||||||
|
<div class="box-content">22</div>
|
||||||
|
</div-->
|
||||||
|
<div class="box over">
|
||||||
|
<div class="box-title">OVER DUE TASKS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['over_due_percentage']" />%</div>
|
||||||
|
</div>
|
||||||
|
<div class="box cost">
|
||||||
|
<div class="box-title">WORKING HOURS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_working_hours']" /> H</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="data_tb">
|
||||||
|
<tr>
|
||||||
|
<th>NO</th>
|
||||||
|
<th>NAME</th>
|
||||||
|
<th>POSITION</th>
|
||||||
|
<th>DEPARMENT</th>
|
||||||
|
<th>OPENNED TASKS</th>
|
||||||
|
<th>CLOSED TASKS</th>
|
||||||
|
<th>ON-TIME</th>
|
||||||
|
<th>OVERDUE</th>
|
||||||
|
<th>WORKING HOURS</th>
|
||||||
|
</tr>
|
||||||
|
<t t-foreach="docs" t-as="o">
|
||||||
|
<tr>
|
||||||
|
<td><span t-esc="o_index+1"/></td>
|
||||||
|
<td><span t-esc="o['name']"/></td>
|
||||||
|
<td><span t-esc="o['job']"/></td>
|
||||||
|
<td><span t-esc="o['department']"/></td>
|
||||||
|
<td><span t-esc="o['opened']"/></td>
|
||||||
|
<td><span t-esc="o['closed']"/></td>
|
||||||
|
<td><span t-esc="o['on_time']"/></td>
|
||||||
|
<td><span t-esc="o['over_due']"/></td>
|
||||||
|
<td><span t-esc="o['work_hours']"/></td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,160 @@
|
||||||
|
<odoo>
|
||||||
|
<template id="report_maintenance_request">
|
||||||
|
<t t-call="web.html_container">
|
||||||
|
<t t-foreach="docs" t-as="o">
|
||||||
|
<t t-call="web.external_layout">
|
||||||
|
<style>
|
||||||
|
|
||||||
|
td, th{
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align:center;
|
||||||
|
margin-bottom:40px;
|
||||||
|
|
||||||
|
}
|
||||||
|
th{
|
||||||
|
background-color:cadetblue;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
th,td{
|
||||||
|
border: 1px solid black;
|
||||||
|
min-width:80px;
|
||||||
|
min-height:20px;
|
||||||
|
height:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#failure_tb th , #repair_tb th , #down_tb th , #manager_tb th {
|
||||||
|
word-wrap: break-word;
|
||||||
|
min-width:30px;
|
||||||
|
max-width:60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#repair_tb th {
|
||||||
|
word-wrap: break-word;
|
||||||
|
min-width:30px;
|
||||||
|
max-width:100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<center>
|
||||||
|
<div class="page">
|
||||||
|
<h1>Failure report</h1>
|
||||||
|
<table width="90%" height="100%">
|
||||||
|
<tr>
|
||||||
|
<th colspan="8">REQUEST INFORMATION</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>REQUESTER</th><td colspan="2"><span t-field="o.employee_id.name"/></td>
|
||||||
|
<th>REQUEST NO</th><td colspan="1"><span t-field="o.code"/></td>
|
||||||
|
<th>DATE/TIME</th><td colspan="2"><span t-field="o.request_date"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th >EQUIPMENT</th><td colspan="2"><span t-field="o.equipment_id.name"/></td>
|
||||||
|
<th>EQUIPMENT CONDITION</th><td colspan="4"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<span t-if="o.maintenance_type=='corrective'">
|
||||||
|
<table width="90%" height="100%" id="failure_tb">
|
||||||
|
<tr>
|
||||||
|
<th colspan="8">FAILURE</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>FAILURE TYPE</th><td colspan="2"><span t-field="o.failure_id.name"/></td>
|
||||||
|
<th>FAILED COMPONANT</th><td colspan="4"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>FAILURE CAUSE</th><td colspan="7"><span t-field="o.failure_cause_id.name"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>HOW FAILURE WAS DETECTED</th><td colspan="7"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table width="90%" height="100%" id="repair_tb">
|
||||||
|
<tr>
|
||||||
|
<th colspan="8">REPAIRING AND CORRECTION ACTION</th>
|
||||||
|
</tr>
|
||||||
|
<tr height="120px">
|
||||||
|
<th>CORRECTION ACTION</th>
|
||||||
|
<td colspan="8"><span t-field="o.maintenance_work"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>REPAIR COMPLATE DATE AND TIME</th>
|
||||||
|
<td><span t-field="o.done_time"/></td>
|
||||||
|
<th>REPAIR DURATION</th>
|
||||||
|
<td><span t-field="o.duration"/></td>
|
||||||
|
<th>EQUIPMENT CONDITION</th>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table width="90%" height="100%" id="down_tb">
|
||||||
|
<tr>
|
||||||
|
<th colspan="8">DOWNTIME AND LOSSES</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>DOWNTIME</th>
|
||||||
|
<td colspan="3"><span t-field="o.down_time"/></td>
|
||||||
|
<th>LOSSES OF PRODUCTION</th>
|
||||||
|
<td colspan="3"><span t-field="o.product_loss"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</span>
|
||||||
|
<span t-if="o.maintenance_type=='preventive'">
|
||||||
|
<table width="90%" height="100%" id="down_tb">
|
||||||
|
<tr>
|
||||||
|
<th colspan="8">Tasks Details</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Task Title</th>
|
||||||
|
<th>Employee</th>
|
||||||
|
<th>Executing Time</th>
|
||||||
|
<th>Duration</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
<t t-foreach="o.task_ids" t-as="t">
|
||||||
|
<tr>
|
||||||
|
<td><span t-field="t.name"/></td>
|
||||||
|
<td><span t-field="t.employee_id.name"/></td>
|
||||||
|
<td><span t-field="t.time"/></td>
|
||||||
|
<td><span t-field="t.duration"/></td>
|
||||||
|
<td>
|
||||||
|
<span t-if="t.is_done">Done</span>
|
||||||
|
<span t-else="" >Pending</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
<span t-if="len(o.task_ids) < 3">
|
||||||
|
<t t-foreach="range(3-len(o.task_ids))" t-as="i">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</span>
|
||||||
|
</table>
|
||||||
|
</span>
|
||||||
|
<table width="90%" height="100%" id="manager_tb">
|
||||||
|
<tr>
|
||||||
|
<th>SUPERVISOR</th>
|
||||||
|
<td colspan="3"><span t-field="o.user_id"/></td>
|
||||||
|
<th>MANAGER</th>
|
||||||
|
<td colspan="3">Administrator</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
<odoo>
|
||||||
|
<template id="spare_part_report">
|
||||||
|
<t t-call="web.html_container">
|
||||||
|
<t t-call="web.external_layout">
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.date_tb{
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date_th{
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
.date_tb div{
|
||||||
|
display: table-cell;
|
||||||
|
border-color: #888888;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
padding: 10px;
|
||||||
|
min-width:30px;
|
||||||
|
}
|
||||||
|
.date_th{
|
||||||
|
background-color: #dee2e6;
|
||||||
|
}
|
||||||
|
.box{
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align: center;
|
||||||
|
margin-top:10px;
|
||||||
|
width: 150px;
|
||||||
|
height: 100px;
|
||||||
|
min-width: 150px;
|
||||||
|
min-height: 100px;
|
||||||
|
max-width: 150px;
|
||||||
|
max-height: 100px;
|
||||||
|
color:white;
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
.box-title{
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-content{
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.main-box-container, date_th{
|
||||||
|
margin:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-container{
|
||||||
|
|
||||||
|
}
|
||||||
|
.main-box-container .left{
|
||||||
|
float: left;
|
||||||
|
margin-top:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-box-container .right{
|
||||||
|
margin-left:300px;
|
||||||
|
}
|
||||||
|
.main-box-container .row{
|
||||||
|
display: table;
|
||||||
|
border-spacing: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-box-container .row .box{
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data_tb{
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
.data_tb th, #filters_tb th{
|
||||||
|
background-color: #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data_tb td , .data_tb th{
|
||||||
|
border-color: #888888;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 10px;
|
||||||
|
min-width:100px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters_tb, #filters_tb th, #filters_tb td{
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align : center;
|
||||||
|
padding : 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filters_tb th, #filters_tb td{
|
||||||
|
min-width: 150px;
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zooba{
|
||||||
|
background-color:#66CDAA;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.over{
|
||||||
|
background-color:#DC143C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high{
|
||||||
|
background-color:red;
|
||||||
|
}
|
||||||
|
.open{
|
||||||
|
background-color:#FFD700;
|
||||||
|
}
|
||||||
|
.closed{
|
||||||
|
background-color:#228B22 ;
|
||||||
|
}
|
||||||
|
.total_work_order{
|
||||||
|
background-color:#87CEFA ;
|
||||||
|
}
|
||||||
|
.plan{
|
||||||
|
background-color:#6495ED ;
|
||||||
|
}
|
||||||
|
.hours{
|
||||||
|
background-color:#1E90FF ;
|
||||||
|
}
|
||||||
|
.cost{
|
||||||
|
background-color:#663399 ;
|
||||||
|
}
|
||||||
|
.downtime{
|
||||||
|
background-color:#9370DB ;
|
||||||
|
}
|
||||||
|
.loss{
|
||||||
|
background-color:#4B0082 ;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<center>
|
||||||
|
<table id="filters_tb">
|
||||||
|
<tr>
|
||||||
|
<th>Date From</th>
|
||||||
|
<th>Date To</th>
|
||||||
|
<th>Spare Part</th>
|
||||||
|
<th>Category</th>
|
||||||
|
<th>Equipment</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span t-esc="time_from" /></td>
|
||||||
|
<td><span t-esc="time_to" /> </td>
|
||||||
|
<td><span t-esc="filters.get('spare_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('spare_categ_id', 'ALL')" /></td>
|
||||||
|
<td><span t-esc="filters.get('equipment_id', 'ALL')" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="main-box-container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title">TOTAL EQUIPMENT</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_equipment']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box total_work_order">
|
||||||
|
<div class="box-title">TOTAL WORK ORDERS</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_orders']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box high">
|
||||||
|
<div class="box-title">HIGH PRIORITY</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_high']" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="box downtime">
|
||||||
|
<div class="box-title">TOTAL DOWNTIME</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_downtime']" /> H</div>
|
||||||
|
</div>
|
||||||
|
<div class="box loss">
|
||||||
|
<div class="box-title">TOTAL LOSSES</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_loss']" /> </div>
|
||||||
|
</div>
|
||||||
|
<div class="box cost">
|
||||||
|
<div class="box-title">Repair COST</div>
|
||||||
|
<div class="box-content"><span t-esc="total['total_cost']" /> SDG</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="data_tb">
|
||||||
|
<tr>
|
||||||
|
<th>NO</th>
|
||||||
|
<th>PART</th>
|
||||||
|
<th>S/N</th>
|
||||||
|
<th>CATEGORY</th>
|
||||||
|
<th>CONSUMPTION</th>
|
||||||
|
<th>STOCK</th>
|
||||||
|
<th>NO. OF WORK ORDER</th>
|
||||||
|
<th>Down-Time</th>
|
||||||
|
<th>LOSSES</th>
|
||||||
|
<th>COST</th>
|
||||||
|
</tr>
|
||||||
|
<t t-foreach="docs" t-as="o">
|
||||||
|
<tr>
|
||||||
|
<td><span t-esc="o_index+1"/></td>
|
||||||
|
<td><span t-esc="o['name']"/></td>
|
||||||
|
<td><span t-esc="o['sn']"/></td>
|
||||||
|
<td><span t-esc="o['category']"/></td>
|
||||||
|
<td><span t-esc="o['consume']"/></td>
|
||||||
|
<td><span t-esc="o['stock']"/></td>
|
||||||
|
<td><span t-esc="o['order_count']"/></td>
|
||||||
|
<td><span t-esc="o['down_time']"/></td>
|
||||||
|
<td><span t-esc="o['loss']"/></td>
|
||||||
|
<td><span t-esc="o['cost']"/></td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<record id="maintenance_order_stage_visibility_stage_group" model="res.groups">
|
||||||
|
<field name="name">Maintenance Order Acceptation</field>
|
||||||
|
</record>
|
||||||
|
<record id="request_order_stage" model="res.groups">
|
||||||
|
<field name="name">Request Order Acceptation</field>
|
||||||
|
</record>
|
||||||
|
<record id="maintenance_order_done" model="res.groups">
|
||||||
|
<field name="name">Maintenance Order Done</field>
|
||||||
|
</record>
|
||||||
|
<record id="maintenance_order_stage_cancel_visibility_stage_group" model="res.groups">
|
||||||
|
<field name="name">Maintenance Order Cancel</field>
|
||||||
|
</record>
|
||||||
|
<record id="maintenance_order_set_to_draft" model="res.groups">
|
||||||
|
<field name="name">Maintenance Order ٍSet To Draft</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_equipment_job,equipment.job.user,model_maintenance_equipment_job,base.group_user,1,0,0,0
|
||||||
|
access_equipment_job_admin_user,equipment.job.admin.user,model_maintenance_equipment_job,maintenance.group_equipment_manager,1,1,1,1
|
||||||
|
access_equipments_jobs,equipments.jobs,model_maintenance_equipments_jobs,,1,1,1,1
|
||||||
|
access_equipment_task,equipment.task.user,model_maintenance_equipment_task,base.group_user,1,0,0,0
|
||||||
|
access_equipment_task_admin_user,equipment.task.admin.user,model_maintenance_equipment_task,maintenance.group_equipment_manager,1,1,1,1
|
||||||
|
access_request_task,request.task.user,model_maintenance_request_task,base.group_user,1,0,0,0
|
||||||
|
access_request_task_admin_user,request.task.admin.user,model_maintenance_request_task,maintenance.group_equipment_manager,1,1,1,1
|
||||||
|
access_maintenance_rootfailure,access_maintenance_rootfailure,model_maintenance_rootfailure,base.group_user,1,0,0,0
|
||||||
|
access_maintenance_rootfailure_admin,access_maintenance_rootfailure,model_maintenance_rootfailure,maintenance.group_equipment_manager,1,1,1,1
|
||||||
|
access_maintenance_report_wiz,access_maintenance_report_wiz,model_maintenance_report_wiz,base.group_user,1,1,1,1
|
||||||
|
access_maintenance_failure,access_maintenance_failure,model_maintenance_failure,base.group_user,1,0,0,0
|
||||||
|
access_maintenance_failure_admin,access_maintenance_failure_admin,model_maintenance_failure,maintenance.group_equipment_manager,1,1,1,1
|
||||||
|
access_maintenance_req_spare,access_maintenance_req_spare,model_maintenance_request_spare,base.group_user,1,0,0,0
|
||||||
|
access_maintenance_req_spare_admin,access_maintenance_req_spare_admin,model_maintenance_request_spare,maintenance.group_equipment_manager,1,1,1,1
|
||||||
|
access_maintenance_summary,maintenance_summary_user,model_maintenance_summary,base.group_user,1,0,0,0
|
||||||
|
access_maintenance_matrial,maintenance_matrial_user,model_matrial_line,base.group_user,1,1,1,1
|
||||||
|
access_checklist_line,maintenance_checklist_line,model_checklist_line,base.group_user,1,1,1,1
|
||||||
|
access_equipment_locations,equipment_locations,model_equipment_locations,,1,1,1,1
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* DOM element rendering detection
|
||||||
|
* https://davidwalsh.name/detect-node-insertion
|
||||||
|
*/
|
||||||
|
@keyframes chartjs-render-animation {
|
||||||
|
from { opacity: 0.99; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.chartjs-render-monitor {
|
||||||
|
animation: chartjs-render-animation 0.001s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DOM element resizing detection
|
||||||
|
* https://github.com/marcj/css-element-queries
|
||||||
|
*/
|
||||||
|
.chartjs-size-monitor,
|
||||||
|
.chartjs-size-monitor-expand,
|
||||||
|
.chartjs-size-monitor-shrink {
|
||||||
|
position: absolute;
|
||||||
|
direction: ltr;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chartjs-size-monitor-expand > div {
|
||||||
|
position: absolute;
|
||||||
|
width: 1000000px;
|
||||||
|
height: 1000000px;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chartjs-size-monitor-shrink > div {
|
||||||
|
position: absolute;
|
||||||
|
width: 200%;
|
||||||
|
height: 200%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1 @@
|
||||||
|
@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,71 @@
|
||||||
|
odoo.define('maintenance.charts', function (require) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var AbstractField = require('web.AbstractField');
|
||||||
|
var registry = require('web.field_registry');
|
||||||
|
|
||||||
|
var FieldChart = AbstractField.extend({
|
||||||
|
className: 'pichart',
|
||||||
|
_render: function () {
|
||||||
|
var self = this
|
||||||
|
var fields = self.attrs.keys.split(';')
|
||||||
|
var labels = self.attrs.labels.split(';')
|
||||||
|
var backgroundColors = self.attrs.backgroundColors.split(';')
|
||||||
|
var borderColors = self.attrs.borderColors.split(';')
|
||||||
|
var cutoutPercentage = 50
|
||||||
|
if (self.attrs.cutoutPercentage){
|
||||||
|
cutoutPercentage = self.attrs.cutoutPercentage
|
||||||
|
}
|
||||||
|
|
||||||
|
self._rpc({
|
||||||
|
model: self.model,
|
||||||
|
method: 'search_read',
|
||||||
|
fields: fields,
|
||||||
|
domain: [['id', '=', self.res_id]],
|
||||||
|
}).then(function (result) {
|
||||||
|
var vals = result[0]
|
||||||
|
var data = []
|
||||||
|
for (var f = 0 ; f < fields.length ; f++) {
|
||||||
|
var fld = fields[f]
|
||||||
|
data += [vals[fld]]
|
||||||
|
}
|
||||||
|
var ctx = document.createElement("canvas");
|
||||||
|
var myChart = new Chart(ctx, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels:labels ,
|
||||||
|
datasets: [{
|
||||||
|
label: '# Work Orders',
|
||||||
|
data: data,
|
||||||
|
backgroundColor : backgroundColors,
|
||||||
|
borderColor:borderColors,
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive : true,
|
||||||
|
cutoutPercentage : cutoutPercentage,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: self.value,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: true,
|
||||||
|
position : 'right',
|
||||||
|
labels : {
|
||||||
|
boxWidth : 15,
|
||||||
|
usePointStyle : false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//this.$el.empty();
|
||||||
|
self.$el.append(ctx)
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
registry.add('pichart', FieldChart)
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
odoo.oepetstore = function(instance, local) {
|
||||||
|
var _t = instance.web._t,
|
||||||
|
_lt = instance.web._lt;
|
||||||
|
var QWeb = instance.web.qweb;
|
||||||
|
|
||||||
|
local.HomePage = instance.Widget.extend({
|
||||||
|
start: function() {
|
||||||
|
console.log("pet store home page loaded");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.web.client_actions.add(
|
||||||
|
'petstore.homepage', 'instance.oepetstore.HomePage');
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
|
||||||
|
|
||||||
|
.o_kanban_view.o_kanban_ungrouped.o_kanban_dashboard.o_maintenance_summary {
|
||||||
|
|
||||||
|
.panel.large {
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
.panel.med {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_kanban_record{
|
||||||
|
background-color: white;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-title{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-title{
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: -apple-system, system-ui, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||||
|
letter-spacing: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #888888;
|
||||||
|
padding: 0 0 4px;
|
||||||
|
border-bottom: 1px solid #F2F2F2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxes{
|
||||||
|
display: table;
|
||||||
|
border-spacing: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top:5px;
|
||||||
|
width: 100%; /*Optional*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.box{
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border-color: #ced4da;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
background-color: white;
|
||||||
|
color: #5D8DA8;
|
||||||
|
text-align: center;
|
||||||
|
margin-top:50px;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box:hover{
|
||||||
|
color: #324e5d;
|
||||||
|
}
|
||||||
|
.box-title{
|
||||||
|
margin: 10px;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-content{
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger{
|
||||||
|
color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.done{
|
||||||
|
color:#28a745;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
<t t-name="ChartTemplate">
|
||||||
|
<div style="background-color: red;">This is some simple HTML</div>
|
||||||
|
</t>
|
||||||
|
</templates>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<templates>
|
||||||
|
<div t-name="maintenance.report.action">
|
||||||
|
<div>
|
||||||
|
<h1>Hello</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</templates>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!-- Inherit Form View to Modify it -->
|
||||||
|
<record id="equipment_order_form_inherit" model="ir.ui.view">
|
||||||
|
<field name="name">equipment.order.form.inherit</field>
|
||||||
|
<field name="model">maintenance.request</field>
|
||||||
|
<field name="inherit_id" ref="maintenance_custom.hr_equipment_order_view_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='email_cc']" position="before">
|
||||||
|
|
||||||
|
<label for="asset_id" invisible="0"/>
|
||||||
|
<div invisible="0">
|
||||||
|
<field name="asset_id"
|
||||||
|
class="oe_inline"/>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="asset_maintenance_order_form_inherit" model="ir.ui.view">
|
||||||
|
<field name="name">asset.maintenance.order.form.inherit</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='company_id']" position="after">
|
||||||
|
<field name="asset_id"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!-- Inherit Form View to Modify it -->
|
||||||
|
<record id="equipment_request_form_checklist" model="ir.ui.view">
|
||||||
|
<field name="name">equipment.request.form.checklist</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="//page[@name='assets_info']" position="after">
|
||||||
|
<page string="Checklist" name="checklist_info">
|
||||||
|
<field name="checklist_lines">
|
||||||
|
<tree string="Checklist For Inspection" editable="bottom">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="description"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,726 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
<template id="assets_backend" name="maintenance assets" inherit_id="web.assets_backend">
|
||||||
|
<xpath expr="." position="inside">
|
||||||
|
<link rel="stylesheet" type="text/scss" href="/maintenance_custom/static/src/summary.scss"/>
|
||||||
|
<link rel="stylesheet" type="text/scss" href="/maintenance_custom/static/src/js/Chart.css"/>
|
||||||
|
<script type="text/javascript" src="/maintenance_custom/static/src/js/Chart.js"></script>
|
||||||
|
<script type="text/javascript" src="/maintenance_custom/static/src/js/maintenance_charts.js"></script>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<record id="product_template_only_form_view_inhrit" model="ir.ui.view">
|
||||||
|
<field name="name">product.template</field>
|
||||||
|
<field name="model">product.template</field>
|
||||||
|
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="barcode" position="after">
|
||||||
|
<field name="is_spare"/>
|
||||||
|
<field name="is_tool"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="equipments_locations_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">equipment.locations</field>
|
||||||
|
<field name="model">equipment.locations</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<field name="name"/>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="equipments_locations_view_tree" model="ir.ui.view">
|
||||||
|
<field name="name">equipment.locations.tree</field>
|
||||||
|
<field name="model">equipment.locations</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="Equipment Locations">
|
||||||
|
<field name="name"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="equipments_locations_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">Equipment Locations</field>
|
||||||
|
<field name="res_model">equipment.locations</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="hr_equipment_job_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">maintenance.equipment.job</field>
|
||||||
|
<field name="model">maintenance.equipment.job</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<div class="oe_title">
|
||||||
|
<label for="name" class="oe_edit_only" string="Title" readonly="True"/>
|
||||||
|
<h1>
|
||||||
|
<field name="name" placeholder="Maintenance Request" required="1"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="user_id" required="1"/>
|
||||||
|
<field name="period" required="1"/>
|
||||||
|
<field name="start_date" required="1"/>
|
||||||
|
<field name="attachment" required="0"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="period_type" required="1"/>
|
||||||
|
<field name="maintenance_time" widget="float_time"/>
|
||||||
|
<field name="next_action_date" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group string="Related Tasks">
|
||||||
|
<field name="task_ids" nolabel="1">
|
||||||
|
<tree editable="bottom">
|
||||||
|
<field name="sequence" widget="handle"/>
|
||||||
|
<field name="name"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</group>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="hr_equipments_jobs_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">maintenance.equipments.jobs</field>
|
||||||
|
<field name="model">maintenance.equipments.jobs</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="creat_equi" type="object" class="oe_stat_button" icon="fa-wrench"
|
||||||
|
string="Create Jobs">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="oe_title">
|
||||||
|
<label for="name" class="oe_edit_only" string="Title" readonly="True"/>
|
||||||
|
<h1>
|
||||||
|
<field name="name" placeholder="Maintenance Request" required="1"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="equipments_id" required="1" widget="many2many_tags"/>
|
||||||
|
<field name="user_id" required="1"/>
|
||||||
|
<field name="period" required="1"/>
|
||||||
|
<field name="start_date" required="1" />
|
||||||
|
<field name="attachment" required="0" />
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="period_type" required="1"/>
|
||||||
|
<field name="maintenance_time" widget="float_time"/>
|
||||||
|
<field name="next_action_date" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group string="Related Tasks">
|
||||||
|
<field name="task_ids" nolabel="1">
|
||||||
|
<tree editable="bottom">
|
||||||
|
<field name="sequence" widget="handle"/>
|
||||||
|
<field name="name" />
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="hr_equipment_view_form_inherit" model="ir.ui.view">
|
||||||
|
<field name="name">maintenance.equipment.form</field>
|
||||||
|
<field name="model">maintenance.equipment</field>
|
||||||
|
<field name="inherit_id" ref="maintenance.hr_equipment_view_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//button[1]" position="after">
|
||||||
|
<button name="create_maintenance_job" type="object" class="oe_stat_button" icon="fa-wrench"
|
||||||
|
string="Create Jobs">
|
||||||
|
</button>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='location']" position="replace">
|
||||||
|
<field name="location2"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//page[3]" position="attributes">
|
||||||
|
<attribute name="invisible">1</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//page[3]" position="after">
|
||||||
|
<page string="Maintenance">
|
||||||
|
<field name="job_ids">
|
||||||
|
<tree>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="next_action_date"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="hr_equipment_stage_view_tree_inherit" model="ir.ui.view">
|
||||||
|
<field name="name">maintenance.stage.tree</field>
|
||||||
|
<field name="model">maintenance.stage</field>
|
||||||
|
<field name="inherit_id" ref="maintenance.hr_equipment_stage_view_tree"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="done" position="after">
|
||||||
|
<field name="stage_type"/>
|
||||||
|
<field name="next_stage_ids" widget="many2many_tags"/>
|
||||||
|
<field name="pre_stage_ids" widget="many2many_tags"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="hr_maintenance.maintenance_request_view_form_inherit_hr" model="ir.ui.view">
|
||||||
|
<field name="name">maintenance.form</field>
|
||||||
|
<field name="model">maintenance.request</field>
|
||||||
|
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="name" position="replace">
|
||||||
|
<field name="name" placeholder="Maintenance Request"
|
||||||
|
attrs="{'readonly':[('stage_type','=','confirm')]}"/>
|
||||||
|
</field>
|
||||||
|
<xpath expr="//header" position="inside">
|
||||||
|
<button class="oe_highlight" type="object" name="request_order_creation" string="Confirm"
|
||||||
|
attrs="{'invisible':[('stage_type' , '!=' , 'draft')]}"/>
|
||||||
|
<button class="oe_highlight" type="object" name="maintenance_order_creation" string="Maintenance Order"
|
||||||
|
attrs="{'invisible':[('stage_type' , '!=' , 'confirm')]}"/>
|
||||||
|
<button class="oe_highlight" type="object" name="order_set_to_draft" string="Set To Draft"
|
||||||
|
attrs="{'invisible':[('stage_type' , '!=' , 'cancel')]}"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//sheet" position="inside">
|
||||||
|
<notebook>
|
||||||
|
<page string="Matrials" name="purchase_request_info">
|
||||||
|
<field name="line_ids">
|
||||||
|
<tree editable="bottom">
|
||||||
|
|
||||||
|
<field name="product_id"
|
||||||
|
domain="[('purchase_ok', '=', True),('categ_id','child_of',parent.product_category_ids)]"
|
||||||
|
options="{'no_create' : True , 'no_edit' : True ,'no_open' : True}"/>
|
||||||
|
<field name="uom_id"
|
||||||
|
attrs="{'column_required':[('parent.stage_type' , '!=' , 'draft')]}"/>
|
||||||
|
<field name="qty" attrs="{'column_required':[('parent.stage_type' , '!=' , 'draft')]}"/>
|
||||||
|
<field name="price_unit"
|
||||||
|
attrs="{'column_required':[('parent.stage_type' , '!=' , 'draft')]}"/>
|
||||||
|
|
||||||
|
<field name="name"/>
|
||||||
|
<!-- <field name="product_id"-->
|
||||||
|
<!-- domain="[('purchase_ok', '=', True),('categ_id','child_of',parent.product_category_ids)]"-->
|
||||||
|
<!-- options="{'no_create' : True , 'no_edit' : True ,'no_open' : True}"/>-->
|
||||||
|
<!-- <field name="qty" attrs="{'column_required':[('parent.stage_type' , '!=' , 'draft')]}"/>-->
|
||||||
|
<!-- <field name="uom_id"-->
|
||||||
|
<!-- attrs="{'column_required':[('parent.stage_type' , '!=' , 'draft')]}"/>-->
|
||||||
|
<!-- <field name="price_unit"-->
|
||||||
|
<!-- attrs="{'column_required':[('parent.stage_type' , '!=' , 'draft')]}"/>-->
|
||||||
|
<field name="sum_total" force_save="1" sum="Total amount"/>
|
||||||
|
<field name="account_id"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
<page string="Account Assets Info" name="assets_info">
|
||||||
|
<group>
|
||||||
|
<field name="employee_id"/>
|
||||||
|
<field name="department_id"/>
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="acquisition_date"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<!-- todo end -->
|
||||||
|
<field name="description" position="replace"/>
|
||||||
|
<xpath expr="//group[1]" position="replace">
|
||||||
|
<notebook>
|
||||||
|
<page string="Request">
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="code" readonly="True"/>
|
||||||
|
<field name="employee_id" string="Requester"
|
||||||
|
options="{'no_create_edit': True, 'no_open': True}"
|
||||||
|
attrs="{'readonly':[('stage_type','=','confirm')]}"/>
|
||||||
|
<field name="equipment_id" string="Machine" options="{'no_create': True}"
|
||||||
|
context="{'default_company_id':company_id, 'default_category_id':category_id}"
|
||||||
|
attrs="{'readonly':[('stage_type','=','confirm')]}"/>
|
||||||
|
<field name="category_id" options="{'no_create': True}"
|
||||||
|
groups="maintenance.group_equipment_manager"
|
||||||
|
context="{'default_company_id':company_id}" invisible="1"/>
|
||||||
|
<field name="done" invisible="1"/>
|
||||||
|
<field name="close_date" invisible="1" attrs="{'invisible': [('done', '!=', True)]}"
|
||||||
|
readonly="True"/>
|
||||||
|
<field name="archive" invisible="1"/>
|
||||||
|
<field name="maintenance_type" widget="radio" invisible="1"/>
|
||||||
|
<field name="done_time"
|
||||||
|
attrs="{'invisible':[('stage_type','not in', ['request_done' , 'repair_done'])], 'required' : [('stage_type','in', ['request_done' , 'repair_done'])],'readonly':[('stage_type','=','confirm')]}"/>
|
||||||
|
<field name="down_time" widget="float_time"
|
||||||
|
attrs="{'invisible':['|','|' ,('machine_status','!=','out_service'),('stage_type','not in', ['request_done' , 'repair_done']),('maintenance_type','!=', 'corrective')],'readonly':[('stage_type','=','confirm')]}"
|
||||||
|
class="oe_inline"/>
|
||||||
|
<field name="product_loss"
|
||||||
|
attrs="{'invisible':['|','|' ,('machine_status','!=','part'),('stage_type','not in', ['request_done' , 'repair_done']),('maintenance_type','!=', 'corrective')],'readonly':[('stage_type','=','confirm')]}"
|
||||||
|
class="oe_inline"/>
|
||||||
|
<field name="dis_priority" widget="radio"/>
|
||||||
|
<field name="vendor_id"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="request_date" readonly="True"/>
|
||||||
|
<field name="department_id" attrs="{'readonly':[('stage_type','=','confirm')]}"
|
||||||
|
options="{'no_create': True}"/>
|
||||||
|
<field name="maintenance_team_id"/>
|
||||||
|
<field name="machine_status" invisible="0"
|
||||||
|
attrs="{'readonly':[('stage_type','=','confirm')]}"/>
|
||||||
|
<field name="failure_id"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('stage_type', '=' , 'order')],'invisible':[('stage_type','not in',['for_order', 'request_done' , 'repair_done'])],'required':[('stage_type','in',['for_order' , 'request_done' , 'repair_done'])]}"/>
|
||||||
|
<field name="user_id" options="{'no_create': True}" string="Supervisor"
|
||||||
|
attrs="{'invisible':[('stage_type','not in',['for_order', 'request_done' , 'repair_done'])],'required':[('stage_type','in',['for_order' , 'request_done' , 'repair_done'])],'readonly':[('stage_type','=','confirm')]}"/>
|
||||||
|
<field name="schedule_date"
|
||||||
|
attrs="{'invisible':[('stage_type','not in',['for_order','repair_done','request_done'])],'readonly':[('stage_type','=','confirm')]}"/>
|
||||||
|
<field name="stage_type" invisible="1"/>
|
||||||
|
<label for="duration"
|
||||||
|
attrs="{'invisible':[('stage_type','not in',['for_order','repair_done','request_done'])],'readonly':[('stage_type','=','confirm')]}"/>
|
||||||
|
<div attrs="{'invisible':[('stage_type','not in',['for_order','repair_done','request_done'])],'readonly':[('stage_type','=','confirm')]}">
|
||||||
|
<field name="duration" widget="float_time" class="oe_inline"/>
|
||||||
|
<span class="ml8">hours</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<field name="email_cc" string="Email cc" groups="base.group_no_one" invisible="1"/>
|
||||||
|
<field name="company_id" attrs="{'readonly':['|',('stage_type','=','confirm')]}"
|
||||||
|
options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group string="Description">
|
||||||
|
<field name="description" attrs="{'readonly':[('stage_type','=','confirm')]}" nolabel="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</xpath>
|
||||||
|
<!-- todo start -->
|
||||||
|
<xpath expr="//field[@name='employee_id']" position="after">
|
||||||
|
<field name="partner_id"/>
|
||||||
|
<field name="product_category_ids" required="1" widget="many2many_tags"/>
|
||||||
|
</xpath>
|
||||||
|
<!-- todo end-->
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<!-- Inherit Form View to Modify it -->
|
||||||
|
<record id="hr_equipment_request_view_form_custom" model="ir.ui.view">
|
||||||
|
<field name="name">hr.equipment.request.view.form.custom</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='stage_id']" position="attributes">
|
||||||
|
<attribute name="options">{'no_edit': True}</attribute>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- maintenance order form-->
|
||||||
|
<record id="hr_equipment_order_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">equipment.order.form</field>
|
||||||
|
<field name="model">maintenance.request</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Maintenance Order">
|
||||||
|
<header>
|
||||||
|
<field name="stage_id" widget="statusbar"/>
|
||||||
|
<field name="purchase_order_id" invisible="1"/>
|
||||||
|
<button class="oe_highlight" type="object" name="maintenance_order_done" string="Done"
|
||||||
|
attrs="{'invisible':[('stage_type' , '!=' , 'for_order')]}"/>
|
||||||
|
<button string="Reopen Request" name="reset_equipment_request" type="object"
|
||||||
|
attrs="{'invisible': [('archive', '=', False)]}"/>
|
||||||
|
<button name="create_purchase_request" type="object" string="Create Purchase Request"
|
||||||
|
class="oe_highlight" attrs="{'invisible':['|',('stage_type' , '!=' , 'for_order'),('purchase_order_id' , '!=' , False)]}"/>
|
||||||
|
<button name="archive_equipment_request" type="object" string="Cancel"
|
||||||
|
class="oe_highlight" attrs="{'invisible':[('stage_type' , '!=' , 'for_order')]}"/>
|
||||||
|
</header>
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_button_box">
|
||||||
|
<button width='200' class="oe_stat_button" type="object"
|
||||||
|
name="to_open_maintenance_purchase_order"
|
||||||
|
icon="fa-file" attrs="{'invisible':[('stage_type' , '!=' , 'for_order')]}">
|
||||||
|
<field string="Purchase Request" name="purchase_order_count" widget="statinfo"
|
||||||
|
attrs="{'invisible':[('stage_type' , '!=' , 'for_order')]}"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div attrs="{'invisible': [('archive', '=', False)]}">
|
||||||
|
<span class="badge badge-warning float-right">Canceled</span>
|
||||||
|
</div>
|
||||||
|
<div class="oe_right">
|
||||||
|
<field name="kanban_state" class="oe_inline" widget="state_selection"/>
|
||||||
|
</div>
|
||||||
|
<div class="oe_title">
|
||||||
|
<label for="name" class="oe_edit_only" string="Title" readonly="True"/>
|
||||||
|
<h1>
|
||||||
|
<field name="name" attrs="{'readonly':[('stage_type','=','confirm')]}"
|
||||||
|
placeholder="Maintenance Request"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<notebook>
|
||||||
|
<page string="Matrials" name="purchase_request_info">
|
||||||
|
<field name="line_ids">
|
||||||
|
<tree editable="bottom">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="product_id"/>
|
||||||
|
<field name="qty"
|
||||||
|
attrs="{'column_required':[('parent.stage_type' , '!=' , 'draft')]}"/>
|
||||||
|
<field name="uom_id"/>
|
||||||
|
<field name="price_unit"
|
||||||
|
attrs="{'column_required':[('parent.stage_type' , '!=' , 'draft')]}"/>
|
||||||
|
<field name="sum_total" force_save="1" sum="Total amount"/>
|
||||||
|
<field name="account_id"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
<page string="Request Details">
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="code" readonly="True"/>
|
||||||
|
<field name="partner_id" />
|
||||||
|
<field name="employee_id" string="Requester"
|
||||||
|
options="{'no_create_edit': True, 'no_open': True}"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="equipment_id" string="Machine"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"
|
||||||
|
context="{'default_company_id':company_id, 'default_category_id':category_id}"/>
|
||||||
|
<field name="purchase_order_id" readonly="1" attrs="{'invisible':[('purchase_order_id','=',False)]}"/>
|
||||||
|
<field name="category_id"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"
|
||||||
|
groups="maintenance.group_equipment_manager"
|
||||||
|
context="{'default_company_id':company_id}" invisible="1"/>
|
||||||
|
<field name="done" invisible="1"/>
|
||||||
|
<field name="close_date" invisible="1" attrs="{'invisible': [('done', '!=', True)]}"
|
||||||
|
readonly="True"/>
|
||||||
|
<field name="archive" invisible="1"/>
|
||||||
|
<field name="entry_source" invisible="1"/>
|
||||||
|
<field name="done_time"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')],'invisible':[('stage_type','not in', ['request_done' , 'repair_done'])]}"/>
|
||||||
|
<field name="down_time" widget="float_time" attrs="{
|
||||||
|
'readonly' : ['|',('stage_type','=','confirm'),('entry_source' , '!=' , 'order')],
|
||||||
|
'invisible':['|','|' ,('machine_status','!=','out_service'),('stage_type','not in', ['request_done' , 'repair_done']),('maintenance_type','!=', 'corrective')]}"
|
||||||
|
class="oe_inline"/>
|
||||||
|
<field name="product_loss" attrs="{
|
||||||
|
'readonly' : ['|',('stage_type','=','confirm'),('entry_source' , '!=' , 'order')],
|
||||||
|
'invisible':['|','|' ,('machine_status','!=','part'),('stage_type','not in', ['request_done' , 'repair_done']),('maintenance_type','!=', 'corrective')]}"
|
||||||
|
class="oe_inline"/>
|
||||||
|
<field name="dis_priority"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"
|
||||||
|
widget="radio"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="request_date" readonly="1"/>
|
||||||
|
<field name="department_id"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="machine_status" invisible="0"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="maintenance_type" widget="radio" invisible="0"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="maintenance_category"
|
||||||
|
attrs="{ 'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<!-- 'invisible':[('entry_source','!=', 'order')],-->
|
||||||
|
<field name="failure_id"
|
||||||
|
attrs="{'invisible':[('maintenance_type','!=', 'corrective')]}"/>
|
||||||
|
<field name="user_id" string="Supervisor" options="{'no_create': True}"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="employee_ids" invisible="1" options="{'no_create': True}"
|
||||||
|
widget="many2many_tags"/>
|
||||||
|
<field name="schedule_date" invisible="0"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="stage_type" invisible="1"/>
|
||||||
|
<label for="duration" invisible="0"/>
|
||||||
|
<div invisible="0">
|
||||||
|
<field name="duration"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"
|
||||||
|
widget="float_time" class="oe_inline"/>
|
||||||
|
<span class="ml8">hours</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<field name="email_cc" string="Email cc" groups="base.group_no_one" invisible="1"/>
|
||||||
|
<field name="company_id" options="{'no_create': True}"
|
||||||
|
groups="base.group_multi_company" readonly="True"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group string="Description">
|
||||||
|
<field name="description" nolabel="1"
|
||||||
|
attrs="{'readonly':[('entry_source', '!=' , 'order')]}"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="Checklist" name="checklist_info">
|
||||||
|
<field name="checklist_lines">
|
||||||
|
<tree string="Checklist For Inspection" editable="bottom">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="description"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
<page string="Supervisor">
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="user_id" string="Supervisor" options="{'no_create': True}"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="maintenance_team_id"
|
||||||
|
attrs="{'invisible':[('maintenance_type','!=', 'corrective')],'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"
|
||||||
|
options="{'no_create': True}" invisible="1"/>
|
||||||
|
<field name="team_type"
|
||||||
|
attrs="{'invisible':[('maintenance_type','!=', 'corrective')],'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="start_time"
|
||||||
|
attrs="{'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="failure_id"
|
||||||
|
attrs="{'invisible':[('maintenance_type','!=', 'corrective')],'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="out_entity_id" options="{'no_create': True}"
|
||||||
|
attrs="{'invisible' : [('team_type' , '!=' , 'out')],'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="dis_employee_ids" options="{'no_create': True}" widget="many2many_tags"
|
||||||
|
attrs="{'invisible' : [('team_type' , '!=' , 'in')],'readonly':['|',('stage_type','=','confirm'),('entry_source', '!=' , 'order')]}"/>
|
||||||
|
<field name="employee_ids" invisible="1" options="{'no_create': True}"
|
||||||
|
widget="many2many_tags"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group string="Failure Description"
|
||||||
|
attrs="{'invisible':[('maintenance_type','!=', 'corrective')]}">
|
||||||
|
<field name="failure_desc" nolabel="1"/>
|
||||||
|
</group>
|
||||||
|
<group string="Failure root cause"
|
||||||
|
attrs="{'invisible':[('maintenance_type','!=', 'corrective')]}">
|
||||||
|
<field name="failure_cause_id" nolabel="1"/>
|
||||||
|
</group>
|
||||||
|
<group string="Maintenance Work"
|
||||||
|
attrs="{'invisible':[('maintenance_type','!=', 'corrective')]}">
|
||||||
|
<field name="maintenance_work" nolabel="1"/>
|
||||||
|
</group>
|
||||||
|
<group attrs="{'invisible':[('maintenance_type','!=', 'preventive')]}">
|
||||||
|
<field name="attachment" required="0" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<group string="Tasks" attrs="{'invisible':[('maintenance_type','!=', 'preventive')]}">
|
||||||
|
<field name="task_ids" nolabel="1">
|
||||||
|
<tree editable="bottom">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="employee_id" required="1"/>
|
||||||
|
<field name="time" widget="float_time"/>
|
||||||
|
<field name="duration" widget="float_time"/>
|
||||||
|
<field name="is_done"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</group>
|
||||||
|
<group string="Tools">
|
||||||
|
<field name="tool_ids" nolabel="1" widget="many2many_tags"/>
|
||||||
|
</group>
|
||||||
|
<!-- <group string="Spares">-->
|
||||||
|
<!-- <field name="spare_ids" nolabel="1">-->
|
||||||
|
<!-- <tree editable="bottom">-->
|
||||||
|
<!-- <field name="spare_id"/>-->
|
||||||
|
<!-- <field name="quantity"/>-->
|
||||||
|
<!-- <field name="cost"/>-->
|
||||||
|
<!-- <field name="total"/>-->
|
||||||
|
<!-- </tree>-->
|
||||||
|
<!-- </field>-->
|
||||||
|
<!-- </group>-->
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
<div class="oe_chatter">
|
||||||
|
<field name="message_follower_ids" widget="mail_followers"/>
|
||||||
|
<field name="activity_ids" widget="mail_activity"/>
|
||||||
|
<field name="message_ids" widget="mail_thread"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="maintenance_failure_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">maintenance.failure.form</field>
|
||||||
|
<field name="model">maintenance.failure</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Fiulre Types">
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<field name="name"/>
|
||||||
|
</group>
|
||||||
|
<group string='Related Engineers'>
|
||||||
|
<field name="user_ids" nolabel="1"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="maintenance_summary_kanban" model="ir.ui.view">
|
||||||
|
<field name="name">Maintenance Summary</field>
|
||||||
|
<field name="model">maintenance.summary</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<kanban class="oe_background_grey o_kanban_dashboard o_maintenance_summary" create="0">
|
||||||
|
<templates>
|
||||||
|
<t t-name="kanban-box">
|
||||||
|
<div class="panel med">
|
||||||
|
<field name="order_chart" widget="pichart" keys="total_open;total_repair;total_close"
|
||||||
|
labels="Open;Repaired;Closed"
|
||||||
|
backgroundColors="rgba(255, 99, 132, 0.2);rgba(54, 162, 235, 0.2);rgba(255, 206, 86, 0.2)"
|
||||||
|
borderColors="rgba(255, 99, 132, 1);rgba(54, 162, 235, 1);rgba(255, 206, 86, 1)"/>
|
||||||
|
</div>
|
||||||
|
<div class="panel med">
|
||||||
|
<field name="priority_chart" widget="pichart" keys="total_low;total_normal;total_high"
|
||||||
|
labels="Low;Normal;High" backgroundColors="#80ff00;#e0ff33;red"
|
||||||
|
borderColors="#80ff00;#e0ff33;red"/>
|
||||||
|
</div>
|
||||||
|
<div class="panel med">
|
||||||
|
<field name="planned_chart" widget="pichart" keys="total_planned;total_unplanned"
|
||||||
|
labels="Planned;Un Planned" backgroundColors="#87CEFA;#F0F8FF"
|
||||||
|
borderColors="#F0F8FF;#F0F8FF" cutoutPercentage="85"/>
|
||||||
|
</div>
|
||||||
|
<div class="panel med">
|
||||||
|
<div class="boxes">
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title">Partially effect</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<field name="total_partially_effect"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title">losses of production</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<field name="total_loss"/>
|
||||||
|
units
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="boxes">
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title">Out of Service</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<field name="total_outservice"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box zooba">
|
||||||
|
<div class="box-title">Downtime</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<field name="total_downtime"/>
|
||||||
|
Hour(s)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</templates>
|
||||||
|
</kanban>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- Form view for "model" -->
|
||||||
|
<record id="purchase_order_custom_form_view" model="ir.ui.view">
|
||||||
|
<field name="name">view.purchase.order.form</field>
|
||||||
|
<field name="model">purchase.order</field>
|
||||||
|
<field name="inherit_id" ref="purchase_requisition_custom.purchase_order_custom_form_view" />
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='request_id']" position="after">
|
||||||
|
<field name="maintenance_id" readonly="1"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="maintenance_failure_view_tree" model="ir.ui.view">
|
||||||
|
<field name="name">maintenance.failure.tree</field>
|
||||||
|
<field name="model">maintenance.failure</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="Fiulre Types">
|
||||||
|
<field name="name"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="maintenance_failure_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">Failure Types</field>
|
||||||
|
<field name="res_model">maintenance.failure</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="maintenance_equipments_group_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">Maintenance Equipments</field>
|
||||||
|
<field name="res_model">maintenance.equipments.jobs</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="hr_equipment_order_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">Maintenance Orders</field>
|
||||||
|
<field name="res_model">maintenance.request</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="context">{'default_user_id': uid, 'default_entry_source' : 'order'}</field>
|
||||||
|
<field name="domain">['|',('stage_id.stage_type','=','for_order'),('entry_source','=','order')]</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="o_view_nocontent_smiling_face">
|
||||||
|
Add a new maintenance request
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Follow the process of the request and communicate with the collaborator.
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="maintenance.hr_equipment_request_action" model="ir.actions.act_window">
|
||||||
|
<field name="domain">['|',('maintenance_type','=','corrective'),('entry_source','=',
|
||||||
|
'request'),('stage_id.stage_type','!=','for_order')]
|
||||||
|
</field>
|
||||||
|
<field name="context">{'default_user_id': uid , 'default_maintenance_category':'unplanned'}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_order_tree" model="ir.actions.act_window.view">
|
||||||
|
<field eval="1" name="sequence"/>
|
||||||
|
<field name="view_mode">tree</field>
|
||||||
|
<field name="act_window_id" ref="hr_equipment_order_action"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_request_tree" model="ir.actions.act_window.view">
|
||||||
|
<field eval="1" name="sequence"/>
|
||||||
|
<field name="view_mode">tree</field>
|
||||||
|
<field name="act_window_id" ref="maintenance.hr_equipment_request_action"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="action_order_form" model="ir.actions.act_window.view">
|
||||||
|
<field eval="2" name="sequence"/>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="hr_equipment_order_view_form"/>
|
||||||
|
<field name="act_window_id" ref="hr_equipment_order_action"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_request_form" model="ir.actions.act_window.view">
|
||||||
|
<field eval="2" name="sequence"/>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="maintenance.hr_equipment_request_view_form"/>
|
||||||
|
<field name="act_window_id" ref="maintenance.hr_equipment_request_action"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="maintenance_summary_dashboard_action" model="ir.actions.act_window">
|
||||||
|
<field name="name">Maintenance Summary</field>
|
||||||
|
<field name="res_model">maintenance.summary</field>
|
||||||
|
<field name="view_id" ref="maintenance_summary_kanban"/>
|
||||||
|
<field name="view_mode">kanban</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="o_view_nocontent_smiling_face">
|
||||||
|
Add a new record in the Equipment Category
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="menu_m_request_form" name="Maintenance Orders" parent="maintenance.menu_m_request"
|
||||||
|
action="hr_equipment_order_action" groups="maintenance.group_equipment_manager,base.group_user"
|
||||||
|
sequence="1"/>
|
||||||
|
<menuitem id="menu_m_group_form" name="Maintenance Equipments Group" parent="maintenance.menu_m_request"
|
||||||
|
action="maintenance_equipments_group_action" sequence="5"/>
|
||||||
|
|
||||||
|
<menuitem action="sale.product_template_action" id="menu_product_template_action"
|
||||||
|
parent="maintenance.menu_maintenance_configuration" sequence="1"/>
|
||||||
|
|
||||||
|
<menuitem action="maintenance_failure_action" id="menu_failure_types" name="Failure Types"
|
||||||
|
parent="maintenance.menu_maintenance_configuration" sequence="1"/>
|
||||||
|
|
||||||
|
<menuitem id="maintenance_summary_dashboard_menu" name="Maintenance Summary"
|
||||||
|
parent="maintenance.maintenance_reporting" groups="maintenance.group_equipment_manager,base.group_user"
|
||||||
|
action="maintenance_summary_dashboard_action"/>
|
||||||
|
<menuitem id="equipments_locations_menu" name="Equipments Locations"
|
||||||
|
parent="maintenance.menu_maintenance_configuration"
|
||||||
|
action="equipments_locations_action"/>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Customize menu security -->
|
||||||
|
<odoo>
|
||||||
|
<record model="ir.ui.menu" id="maintenance.menu_maintenance_title">
|
||||||
|
<field name="groups_id" eval="[(6,0,[ref('maintenance.group_equipment_manager')])]"/>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
from . import maintenance_report_wiz
|
||||||
|
|
@ -0,0 +1,285 @@
|
||||||
|
from datetime import datetime
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
def to_str(array):
|
||||||
|
return ",".join(str(i) for i in array)
|
||||||
|
|
||||||
|
|
||||||
|
class MaintenanceReportWiz(models.TransientModel):
|
||||||
|
_name = 'maintenance.report.wiz'
|
||||||
|
|
||||||
|
time_from = fields.Datetime('From', required=True)
|
||||||
|
time_to = fields.Datetime('To', required=True)
|
||||||
|
equipment_ids = fields.Many2many('maintenance.equipment', 'equipment_report_wiz_rel' , string='Equipment')
|
||||||
|
category_ids = fields.Many2many('maintenance.equipment.category', 'equipment_cat_report_wiz_rel', string='Equipment Category' )
|
||||||
|
spare_categ_ids = fields.Many2many('product.category', 'spare_cat_report_wiz_rel', string='Spare Category' )
|
||||||
|
failure_ids = fields.Many2many('maintenance.failure', 'failure_report_wiz_rel' , string='Failure Type')
|
||||||
|
user_ids = fields.Many2many('res.users', 'users_report_wiz_rel' , string='Supervisor')
|
||||||
|
department_ids = fields.Many2many('hr.department', 'dep_report_wiz_rel' , string='Department')
|
||||||
|
employee_ids = fields.Many2many('hr.employee', 'emp_report_wiz_rel' , string='Members')
|
||||||
|
team_type = fields.Selection([('in', 'Internal Team'), ('out', 'Outsite Entity')], string='Team Type')
|
||||||
|
spare_ids = fields.Many2many('product.template', 'spare_report_wiz_rel' , string='Spare Parts', domain=[('is_spare','=',True)])
|
||||||
|
machine_status = fields.Selection([('out_service', 'Out of Service'),('part','Partially effect'),('in_service','In Service')], string='Machine Status')
|
||||||
|
report_type = fields.Selection([
|
||||||
|
('general', 'General Report'),
|
||||||
|
('spare','Spare Parts'),
|
||||||
|
('equipment', 'Equipment'),
|
||||||
|
('team','Team Members')], string='Report Type')
|
||||||
|
|
||||||
|
def _filters(self):
|
||||||
|
cond = []
|
||||||
|
filters = {}
|
||||||
|
if self.time_from :
|
||||||
|
cond.append(['request_date', '>=' , self.time_from])
|
||||||
|
if self.time_to :
|
||||||
|
cond.append(['request_date', '<=' , self.time_to])
|
||||||
|
if self.equipment_ids :
|
||||||
|
cond.append(['equipment_id', 'in' , self.equipment_ids.ids])
|
||||||
|
stri = ",".join(i.name for i in self.equipment_ids)
|
||||||
|
filters.update({'equipment_id' :stri})
|
||||||
|
if self.category_ids:
|
||||||
|
equipment_ids = self.env.get('maintenance.equipment').search([('category_id', 'in',self.category_ids.ids )])
|
||||||
|
cond.append(['equipment_id', 'in' , equipment_ids.ids])
|
||||||
|
stri = ",".join(i.name for i in self.category_ids)
|
||||||
|
filters.update({'category_id' :stri})
|
||||||
|
if self.user_ids :
|
||||||
|
cond.append(['user_id', 'in' , self.user_ids.ids])
|
||||||
|
stri = ",".join(i.name for i in self.user_ids)
|
||||||
|
filters.update({'user_id' :stri})
|
||||||
|
if self.failure_ids :
|
||||||
|
cond.append(['failure_id', 'in' , self.failure_ids.ids])
|
||||||
|
stri = " , ".join(i.name for i in self.failure_ids)
|
||||||
|
filters.update({'failure_id' :stri})
|
||||||
|
if self.team_type :
|
||||||
|
cond.append(['team_type', '=' , self.team_type])
|
||||||
|
stri = self.team_type == 'in' and 'Internal Team' or 'Outsite Entity'
|
||||||
|
filters.update({'team_type' :stri})
|
||||||
|
if self.machine_status :
|
||||||
|
cond.append(['machine_status', '=' , self.machine_status])
|
||||||
|
stri = self.team_type
|
||||||
|
filters.update({'machine_status' :stri})
|
||||||
|
if self.spare_ids or self.report_type == 'spare' :
|
||||||
|
ids = self.spare_ids and self.spare_ids.ids or self.env.get('product.template').search([('is_spare', '=', True)]).ids
|
||||||
|
spare_ids = self.env.get('maintenance.request.spare').search([('spare_id', 'in',ids )])
|
||||||
|
order_ids = [s.request_id.id for s in spare_ids]
|
||||||
|
cond.append(['id', 'in' , order_ids])
|
||||||
|
stri = " , ".join(i.name for i in self.spare_ids)
|
||||||
|
filters.update({'spare_id' :stri})
|
||||||
|
if self.department_ids or self.employee_ids or self.report_type == 'team' :
|
||||||
|
emp_cond = []
|
||||||
|
if self.department_ids :
|
||||||
|
emp_cond += [('department_id', 'in', self.department_ids.ids)]
|
||||||
|
dep_stri = " , ".join(i.name for i in self.department_ids)
|
||||||
|
filters.update({'department_id' :dep_stri})
|
||||||
|
emp_ids = self.employee_ids.ids and self.employee_ids.ids or self.env.get('hr.employee').search(emp_cond).ids
|
||||||
|
emp_ids_str = " , ".join(str(i) for i in emp_ids)
|
||||||
|
query = '''
|
||||||
|
select maintenance_request_id from req_member_rel where hr_employee_id in (%s)
|
||||||
|
'''%(emp_ids_str)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
res = self.env.cr.fetchall()
|
||||||
|
order_ids = [r[0] for r in res]
|
||||||
|
cond.append(['id', 'in' , order_ids])
|
||||||
|
stri = " , ".join(i.name for i in self.env['hr.employee'].browse(emp_ids))
|
||||||
|
filters.update({'employee_id' :stri})
|
||||||
|
if self.spare_categ_ids:
|
||||||
|
product_ids = self.env.get('product.template').search([('categ_id', 'in',self.spare_categ_ids.ids ),('is_spare', '=', True)])
|
||||||
|
spare_ids = self.env.get('maintenance.request.spare').search([('spare_id', 'in',product_ids.ids )])
|
||||||
|
order_ids = [s.request_id.id for s in spare_ids]
|
||||||
|
cond.append(['id', 'in' , order_ids])
|
||||||
|
stri = " , ".join(i.name for i in self.spare_categ_ids)
|
||||||
|
filters.update({'spare_categ_id' :stri})
|
||||||
|
return cond , filters
|
||||||
|
|
||||||
|
def print_report(self):
|
||||||
|
cond , filters = self._filters()
|
||||||
|
requests = self.env.get('maintenance.request').search(cond)
|
||||||
|
if not requests :
|
||||||
|
raise ValidationError(_('Connot Find any Request/Order .'))
|
||||||
|
time_from = self.time_from
|
||||||
|
time_to = self.time_to
|
||||||
|
totals = self.compute_general_report(requests)
|
||||||
|
data = {
|
||||||
|
'form' : {
|
||||||
|
'time_from' : time_from,
|
||||||
|
'time_to' : time_to,
|
||||||
|
'total' : totals,
|
||||||
|
'filters' : filters,
|
||||||
|
'rec_ids' : requests.ids + [0],
|
||||||
|
'spare_categ_ids' : self.spare_categ_ids.ids,
|
||||||
|
'spare_ids' : self.spare_ids.ids,
|
||||||
|
'category_ids' : self.category_ids.ids,
|
||||||
|
'equipment_ids' : self.equipment_ids.ids,
|
||||||
|
'employee_ids' : self.employee_ids.ids,
|
||||||
|
'department_ids' : self.department_ids.ids,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if self.report_type == 'general':
|
||||||
|
report = self.env.ref('maintenance_custom.action_general_maintenance_report').report_action(requests,data=data)
|
||||||
|
elif self.report_type == 'spare':
|
||||||
|
report = self.env.ref('maintenance_custom.action_spare_part_report').report_action(requests,data=data)
|
||||||
|
if self.report_type == 'equipment':
|
||||||
|
report = self.env.ref('maintenance_custom.action_equipment_report').report_action(requests,data=data)
|
||||||
|
if self.report_type == 'team':
|
||||||
|
report = self.env.ref('maintenance_custom.action_maintenance_team_report').report_action(requests,data=data)
|
||||||
|
return report
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_members(self, order_str):
|
||||||
|
query = '''
|
||||||
|
SELECT
|
||||||
|
count(distinct hr_employee_id )
|
||||||
|
FROM req_member_rel WHERE maintenance_request_id IN (%s)
|
||||||
|
|
||||||
|
'''%(order_str)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
try :
|
||||||
|
total = self.env.cr.fetchall()[0][0]
|
||||||
|
except :
|
||||||
|
total = 0
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_equipment(self, order_str):
|
||||||
|
query = '''
|
||||||
|
SELECT count(distinct equipment_id)
|
||||||
|
FROM maintenance_request WHERE id IN (%s)
|
||||||
|
'''%(order_str)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
try :
|
||||||
|
total = self.env.cr.fetchall()[0][0]
|
||||||
|
except :
|
||||||
|
total = 0
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_cost(self, order_str):
|
||||||
|
query = '''
|
||||||
|
SELECT sum(quantity * cost) FROM maintenance_request_spare WHERE request_id IN (%s)
|
||||||
|
'''%(order_str)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
try :
|
||||||
|
total = self.env.cr.fetchall()[0][0]
|
||||||
|
except :
|
||||||
|
total = 0
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_downtime(self, order_str):
|
||||||
|
query = '''
|
||||||
|
SELECT sum(down_time)
|
||||||
|
FROM maintenance_request WHERE id IN (%s) and machine_status = 'out_service'
|
||||||
|
'''%(order_str)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
try :
|
||||||
|
total = self.env.cr.fetchall()[0][0]
|
||||||
|
except :
|
||||||
|
total = 0
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_loss(self, order_str):
|
||||||
|
query = '''
|
||||||
|
SELECT sum(product_loss)
|
||||||
|
FROM maintenance_request WHERE id IN (%s) and machine_status = 'part'
|
||||||
|
'''%(order_str)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
try :
|
||||||
|
total = self.env.cr.fetchall()[0][0]
|
||||||
|
except :
|
||||||
|
total = 0
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_over_due(self, order_str):
|
||||||
|
query = '''
|
||||||
|
SELECT count(id) FROM maintenance_request
|
||||||
|
WHERE duration > 0 AND done_time >= schedule_date + interval '1' HOUR * duration
|
||||||
|
AND id in (%s) and stage_id in (select id from maintenance_stage where stage_type = 'request_done' )
|
||||||
|
'''%(order_str)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
try :
|
||||||
|
total = self.env.cr.fetchall()[0][0]
|
||||||
|
except :
|
||||||
|
total = 0
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_planned(self, order_ids):
|
||||||
|
count = self.env.get('maintenance.request').search_count([
|
||||||
|
('id', 'in', order_ids),
|
||||||
|
('maintenance_category','=', 'planned')
|
||||||
|
])
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
def _get_high_priority(self, order_ids):
|
||||||
|
count = self.env.get('maintenance.request').search_count([
|
||||||
|
('id', 'in', order_ids),
|
||||||
|
('priority','=', '3')
|
||||||
|
])
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_closed(self, order_ids):
|
||||||
|
res = self.env.get('maintenance.stage').search([('stage_type', '=', 'request_done')])
|
||||||
|
stage_done = res.ids
|
||||||
|
count = self.env.get('maintenance.request').search_count([
|
||||||
|
('id', 'in', order_ids),
|
||||||
|
('stage_id','in', stage_done),
|
||||||
|
])
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total_open(self,order_ids):
|
||||||
|
res = self.env.get('maintenance.stage').search([('stage_type', '!=', 'request_done')])
|
||||||
|
stage_open = res.ids
|
||||||
|
count = self.env.get('maintenance.request').search_count([
|
||||||
|
('id', 'in', order_ids),
|
||||||
|
('stage_id','in', stage_open),
|
||||||
|
])
|
||||||
|
return count
|
||||||
|
|
||||||
|
def _get_total_working_hours(self,order_str):
|
||||||
|
res = self.env.get('maintenance.stage').search([('done', '=', True)])
|
||||||
|
stage_done = res.ids
|
||||||
|
query = '''
|
||||||
|
SELECT sum(EXTRACT(EPOCH FROM done_time-start_time)/3600) FROM maintenance_request
|
||||||
|
WHERE Stage_id in (%s) and id in (%s)
|
||||||
|
'''%(to_str(stage_done), order_str)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
try :
|
||||||
|
total = self.env.cr.fetchall()[0][0]
|
||||||
|
total = round(total,2)
|
||||||
|
except :
|
||||||
|
total = 0
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def compute_general_report(self, orders):
|
||||||
|
order_ids = orders.ids
|
||||||
|
order_str = ",".join(str(i) for i in order_ids)
|
||||||
|
total_orders = len(order_ids)
|
||||||
|
planned = round((self._get_total_planned(order_ids) / float(total_orders) * 100 ), 2)
|
||||||
|
overdue = self._get_total_over_due(order_str)
|
||||||
|
over_due_percentage = overdue / total_orders * 100
|
||||||
|
over_due_percentage = round(over_due_percentage, 2)
|
||||||
|
res = {
|
||||||
|
'total_equipment' : self._get_total_equipment(order_str),
|
||||||
|
'total_members' : self._get_total_members(order_str),
|
||||||
|
'total_orders' : total_orders ,
|
||||||
|
'total_over_due' : overdue,
|
||||||
|
'over_due_percentage' : over_due_percentage ,
|
||||||
|
'total_planned' : planned,
|
||||||
|
'total_high' : self._get_high_priority(order_ids),
|
||||||
|
'total_loss' : self._get_total_loss(order_str),
|
||||||
|
'total_downtime' : self._get_total_downtime(order_str),
|
||||||
|
'total_colse' : self._get_total_closed(order_ids),
|
||||||
|
'total_open' : self._get_total_open(order_ids),
|
||||||
|
'total_working_hours' : self._get_total_working_hours(order_str),
|
||||||
|
'total_cost' : self._get_total_cost(order_str),
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="maintenance_report_wiz_view" model="ir.ui.view">
|
||||||
|
<field name="name">maintenance.report.wiz.form</field>
|
||||||
|
<field name="model">maintenance.report.wiz</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Maintenance Reports">
|
||||||
|
<group>
|
||||||
|
|
||||||
|
<group>
|
||||||
|
|
||||||
|
<field name="time_from" />
|
||||||
|
<field name="category_ids" widget="many2many_tags" attrs="{'invisible':[('report_type','not in', ['general'])]}"/>
|
||||||
|
<field name="spare_categ_ids" widget="many2many_tags" attrs="{'invisible':[('report_type','not in', ['spare'])]}" />
|
||||||
|
<field name="failure_ids" widget="many2many_tags" attrs="{'invisible':[('report_type','not in', ['general'])]}" />
|
||||||
|
<field name="user_ids" widget="many2many_tags" attrs="{'invisible':[('report_type','not in', ['general'])]}" />
|
||||||
|
<field name="spare_ids" widget="many2many_tags" attrs="{'invisible':[('report_type', 'in', ['team'])]}"/>
|
||||||
|
<field name="department_ids" widget="many2many_tags" attrs="{'invisible':[('report_type','not in', ['team'])]}" />
|
||||||
|
<field name="machine_status" attrs="{'invisible':[('report_type','not in', ['general' ,'equipment'])]}" />
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="time_to" />
|
||||||
|
<field name="employee_ids" widget="many2many_tags" attrs="{'invisible':[('report_type','not in', ['general', 'team'])]}" />
|
||||||
|
<field name="equipment_ids" widget="many2many_tags" attrs="{'invisible':[('report_type','in', ['team'])]}"/>
|
||||||
|
<field name="team_type" attrs="{'invisible':[('report_type','not in', ['general'])]}" />
|
||||||
|
<field name="report_type" invisible="1" />
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button name="print_report" type="object" string="Print" />
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_maintenance_report_wiz" model="ir.actions.act_window">
|
||||||
|
<field name="name">General Maintenance Reports</field>
|
||||||
|
<field name="res_model">maintenance.report.wiz</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
<field name="context">{'default_report_type' : 'general'}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_spare_report_wiz" model="ir.actions.act_window">
|
||||||
|
<field name="name">Spare Parts Reports</field>
|
||||||
|
<field name="res_model">maintenance.report.wiz</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
<field name="context">{'default_report_type' : 'spare'}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="action_equipment_report_wiz" model="ir.actions.act_window">
|
||||||
|
<field name="name">Equipment Reports</field>
|
||||||
|
<field name="res_model">maintenance.report.wiz</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
<field name="context">{'default_report_type' : 'equipment'}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_team_report_wiz" model="ir.actions.act_window">
|
||||||
|
<field name="name">Teams Reports</field>
|
||||||
|
<field name="res_model">maintenance.report.wiz</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
<field name="context">{'default_report_type' : 'team'}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<menuitem
|
||||||
|
action="action_maintenance_report_wiz"
|
||||||
|
id="maintenance_report_menu"
|
||||||
|
name="Maintenance Reports"
|
||||||
|
parent="maintenance.maintenance_reporting"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<menuitem
|
||||||
|
action="action_spare_report_wiz"
|
||||||
|
id="spare_report_menu"
|
||||||
|
name="Spare Parts Reports"
|
||||||
|
parent="maintenance.maintenance_reporting"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<menuitem
|
||||||
|
action="action_equipment_report_wiz"
|
||||||
|
id="equipment_report_menu"
|
||||||
|
name="Equipment Reports"
|
||||||
|
parent="maintenance.maintenance_reporting"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<menuitem
|
||||||
|
action="action_team_report_wiz"
|
||||||
|
id="team_report_menu"
|
||||||
|
name="Maintenance Team Reports"
|
||||||
|
parent="maintenance.maintenance_reporting"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
Loading…
Reference in New Issue