diff --git a/maintenance_usage/__init__.py b/maintenance_usage/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/maintenance_usage/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/maintenance_usage/__manifest__.py b/maintenance_usage/__manifest__.py new file mode 100644 index 00000000..f445d745 --- /dev/null +++ b/maintenance_usage/__manifest__.py @@ -0,0 +1,26 @@ +{ + 'name': 'Equipment Usage', + 'version': '11.0.1.0.0', + 'author': 'Hibou Corp. ', + 'category': 'Human Resources', + 'summary': 'Keep track of usage on different types of equipment.', + 'description': """ +Equipment Usage +=============== + +Keep track of usage on different types of equipment. Adds fields for usage on equipments +and descriptive UOM on categories. + +Create preventative maintenance requests based on usage. +""", + 'website': 'https://hibou.io/', + 'depends': [ + 'hr_maintenance', + ], + 'data': [ + 'security/ir.model.access.csv', + 'views/maintenance_views.xml', + ], + 'installable': True, + 'auto_install': False, +} diff --git a/maintenance_usage/models/__init__.py b/maintenance_usage/models/__init__.py new file mode 100644 index 00000000..12bf298f --- /dev/null +++ b/maintenance_usage/models/__init__.py @@ -0,0 +1 @@ +from . import maintenance diff --git a/maintenance_usage/models/maintenance.py b/maintenance_usage/models/maintenance.py new file mode 100644 index 00000000..57d86c9f --- /dev/null +++ b/maintenance_usage/models/maintenance.py @@ -0,0 +1,113 @@ +from math import floor +from odoo import api, fields, models + + +class MaintenanceEquipmentCategory(models.Model): + _inherit = 'maintenance.equipment.category' + + usage_uom_id = fields.Many2one('product.uom', string='Usage UOM') + + +class MaintenanceEquipment(models.Model): + _inherit = 'maintenance.equipment' + + employee_id = fields.Many2one(track_visibility=False) + department_id = fields.Many2one(track_visibility=False) + usage_qty = fields.Float(string='Usage', default=0.0) + usage_uom_id = fields.Many2one('product.uom', related='category_id.usage_uom_id') + usage_log_ids = fields.One2many('maintenance.usage.log', 'equipment_id', string='Usage') + usage_count = fields.Integer(string='Usage Count', compute='_compute_usage_count') + maintenance_usage = fields.Float(string='Preventative Usage') + + def _compute_usage_count(self): + for equipment in self: + equipment.usage_count = len(equipment.usage_log_ids) + + @api.model + def create(self, values): + record = super(MaintenanceEquipment, self).create(values) + # create first usage record + record._log_usage() + return record + + @api.multi + def write(self, values): + usage_qty = values.get('usage_qty') + employee_id = values.get('employee_id') + department_id = values.get('department_id') + if any((usage_qty, employee_id, department_id)): + for equipment in self: + log_values = {} + + if (equipment.usage_qty is not None + and usage_qty is not None + and abs(usage_qty - equipment.usage_qty) > 0.0001): + log_values['qty'] = usage_qty + if employee_id != equipment.employee_id.id: + log_values['employee_id'] = employee_id + if department_id != equipment.department_id.id: + log_values['department_id'] = department_id + + if log_values: + equipment._log_usage(values=log_values) + + # Check to have the original fields before write. + self._check_maintenance_usage(usage_qty) + + result = super(MaintenanceEquipment, self).write(values) + return result + + def _log_usage(self, values={}): + values['equipment_id'] = self.id + values['date'] = fields.Datetime.now() + self.env['maintenance.usage.log'].create(values) + + @api.multi + def _check_maintenance_usage(self, usage_qty): + for e in self.filtered(lambda e: e.maintenance_usage): + try: + if floor(e.usage_qty / e.maintenance_usage) != floor(usage_qty / e.maintenance_usage): + next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False), + ('equipment_id', '=', e.id), + ('maintenance_type', '=', 'preventive'), + ]) + if not next_requests: + e._create_new_request(fields.Date.today()) + except TypeError: + pass + + def action_open_usage_log(self): + for equipment in self: + action = self.env.ref('maintenance_usage.maintenance_usage_log_action_reports').read()[0] + action['domain'] = [('equipment_id', '=', equipment.id)] + action['context'] = { + 'default_equipment_id': equipment.id, + 'default_employee_id': equipment.employee_id.id, + 'default_department_id': equipment.department_id.id, + 'default_qty': equipment.usage_qty, + } + return action + + +class MaintenanceUsageLog(models.Model): + _name = 'maintenance.usage.log' + _order = 'date DESC' + _log_access = False + + date = fields.Datetime(string='Date', default=fields.Datetime.now) + equipment_id = fields.Many2one('maintenance.equipment', string='Equipment', required=True) + employee_id = fields.Many2one('hr.employee', string='Employee') + department_id = fields.Many2one('hr.department', string='Department') + qty = fields.Float(string='Quantity') + uom_id = fields.Many2one(string='Unit of Measure', related='equipment_id.category_id.usage_uom_id') + + @api.model + def create(self, values): + equipment = self.env['maintenance.equipment'].browse(values.get('equipment_id')) + if not values.get('employee_id'): + values['employee_id'] = equipment.employee_id.id + if not values.get('department_id'): + values['department_id'] = equipment.department_id.id + if not values.get('qty'): + values['qty'] = equipment.usage_qty + return super(MaintenanceUsageLog, self).create(values) diff --git a/maintenance_usage/security/ir.model.access.csv b/maintenance_usage/security/ir.model.access.csv new file mode 100644 index 00000000..aea213d8 --- /dev/null +++ b/maintenance_usage/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"manage_maintenance_usage_log","manage maintenance.usage.log","model_maintenance_usage_log","stock.group_stock_manager",1,1,1,1 +"access_maintenance_usage_log","access maintenance.usage.log","model_maintenance_usage_log","base.group_user",1,0,1,0 \ No newline at end of file diff --git a/maintenance_usage/tests/__init__.py b/maintenance_usage/tests/__init__.py new file mode 100644 index 00000000..bd38ce7a --- /dev/null +++ b/maintenance_usage/tests/__init__.py @@ -0,0 +1 @@ +from . import test_maintenance_usage diff --git a/maintenance_usage/tests/test_maintenance_usage.py b/maintenance_usage/tests/test_maintenance_usage.py new file mode 100644 index 00000000..d0d9992f --- /dev/null +++ b/maintenance_usage/tests/test_maintenance_usage.py @@ -0,0 +1,43 @@ +from odoo.tests import common + + +class TestMaintenanceUsage(common.TransactionCase): + """Tests for usage on creation and update + """ + + def test_create(self): + test_usage = 21.0 + equipment = self.env['maintenance.equipment'].create({ + 'name': 'Monitor', + 'usage_qty': test_usage, + }) + + self.assertTrue(equipment.usage_log_ids) + self.assertEqual(equipment.usage_log_ids[0].qty, test_usage) + + def test_update(self): + test_usage = 21.0 + test_usage2 = 50.1 + equipment = self.env['maintenance.equipment'].create({ + 'name': 'Monitor', + 'usage_qty': test_usage, + }) + equipment.usage_qty = test_usage2 + updated_usage = equipment.usage_log_ids.filtered(lambda u: abs(u.qty - test_usage2) < 0.01) + + self.assertTrue(updated_usage) + self.assertAlmostEqual(updated_usage[0].qty, test_usage2) + + def test_maintenance_usage(self): + test_usage = 21.0 + test_usage2 = 50.1 + equipment = self.env['maintenance.equipment'].create({ + 'name': 'Monitor', + 'usage_qty': test_usage, + 'maintenance_usage': 20.0, + 'maintenance_team_id': self.env['maintenance.team'].search([], limit=1).id + }) + self.assertFalse(equipment.maintenance_ids) + + equipment.usage_qty = test_usage2 + self.assertTrue(equipment.maintenance_ids) diff --git a/maintenance_usage/views/maintenance_views.xml b/maintenance_usage/views/maintenance_views.xml new file mode 100644 index 00000000..0899ac92 --- /dev/null +++ b/maintenance_usage/views/maintenance_views.xml @@ -0,0 +1,157 @@ + + + + maintenance.equipment.category.inherited + maintenance.equipment.category + + + + + + + + + + + + equipment.form.inherited + maintenance.equipment + + + + + + + + + + + + + + + + + + + + equipment.usage.log.search + maintenance.usage.log + + + + + + + + + + + + + + + + + equipment.usage.log.form + maintenance.usage.log + +
+
+ + + + + + + + + + + + + + + + + + equipment.usage.log.tree + maintenance.usage.log + + + + + + + + + + + + + + equipment.usage.log.graph + maintenance.usage.log + + + + + + + + + + equipment.usage.log.pivot + maintenance.usage.log + + + + + + + + + + equipment.usage.log.calendar + maintenance.usage.log + + + + + + + + + + + Equipment Usage + maintenance.usage.log + tree,form,graph,pivot,calendar + +

+ No usage. +

+
+
+ + + \ No newline at end of file