Add odex25_maintenance

This commit is contained in:
expert 2024-06-24 14:13:41 +03:00
parent 3a3f834c54
commit 4755d7ddc4
40 changed files with 42417 additions and 1 deletions

View File

@ -1,2 +1,2 @@
# odex25-standard-moduless
# odex25-standard-modules
This Repo contains general standard modules for all projects.

View File

@ -0,0 +1,4 @@
from . import models
from . import wizard
from . import reports
from . import controllers

View File

@ -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,
}

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import service

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,4 @@
from . import maintenance
from . import maintenance_asset
from . import maintenance_checklist
from . import maintenance_checklist_line

View File

@ -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')

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -0,0 +1 @@
from . import general_maintenance_report

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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) &lt; 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>

View File

@ -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>

View File

@ -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>

View File

@ -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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_equipment_job equipment.job.user model_maintenance_equipment_job base.group_user 1 0 0 0
3 access_equipment_job_admin_user equipment.job.admin.user model_maintenance_equipment_job maintenance.group_equipment_manager 1 1 1 1
4 access_equipments_jobs equipments.jobs model_maintenance_equipments_jobs 1 1 1 1
5 access_equipment_task equipment.task.user model_maintenance_equipment_task base.group_user 1 0 0 0
6 access_equipment_task_admin_user equipment.task.admin.user model_maintenance_equipment_task maintenance.group_equipment_manager 1 1 1 1
7 access_request_task request.task.user model_maintenance_request_task base.group_user 1 0 0 0
8 access_request_task_admin_user request.task.admin.user model_maintenance_request_task maintenance.group_equipment_manager 1 1 1 1
9 access_maintenance_rootfailure access_maintenance_rootfailure model_maintenance_rootfailure base.group_user 1 0 0 0
10 access_maintenance_rootfailure_admin access_maintenance_rootfailure model_maintenance_rootfailure maintenance.group_equipment_manager 1 1 1 1
11 access_maintenance_report_wiz access_maintenance_report_wiz model_maintenance_report_wiz base.group_user 1 1 1 1
12 access_maintenance_failure access_maintenance_failure model_maintenance_failure base.group_user 1 0 0 0
13 access_maintenance_failure_admin access_maintenance_failure_admin model_maintenance_failure maintenance.group_equipment_manager 1 1 1 1
14 access_maintenance_req_spare access_maintenance_req_spare model_maintenance_request_spare base.group_user 1 0 0 0
15 access_maintenance_req_spare_admin access_maintenance_req_spare_admin model_maintenance_request_spare maintenance.group_equipment_manager 1 1 1 1
16 access_maintenance_summary maintenance_summary_user model_maintenance_summary base.group_user 1 0 0 0
17 access_maintenance_matrial maintenance_matrial_user model_matrial_line base.group_user 1 1 1 1
18 access_checklist_line maintenance_checklist_line model_checklist_line base.group_user 1 1 1 1
19 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

View File

@ -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

View File

@ -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

View File

@ -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)
});

View File

@ -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');
}

View File

@ -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;
}
}

View File

@ -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>

View File

@ -0,0 +1,7 @@
<templates>
<div t-name="maintenance.report.action">
<div>
<h1>Hello</h1>
</div>
</div>
</templates>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1 @@
from . import maintenance_report_wiz

View File

@ -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

View File

@ -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>