From e41171dbf84bf42eb1002e8c51819dad2a935591 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Mon, 2 Oct 2017 18:49:38 +0200 Subject: [PATCH 001/129] [ADD] maintenance_plan module (#2) --- maintenance_plan/README.rst | 94 ++++++++ maintenance_plan/__init__.py | 2 + maintenance_plan/__manifest__.py | 25 ++ .../data/demo_maintenance_plan.xml | 51 ++++ maintenance_plan/hooks.py | 47 ++++ maintenance_plan/models/__init__.py | 1 + maintenance_plan/models/maintenance.py | 222 ++++++++++++++++++ maintenance_plan/security/ir.model.access.csv | 5 + maintenance_plan/tests/__init__.py | 0 .../tests/test_maintenance_plan.py | 44 ++++ maintenance_plan/views/maintenance.xml | 89 +++++++ 11 files changed, 580 insertions(+) create mode 100644 maintenance_plan/README.rst create mode 100644 maintenance_plan/__init__.py create mode 100644 maintenance_plan/__manifest__.py create mode 100644 maintenance_plan/data/demo_maintenance_plan.xml create mode 100644 maintenance_plan/hooks.py create mode 100644 maintenance_plan/models/__init__.py create mode 100644 maintenance_plan/models/maintenance.py create mode 100644 maintenance_plan/security/ir.model.access.csv create mode 100644 maintenance_plan/tests/__init__.py create mode 100644 maintenance_plan/tests/test_maintenance_plan.py create mode 100644 maintenance_plan/views/maintenance.xml diff --git a/maintenance_plan/README.rst b/maintenance_plan/README.rst new file mode 100644 index 000000000..c013c4612 --- /dev/null +++ b/maintenance_plan/README.rst @@ -0,0 +1,94 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +================ +Maintenance Plan +================ + +This module extends the functionality of Odoo Maintenance module by allowing +an equipment to have different preventive maintenance kinds. + +Installation +============ + +Install the module. + +Should you already use the maintenance module and have equipments with field +'Preventive Maintenance Frequency' defined, a new maintenance plan will be +automatically created on these equipments with maintenance kind 'Install'. + +Moreover if a Request of type 'preventive' exists, whose stage isn't marked as +'Request done', and has a Request Date matching the equipment's +'Next Preventive Maintenance', the request will be updated with the +'Install' maintenance kind. + +Make sure you don't have multiple 'preventive' requests at a stage which isn't +marked as 'Request done' and on the same 'Request date' as the equipment or +the module installation will fail with a User Error. + + +Usage +===== + +Instead of defining a period and duration for only one preventive maintenance +per equipment, you can define multiple preventive maintenance kind for each +equipment. + +Maintenance Kinds have to be defined through the configuration menu. Their name +have to be unique and can be set as active or inactive, should these not be +used anymore. + +On any equipment over the maintenance tab, the maintenance plan will appear +as an embedded list view, allowing to add different maintenance kind with their +own period and duration. The next maintenance date will then be computed +automatically according to today's date and the period defined, but the +maintenance request won't be created automatically as is the case in Odoo's +Maintenance module. + +Instead, this module uses the original Cron job of Odoo's Maintenance module +to generate maintenance requests, should there not be any requests which is not +done, at the request date matching the maintenance plan next_maintenance_date +for this equipment and this maintenance kind ! + + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/{repo_id}/10.0 + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Akim Juillerat + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/maintenance_plan/__init__.py b/maintenance_plan/__init__.py new file mode 100644 index 000000000..cc6b6354a --- /dev/null +++ b/maintenance_plan/__init__.py @@ -0,0 +1,2 @@ +from . import models +from .hooks import post_init_hook diff --git a/maintenance_plan/__manifest__.py b/maintenance_plan/__manifest__.py new file mode 100644 index 000000000..7a9dc1364 --- /dev/null +++ b/maintenance_plan/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{'name': 'Maintenance Plan', + 'summary': 'Extends preventive maintenance planning', + 'version': '10.0.1.0.0', + 'author': 'Odoo Community Association (OCA), Camptocamp SA', + 'license': 'AGPL-3', + 'category': 'Maintenance', + 'website': 'http://www.camptocamp.com', + 'images': [], + 'depends': [ + 'maintenance', + ], + 'data': [ + 'security/ir.model.access.csv', + 'views/maintenance.xml' + ], + 'demo': [ + 'data/demo_maintenance_plan.xml' + ], + 'post_init_hook': 'post_init_hook', + 'installable': True, + 'auto_install': False, + } diff --git a/maintenance_plan/data/demo_maintenance_plan.xml b/maintenance_plan/data/demo_maintenance_plan.xml new file mode 100644 index 000000000..2512ee9d0 --- /dev/null +++ b/maintenance_plan/data/demo_maintenance_plan.xml @@ -0,0 +1,51 @@ + + + + + + Monthly + + + + Weekly + + + + + + + + 30 + 2 + + + + + + 30 + 2 + + + + + + 30 + 2 + + + + + + 30 + 4 + + + + + + 7 + 1 + + + + \ No newline at end of file diff --git a/maintenance_plan/hooks.py b/maintenance_plan/hooks.py new file mode 100644 index 000000000..bb63628d4 --- /dev/null +++ b/maintenance_plan/hooks.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging +from odoo import SUPERUSER_ID, api, _ +from odoo.exceptions import UserError + + +def post_init_hook(cr, registry): + + logging.getLogger('odoo.addons.maintenance_plan').info( + 'Migrating existing preventive maintenance') + + env = api.Environment(cr, SUPERUSER_ID, {}) + + equipments = env['maintenance.equipment'].search([('period', '!=', False)]) + + if equipments: + + maintenance_kind = env['maintenance.kind'].create({ + 'name': 'Install', + 'active': True, + }) + + for equipment in equipments: + request = equipment.maintenance_ids.filtered( + lambda r: r.maintenance_type == 'preventive' and not + r.stage_id.done and + r.request_date == equipment.next_action_date) + if len(request) > 1: + raise UserError(_( + "You have multiple preventive maintenance requests on " + "equipment %s next action date (%s). Please leave only " + "one preventive request on the date of equipment's next " + "action to install the module." + ) % (equipment.name, equipment.next_action_date)) + elif len(request) == 1: + request.write({ + 'maintenance_kind_id': maintenance_kind.id, + }) + env['maintenance.plan'].create({ + 'equipment_id': equipment.id, + 'maintenance_kind_id': maintenance_kind.id, + 'duration': equipment.maintenance_duration, + 'period': equipment.period + }) diff --git a/maintenance_plan/models/__init__.py b/maintenance_plan/models/__init__.py new file mode 100644 index 000000000..12bf298f8 --- /dev/null +++ b/maintenance_plan/models/__init__.py @@ -0,0 +1 @@ +from . import maintenance diff --git a/maintenance_plan/models/maintenance.py b/maintenance_plan/models/maintenance.py new file mode 100644 index 000000000..6efdf325d --- /dev/null +++ b/maintenance_plan/models/maintenance.py @@ -0,0 +1,222 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models, fields, api, _ +from datetime import timedelta +from odoo.exceptions import UserError + + +class MaintenanceKind(models.Model): + + _name = 'maintenance.kind' + _description = 'Maintenance Kind' + + name = fields.Char('Name', required=True, translate=True) + active = fields.Boolean('Active Kind', required=True, default=True) + + _sql_constraints = [ + ('name_uniq', 'unique (name)', + "Maintenance kind name already exists.")] + + +class MaintenancePlan(models.Model): + + _name = 'maintenance.plan' + _description = 'Maintenance Plan' + + equipment_id = fields.Many2one(string='Equipment', + comodel_name='maintenance.equipment', + ondelete='cascade') + maintenance_kind_id = fields.Many2one(string='Maintenance kind', + comodel_name='maintenance.kind', + ondelete='restrict') + + period = fields.Integer(string='Period', + help='Days between each maintenance') + duration = fields.Float(string='Duration', + help='Maintenance duration in hours') + + next_maintenance_date = fields.Date('Next maintenance date', + compute='_compute_next_maintenance') + + @api.depends('period', 'maintenance_kind_id', + 'equipment_id.maintenance_ids.request_date', + 'equipment_id.maintenance_ids.close_date', + 'equipment_id.maintenance_ids.maintenance_kind_id') + def _compute_next_maintenance(self): + + date_now = fields.Date.context_today(self) + today_date = fields.Date.from_string(date_now) + + for plan in self.filtered(lambda x: x.period > 0): + + period_timedelta = timedelta(days=plan.period) + + next_maintenance_todo = self.env['maintenance.request'].search([ + ('equipment_id', '=', plan.equipment_id.id), + ('maintenance_type', '=', 'preventive'), + ('maintenance_kind_id', '=', plan.maintenance_kind_id.id), + ('stage_id.done', '!=', True), + ('close_date', '=', False)], order="request_date asc", limit=1) + last_maintenance_done = self.env['maintenance.request'].search([ + ('equipment_id', '=', plan.equipment_id.id), + ('maintenance_type', '=', 'preventive'), + ('maintenance_kind_id', '=', plan.maintenance_kind_id.id), + ('stage_id.done', '=', True), + ('close_date', '!=', False)], order="close_date desc", limit=1) + if next_maintenance_todo and last_maintenance_done: + next_date = next_maintenance_todo.request_date + date_gap = fields.Date.from_string( + next_maintenance_todo.request_date) - \ + fields.Date.from_string(last_maintenance_done.close_date) + # If the gap between the last_maintenance_done and the + # next_maintenance_todo one is bigger than 2 times the period + # and next request is in the future + # We use 2 times the period to avoid creation too closed + # request from a manually one created + if date_gap > max(timedelta(0), period_timedelta * 2) \ + and fields.Date.from_string( + next_maintenance_todo.request_date) > today_date: + # If the new date still in the past, we set it for today + if fields.Date.from_string( + last_maintenance_done.close_date) + \ + period_timedelta < today_date: + next_date = date_now + else: + next_date = fields.Date.to_string( + fields.Date.from_string( + last_maintenance_done.close_date) + + period_timedelta) + elif next_maintenance_todo: + next_date = next_maintenance_todo.request_date + date_gap = fields.Date.from_string( + next_maintenance_todo.request_date) - today_date + # If next maintenance to do is in the future, and in more than + # 2 times the period, we insert an new request + # We use 2 times the period to avoid creation too closed + # request from a manually one created + if date_gap > timedelta(0) and date_gap > period_timedelta * 2: + next_date = fields.Date.to_string( + today_date + period_timedelta) + elif last_maintenance_done: + next_date = fields.Date.from_string( + last_maintenance_done.close_date) + period_timedelta + # If when we add the period to the last maintenance done and + # we still in past, we plan it for today + if next_date < today_date: + next_date = date_now + else: + next_date = fields.Date.to_string( + today_date + period_timedelta) + + plan.next_maintenance_date = next_date + + @api.multi + def unlink(self): + """ Restrict deletion of maintenance plan should there be maintenance + requests of this kind which are not done for its equipment """ + for plan in self: + request = plan.equipment_id.mapped('maintenance_ids').filtered( + lambda r: ( + r.maintenance_kind_id == plan.maintenance_kind_id and + not r.stage_id.done and + r.maintenance_type == 'preventive') + ) + if request: + raise UserError(_('The maintenance plan %s of equipment %s ' + 'has generated a request which is not done ' + 'yet. You should either set the request as ' + 'done, remove its maintenance kind or ' + 'delete it first.') % ( + plan.maintenance_kind_id.name, plan.equipment_id.name)) + super(MaintenancePlan, self).unlink() + + _sql_constraints = [ + ('equipment_kind_uniq', 'unique (equipment_id, maintenance_kind_id)', + "You cannot define multiple times the same maintenance kind on an " + "equipment maintenance plan.")] + + +class MaintenanceEquipment(models.Model): + + _inherit = 'maintenance.equipment' + + maintenance_plan_ids = fields.One2many(string='Maintenance plan', + comodel_name='maintenance.plan', + inverse_name='equipment_id') + maintenance_team_required = fields.Boolean( + compute='_compute_team_required') + + @api.depends('maintenance_plan_ids') + def _compute_team_required(self): + for equipment in self: + equipment.maintenance_team_required = len( + equipment.maintenance_plan_ids) >= 1 + + def _prepare_request_from_plan(self, maintenance_plan): + return { + 'name': _('Preventive Maintenance (%s) - %s') % ( + maintenance_plan.maintenance_kind_id.name, self.name), + 'request_date': maintenance_plan.next_maintenance_date, + 'schedule_date': maintenance_plan.next_maintenance_date, + 'category_id': self.category_id.id, + 'equipment_id': self.id, + 'maintenance_type': 'preventive', + 'owner_user_id': self.owner_user_id.id or self.env.user.id, + 'technician_user_id': self.technician_user_id.id, + 'maintenance_team_id': self.maintenance_team_id.id, + 'maintenance_kind_id': maintenance_plan.maintenance_kind_id.id, + 'duration': maintenance_plan.duration, + } + + def _create_new_request(self, maintenance_plan): + self.ensure_one() + vals = self._prepare_request_from_plan(maintenance_plan) + self.env['maintenance.request'].create(vals) + + @api.model + def _cron_generate_requests(self): + """ + Generates maintenance request on the next_maintenance_date or + today if none exists + """ + for plan in self.env['maintenance.plan'].search([('period', '>', 0)]): + equipment = plan.equipment_id + next_requests = self.env['maintenance.request'].search( + [('stage_id.done', '=', False), + ('equipment_id', '=', equipment.id), + ('maintenance_type', '=', 'preventive'), + ('maintenance_kind_id', '=', plan.maintenance_kind_id.id), + ('request_date', '=', plan.next_maintenance_date)]) + if not next_requests: + equipment._create_new_request(plan) + + @api.depends('maintenance_plan_ids.next_maintenance_date', + 'maintenance_ids.request_date') + def _compute_next_maintenance(self): + """ Redefine the function to display next_action_date in kanban view""" + for equipment in self: + next_plan_dates = equipment.maintenance_plan_ids.mapped( + 'next_maintenance_date') + next_unplanned_dates = self.env['maintenance.request'].search([ + ('equipment_id', '=', equipment.id), + ('maintenance_kind_id', '=', None), + ('request_date', '>', fields.Date.context_today(self)), + ('stage_id.done', '!=', True), + ('close_date', '=', False) + ]).mapped('request_date') + if len(next_plan_dates + next_unplanned_dates) <= 0: + equipment.next_action_date = None + else: + equipment.next_action_date = min(next_plan_dates + + next_unplanned_dates) + + +class MaintenanceRequest(models.Model): + + _inherit = 'maintenance.request' + + maintenance_kind_id = fields.Many2one(string='Maintenance kind', + comodel_name='maintenance.kind', + ondelete='restrict') diff --git a/maintenance_plan/security/ir.model.access.csv b/maintenance_plan/security/ir.model.access.csv new file mode 100644 index 000000000..832936195 --- /dev/null +++ b/maintenance_plan/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_maintenance_kind_user,access_maintenance_kind_user,model_maintenance_kind,base.group_user,1,0,0,0 +access_maintenance_plan_user,access_maintenance_plan_user,model_maintenance_plan,base.group_user,1,0,0,0 +access_maintenance_kind_manager,access_maintenance_kind_manager,model_maintenance_kind,maintenance.group_equipment_manager,1,1,1,1 +access_maintenance_plan_manager,access_maintenance_plan_manager,model_maintenance_plan,maintenance.group_equipment_manager,1,1,1,1 diff --git a/maintenance_plan/tests/__init__.py b/maintenance_plan/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/maintenance_plan/tests/test_maintenance_plan.py b/maintenance_plan/tests/test_maintenance_plan.py new file mode 100644 index 000000000..465f5acd4 --- /dev/null +++ b/maintenance_plan/tests/test_maintenance_plan.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import odoo.tests.common as test_common +from odoo import fields +from datetime import timedelta + + +class TestMaintenancePlan(test_common.TransactionCase): + + def setUp(self): + super(TestMaintenancePlan, self).setUp() + self.printer1 = self.env.ref('maintenance.equipment_printer1') + self.cron = self.env.ref('maintenance.maintenance_requests_cron') + + def test_next_maintenance_date(self): + + today = fields.Date.today() + today_date = fields.Date.from_string(today) + + for plan in self.printer1.maintenance_plan_ids: + self.assertEqual(plan.next_maintenance_date, + fields.Date.to_string( + today_date + timedelta(days=plan.period))) + + def test_generate_requests(self): + + self.cron.method_direct_trigger() + + generated_requests = self.env['maintenance.request'].search( + ['|', + ('maintenance_kind_id', '=', self.env.ref( + 'maintenance_plan.maintenance_kind_monthly').id), + ('maintenance_kind_id', '=', self.env.ref( + 'maintenance_plan.maintenance_kind_weekly').id) + ]) + + for req in generated_requests: + for plan in req.equipment_id.maintenance_plan_ids: + if plan.maintenance_kind_id == req.maintenance_kind_id: + self.assertEqual(req.duration, plan.duration) + self.assertEqual(req.request_date, + plan.next_maintenance_date) diff --git a/maintenance_plan/views/maintenance.xml b/maintenance_plan/views/maintenance.xml new file mode 100644 index 000000000..c8805df3f --- /dev/null +++ b/maintenance_plan/views/maintenance.xml @@ -0,0 +1,89 @@ + + + + + maintenance.kind.tree + maintenance.kind + + + + + + + + + + + Maintenance kinds + maintenance.kind + tree + + + + + + + + + maintenance.plan.form + maintenance.plan + +
+ + + + + + +
+
+
+ + + maintenance.plan.tree + maintenance.plan + + + + + + + + + + + + + equipment.form.inherit + + maintenance.equipment + + + + + + + + + {'required': [('maintenance_team_required', '=', True)]} + + + + + + + equipment.request.form.inherit + maintenance.request + + + + + + + +
From d934e4fe36005daff6c5862cd131f7ffc0513fde Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Wed, 29 Nov 2017 14:35:21 +0100 Subject: [PATCH 002/129] [FIX] maintenance_plan: README try me on runbot link --- maintenance_plan/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maintenance_plan/README.rst b/maintenance_plan/README.rst index c013c4612..eee0640f5 100644 --- a/maintenance_plan/README.rst +++ b/maintenance_plan/README.rst @@ -54,7 +54,7 @@ for this equipment and this maintenance kind ! .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/{repo_id}/10.0 + :target: https://runbot.odoo-community.org/runbot/240/10.0 Bug Tracker From 235b7bf6e76abeb58bcdc5646512a0c547283159 Mon Sep 17 00:00:00 2001 From: Matteo Mazzoni Date: Thu, 25 Oct 2018 23:49:01 +0200 Subject: [PATCH 003/129] [MIG] maintenance_plan: Migration to 11.0 --- maintenance_plan/README.rst | 71 ++- maintenance_plan/__manifest__.py | 6 +- maintenance_plan/hooks.py | 1 - maintenance_plan/models/maintenance.py | 7 +- maintenance_plan/readme/CONTRIBUTORS.rst | 3 + maintenance_plan/readme/DESCRIPTION.rst | 2 + maintenance_plan/readme/INSTALL.rst | 14 + maintenance_plan/readme/USAGE.rst | 19 + .../static/description/index.html | 457 ++++++++++++++++++ maintenance_plan/tests/__init__.py | 1 + .../tests/test_maintenance_plan.py | 3 +- maintenance_plan/views/maintenance.xml | 5 +- 12 files changed, 554 insertions(+), 35 deletions(-) create mode 100644 maintenance_plan/readme/CONTRIBUTORS.rst create mode 100644 maintenance_plan/readme/DESCRIPTION.rst create mode 100644 maintenance_plan/readme/INSTALL.rst create mode 100644 maintenance_plan/readme/USAGE.rst create mode 100644 maintenance_plan/static/description/index.html diff --git a/maintenance_plan/README.rst b/maintenance_plan/README.rst index eee0640f5..a1e0ff0a5 100644 --- a/maintenance_plan/README.rst +++ b/maintenance_plan/README.rst @@ -1,14 +1,38 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 - ================ Maintenance Plan ================ +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmaintenance-lightgray.png?logo=github + :target: https://github.com/OCA/maintenance/tree/11.0/maintenance_plan + :alt: OCA/maintenance +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/maintenance-11-0/maintenance-11-0-maintenance_plan + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/240/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + This module extends the functionality of Odoo Maintenance module by allowing an equipment to have different preventive maintenance kinds. +**Table of contents** + +.. contents:: + :local: + Installation ============ @@ -27,7 +51,6 @@ Make sure you don't have multiple 'preventive' requests at a stage which isn't marked as 'Request done' and on the same 'Request date' as the equipment or the module installation will fail with a User Error. - Usage ===== @@ -51,44 +74,44 @@ to generate maintenance requests, should there not be any requests which is not done, at the request date matching the maintenance plan next_maintenance_date for this equipment and this maintenance kind ! - -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/240/10.0 - - Bug Tracker =========== -Bugs are tracked on `GitHub Issues -`_. In case of trouble, please -check there if your issue has already been reported. If you spotted it first, -help us smash it by providing detailed and welcomed feedback. +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= -Images ------- +Authors +~~~~~~~ -* Odoo Community Association: `Icon `_. +* Camptocamp SA Contributors ------------- +~~~~~~~~~~~~ * Akim Juillerat +* Matteo Mazzoni +* David Alonso -Maintainer ----------- +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. +This module is part of the `OCA/maintenance `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/maintenance_plan/__manifest__.py b/maintenance_plan/__manifest__.py index 7a9dc1364..6ee08cf36 100644 --- a/maintenance_plan/__manifest__.py +++ b/maintenance_plan/__manifest__.py @@ -1,13 +1,12 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). {'name': 'Maintenance Plan', 'summary': 'Extends preventive maintenance planning', - 'version': '10.0.1.0.0', + 'version': '11.0.1.0.0', 'author': 'Odoo Community Association (OCA), Camptocamp SA', 'license': 'AGPL-3', 'category': 'Maintenance', - 'website': 'http://www.camptocamp.com', + 'website': 'https://github.com/OCA/maintenance', 'images': [], 'depends': [ 'maintenance', @@ -21,5 +20,4 @@ ], 'post_init_hook': 'post_init_hook', 'installable': True, - 'auto_install': False, } diff --git a/maintenance_plan/hooks.py b/maintenance_plan/hooks.py index bb63628d4..2f8d7a8c2 100644 --- a/maintenance_plan/hooks.py +++ b/maintenance_plan/hooks.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/maintenance_plan/models/maintenance.py b/maintenance_plan/models/maintenance.py index 6efdf325d..2ee122f29 100644 --- a/maintenance_plan/models/maintenance.py +++ b/maintenance_plan/models/maintenance.py @@ -1,9 +1,10 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import models, fields, api, _ from datetime import timedelta + +from odoo import _, api, fields, models + from odoo.exceptions import UserError @@ -130,7 +131,7 @@ def unlink(self): 'done, remove its maintenance kind or ' 'delete it first.') % ( plan.maintenance_kind_id.name, plan.equipment_id.name)) - super(MaintenancePlan, self).unlink() + super().unlink() _sql_constraints = [ ('equipment_kind_uniq', 'unique (equipment_id, maintenance_kind_id)', diff --git a/maintenance_plan/readme/CONTRIBUTORS.rst b/maintenance_plan/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..41b667528 --- /dev/null +++ b/maintenance_plan/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Akim Juillerat +* Matteo Mazzoni +* David Alonso diff --git a/maintenance_plan/readme/DESCRIPTION.rst b/maintenance_plan/readme/DESCRIPTION.rst new file mode 100644 index 000000000..2e3ff2219 --- /dev/null +++ b/maintenance_plan/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module extends the functionality of Odoo Maintenance module by allowing +an equipment to have different preventive maintenance kinds. diff --git a/maintenance_plan/readme/INSTALL.rst b/maintenance_plan/readme/INSTALL.rst new file mode 100644 index 000000000..72312331b --- /dev/null +++ b/maintenance_plan/readme/INSTALL.rst @@ -0,0 +1,14 @@ +Install the module. + +Should you already use the maintenance module and have equipments with field +'Preventive Maintenance Frequency' defined, a new maintenance plan will be +automatically created on these equipments with maintenance kind 'Install'. + +Moreover if a Request of type 'preventive' exists, whose stage isn't marked as +'Request done', and has a Request Date matching the equipment's +'Next Preventive Maintenance', the request will be updated with the +'Install' maintenance kind. + +Make sure you don't have multiple 'preventive' requests at a stage which isn't +marked as 'Request done' and on the same 'Request date' as the equipment or +the module installation will fail with a User Error. diff --git a/maintenance_plan/readme/USAGE.rst b/maintenance_plan/readme/USAGE.rst new file mode 100644 index 000000000..e7012288f --- /dev/null +++ b/maintenance_plan/readme/USAGE.rst @@ -0,0 +1,19 @@ +Instead of defining a period and duration for only one preventive maintenance +per equipment, you can define multiple preventive maintenance kind for each +equipment. + +Maintenance Kinds have to be defined through the configuration menu. Their name +have to be unique and can be set as active or inactive, should these not be +used anymore. + +On any equipment over the maintenance tab, the maintenance plan will appear +as an embedded list view, allowing to add different maintenance kind with their +own period and duration. The next maintenance date will then be computed +automatically according to today's date and the period defined, but the +maintenance request won't be created automatically as is the case in Odoo's +Maintenance module. + +Instead, this module uses the original Cron job of Odoo's Maintenance module +to generate maintenance requests, should there not be any requests which is not +done, at the request date matching the maintenance plan next_maintenance_date +for this equipment and this maintenance kind ! diff --git a/maintenance_plan/static/description/index.html b/maintenance_plan/static/description/index.html new file mode 100644 index 000000000..532ce9bfa --- /dev/null +++ b/maintenance_plan/static/description/index.html @@ -0,0 +1,457 @@ + + + + + + +Maintenance Plan + + + +
+

Maintenance Plan

+ + +

Beta License: AGPL-3 OCA/maintenance Translate me on Weblate Try me on Runbot

+

This module extends the functionality of Odoo Maintenance module by allowing +an equipment to have different preventive maintenance kinds.

+

Table of contents

+ +
+

Installation

+

Install the module.

+

Should you already use the maintenance module and have equipments with field +‘Preventive Maintenance Frequency’ defined, a new maintenance plan will be +automatically created on these equipments with maintenance kind ‘Install’.

+

Moreover if a Request of type ‘preventive’ exists, whose stage isn’t marked as +‘Request done’, and has a Request Date matching the equipment’s +‘Next Preventive Maintenance’, the request will be updated with the +‘Install’ maintenance kind.

+

Make sure you don’t have multiple ‘preventive’ requests at a stage which isn’t +marked as ‘Request done’ and on the same ‘Request date’ as the equipment or +the module installation will fail with a User Error.

+
+
+

Usage

+

Instead of defining a period and duration for only one preventive maintenance +per equipment, you can define multiple preventive maintenance kind for each +equipment.

+

Maintenance Kinds have to be defined through the configuration menu. Their name +have to be unique and can be set as active or inactive, should these not be +used anymore.

+

On any equipment over the maintenance tab, the maintenance plan will appear +as an embedded list view, allowing to add different maintenance kind with their +own period and duration. The next maintenance date will then be computed +automatically according to today’s date and the period defined, but the +maintenance request won’t be created automatically as is the case in Odoo’s +Maintenance module.

+

Instead, this module uses the original Cron job of Odoo’s Maintenance module +to generate maintenance requests, should there not be any requests which is not +done, at the request date matching the maintenance plan next_maintenance_date +for this equipment and this maintenance kind !

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp SA
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/maintenance project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/maintenance_plan/tests/__init__.py b/maintenance_plan/tests/__init__.py index e69de29bb..c701c6934 100644 --- a/maintenance_plan/tests/__init__.py +++ b/maintenance_plan/tests/__init__.py @@ -0,0 +1 @@ +from . import test_maintenance_plan diff --git a/maintenance_plan/tests/test_maintenance_plan.py b/maintenance_plan/tests/test_maintenance_plan.py index 465f5acd4..c6b93ce8d 100644 --- a/maintenance_plan/tests/test_maintenance_plan.py +++ b/maintenance_plan/tests/test_maintenance_plan.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). @@ -10,7 +9,7 @@ class TestMaintenancePlan(test_common.TransactionCase): def setUp(self): - super(TestMaintenancePlan, self).setUp() + super().setUp() self.printer1 = self.env.ref('maintenance.equipment_printer1') self.cron = self.env.ref('maintenance.maintenance_requests_cron') diff --git a/maintenance_plan/views/maintenance.xml b/maintenance_plan/views/maintenance.xml index c8805df3f..108a32aa7 100644 --- a/maintenance_plan/views/maintenance.xml +++ b/maintenance_plan/views/maintenance.xml @@ -1,11 +1,12 @@ + maintenance.kind.tree maintenance.kind - + @@ -86,4 +87,6 @@ + + From e2b756965d999ef0e37079bfeb8d2d54cfc34061 Mon Sep 17 00:00:00 2001 From: "David Alonso (Solvos)" Date: Mon, 1 Jul 2019 17:04:48 +0200 Subject: [PATCH 004/129] [FIX] maintenance_plan: prevent preventive request cron crashing when equipment maintenance team is not filled [ADD] icon.png --- maintenance_plan/models/maintenance.py | 5 ++++- maintenance_plan/static/description/icon.png | Bin 0 -> 9455 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 maintenance_plan/static/description/icon.png diff --git a/maintenance_plan/models/maintenance.py b/maintenance_plan/models/maintenance.py index 2ee122f29..e9bab5084 100644 --- a/maintenance_plan/models/maintenance.py +++ b/maintenance_plan/models/maintenance.py @@ -156,6 +156,9 @@ def _compute_team_required(self): equipment.maintenance_plan_ids) >= 1 def _prepare_request_from_plan(self, maintenance_plan): + team = self.maintenance_team_id + if not team: + team = self.env['maintenance.request']._get_default_team_id() return { 'name': _('Preventive Maintenance (%s) - %s') % ( maintenance_plan.maintenance_kind_id.name, self.name), @@ -166,7 +169,7 @@ def _prepare_request_from_plan(self, maintenance_plan): 'maintenance_type': 'preventive', 'owner_user_id': self.owner_user_id.id or self.env.user.id, 'technician_user_id': self.technician_user_id.id, - 'maintenance_team_id': self.maintenance_team_id.id, + 'maintenance_team_id': team.id, 'maintenance_kind_id': maintenance_plan.maintenance_kind_id.id, 'duration': maintenance_plan.duration, } diff --git a/maintenance_plan/static/description/icon.png b/maintenance_plan/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From 21d118d952032238cada71ea7785aa71867626b8 Mon Sep 17 00:00:00 2001 From: "David Alonso (Solvos)" Date: Mon, 8 Jul 2019 11:46:06 +0200 Subject: [PATCH 005/129] [MIG] maintenance_plan: Migration to 12.0 [UPD] Update maintenance_plan.pot --- maintenance_plan/README.rst | 10 +- maintenance_plan/__manifest__.py | 2 +- .../data/demo_maintenance_plan.xml | 2 +- maintenance_plan/i18n/maintenance_plan.pot | 177 ++++++++++++++++++ maintenance_plan/models/maintenance.py | 54 +++--- .../static/description/index.html | 6 +- .../tests/test_maintenance_plan.py | 29 ++- maintenance_plan/views/maintenance.xml | 18 +- 8 files changed, 236 insertions(+), 62 deletions(-) create mode 100644 maintenance_plan/i18n/maintenance_plan.pot diff --git a/maintenance_plan/README.rst b/maintenance_plan/README.rst index a1e0ff0a5..60fc3de50 100644 --- a/maintenance_plan/README.rst +++ b/maintenance_plan/README.rst @@ -14,13 +14,13 @@ Maintenance Plan :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmaintenance-lightgray.png?logo=github - :target: https://github.com/OCA/maintenance/tree/11.0/maintenance_plan + :target: https://github.com/OCA/maintenance/tree/12.0/maintenance_plan :alt: OCA/maintenance .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/maintenance-11-0/maintenance-11-0-maintenance_plan + :target: https://translation.odoo-community.org/projects/maintenance-12-0/maintenance-12-0-maintenance_plan :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/240/11.0 + :target: https://runbot.odoo-community.org/runbot/240/12.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -80,7 +80,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -112,6 +112,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/maintenance `_ project on GitHub. +This module is part of the `OCA/maintenance `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/maintenance_plan/__manifest__.py b/maintenance_plan/__manifest__.py index 6ee08cf36..73cb82cfb 100644 --- a/maintenance_plan/__manifest__.py +++ b/maintenance_plan/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). {'name': 'Maintenance Plan', 'summary': 'Extends preventive maintenance planning', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'author': 'Odoo Community Association (OCA), Camptocamp SA', 'license': 'AGPL-3', 'category': 'Maintenance', diff --git a/maintenance_plan/data/demo_maintenance_plan.xml b/maintenance_plan/data/demo_maintenance_plan.xml index 2512ee9d0..c780c9f7c 100644 --- a/maintenance_plan/data/demo_maintenance_plan.xml +++ b/maintenance_plan/data/demo_maintenance_plan.xml @@ -48,4 +48,4 @@ - \ No newline at end of file + diff --git a/maintenance_plan/i18n/maintenance_plan.pot b/maintenance_plan/i18n/maintenance_plan.pot new file mode 100644 index 000000000..dcdb998d1 --- /dev/null +++ b/maintenance_plan/i18n/maintenance_plan.pot @@ -0,0 +1,177 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * maintenance_plan +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__active +msgid "Active Kind" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__create_uid +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__create_uid +msgid "Created by" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__create_date +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__create_date +msgid "Created on" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,help:maintenance_plan.field_maintenance_plan__period +msgid "Days between each maintenance" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__display_name +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__display_name +msgid "Display Name" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__duration +msgid "Duration" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__equipment_id +msgid "Equipment" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__id +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__id +msgid "ID" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind____last_update +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan____last_update +msgid "Last Modified on" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__write_uid +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__write_date +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__write_date +msgid "Last Updated on" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model,name:maintenance_plan.model_maintenance_equipment +msgid "Maintenance Equipment" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model,name:maintenance_plan.model_maintenance_kind +msgid "Maintenance Kind" +msgstr "" + +#. module: maintenance_plan +#: model:ir.actions.act_window,name:maintenance_plan.maintenance_kind_action +#: model:ir.ui.menu,name:maintenance_plan.menu_maintenance_kind_configuration +msgid "Maintenance Kinds" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model,name:maintenance_plan.model_maintenance_plan +msgid "Maintenance Plan" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model,name:maintenance_plan.model_maintenance_request +msgid "Maintenance Request" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_equipment__maintenance_team_required +msgid "Maintenance Team Required" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,help:maintenance_plan.field_maintenance_plan__duration +msgid "Maintenance duration in hours" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__maintenance_kind_id +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_request__maintenance_kind_id +msgid "Maintenance kind" +msgstr "" + +#. module: maintenance_plan +#: sql_constraint:maintenance.kind:0 +msgid "Maintenance kind name already exists." +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_equipment__maintenance_plan_ids +msgid "Maintenance plan" +msgstr "" + +#. module: maintenance_plan +#: model:maintenance.kind,name:maintenance_plan.maintenance_kind_monthly +msgid "Monthly" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__name +msgid "Name" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__next_maintenance_date +msgid "Next maintenance date" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__period +msgid "Period" +msgstr "" + +#. module: maintenance_plan +#: code:addons/maintenance_plan/models/maintenance.py:151 +#, python-format +msgid "Preventive Maintenance (%s) - %s" +msgstr "" + +#. module: maintenance_plan +#: code:addons/maintenance_plan/models/maintenance.py:116 +#, python-format +msgid "The maintenance plan %s of equipment %s has generated a request which is not done yet. You should either set the request as done, remove its maintenance kind or delete it first." +msgstr "" + +#. module: maintenance_plan +#: model:maintenance.kind,name:maintenance_plan.maintenance_kind_weekly +msgid "Weekly" +msgstr "" + +#. module: maintenance_plan +#: sql_constraint:maintenance.plan:0 +msgid "You cannot define multiple times the same maintenance kind on an equipment maintenance plan." +msgstr "" + +#. module: maintenance_plan +#: code:addons/maintenance_plan/hooks.py:31 +#, python-format +msgid "You have multiple preventive maintenance requests on equipment %s next action date (%s). Please leave only one preventive request on the date of equipment's next action to install the module." +msgstr "" + diff --git a/maintenance_plan/models/maintenance.py b/maintenance_plan/models/maintenance.py index e9bab5084..3c1933648 100644 --- a/maintenance_plan/models/maintenance.py +++ b/maintenance_plan/models/maintenance.py @@ -13,7 +13,7 @@ class MaintenanceKind(models.Model): _name = 'maintenance.kind' _description = 'Maintenance Kind' - name = fields.Char('Name', required=True, translate=True) + name = fields.Char(required=True, translate=True) active = fields.Boolean('Active Kind', required=True, default=True) _sql_constraints = [ @@ -33,10 +33,8 @@ class MaintenancePlan(models.Model): comodel_name='maintenance.kind', ondelete='restrict') - period = fields.Integer(string='Period', - help='Days between each maintenance') - duration = fields.Float(string='Duration', - help='Maintenance duration in hours') + period = fields.Integer(help='Days between each maintenance') + duration = fields.Float(help='Maintenance duration in hours') next_maintenance_date = fields.Date('Next maintenance date', compute='_compute_next_maintenance') @@ -47,8 +45,7 @@ class MaintenancePlan(models.Model): 'equipment_id.maintenance_ids.maintenance_kind_id') def _compute_next_maintenance(self): - date_now = fields.Date.context_today(self) - today_date = fields.Date.from_string(date_now) + today_date = fields.Date.context_today(self) for plan in self.filtered(lambda x: x.period > 0): @@ -68,48 +65,39 @@ def _compute_next_maintenance(self): ('close_date', '!=', False)], order="close_date desc", limit=1) if next_maintenance_todo and last_maintenance_done: next_date = next_maintenance_todo.request_date - date_gap = fields.Date.from_string( - next_maintenance_todo.request_date) - \ - fields.Date.from_string(last_maintenance_done.close_date) + date_gap = next_maintenance_todo.request_date - \ + last_maintenance_done.close_date # If the gap between the last_maintenance_done and the # next_maintenance_todo one is bigger than 2 times the period # and next request is in the future # We use 2 times the period to avoid creation too closed # request from a manually one created if date_gap > max(timedelta(0), period_timedelta * 2) \ - and fields.Date.from_string( - next_maintenance_todo.request_date) > today_date: + and next_maintenance_todo.request_date > today_date: # If the new date still in the past, we set it for today - if fields.Date.from_string( - last_maintenance_done.close_date) + \ + if last_maintenance_done.close_date + \ period_timedelta < today_date: - next_date = date_now + next_date = today_date else: - next_date = fields.Date.to_string( - fields.Date.from_string( - last_maintenance_done.close_date) + - period_timedelta) + next_date = last_maintenance_done.close_date + \ + period_timedelta elif next_maintenance_todo: next_date = next_maintenance_todo.request_date - date_gap = fields.Date.from_string( - next_maintenance_todo.request_date) - today_date + date_gap = next_maintenance_todo.request_date - today_date # If next maintenance to do is in the future, and in more than # 2 times the period, we insert an new request # We use 2 times the period to avoid creation too closed # request from a manually one created if date_gap > timedelta(0) and date_gap > period_timedelta * 2: - next_date = fields.Date.to_string( - today_date + period_timedelta) + next_date = today_date + period_timedelta elif last_maintenance_done: - next_date = fields.Date.from_string( - last_maintenance_done.close_date) + period_timedelta + next_date = last_maintenance_done.close_date + period_timedelta # If when we add the period to the last maintenance done and # we still in past, we plan it for today if next_date < today_date: - next_date = date_now + next_date = today_date else: - next_date = fields.Date.to_string( - today_date + period_timedelta) + next_date = today_date + period_timedelta plan.next_maintenance_date = next_date @@ -156,9 +144,9 @@ def _compute_team_required(self): equipment.maintenance_plan_ids) >= 1 def _prepare_request_from_plan(self, maintenance_plan): - team = self.maintenance_team_id - if not team: - team = self.env['maintenance.request']._get_default_team_id() + team_id = self.maintenance_team_id.id + if not team_id: + team_id = self.env['maintenance.request']._get_default_team_id() return { 'name': _('Preventive Maintenance (%s) - %s') % ( maintenance_plan.maintenance_kind_id.name, self.name), @@ -168,8 +156,8 @@ def _prepare_request_from_plan(self, maintenance_plan): 'equipment_id': self.id, 'maintenance_type': 'preventive', 'owner_user_id': self.owner_user_id.id or self.env.user.id, - 'technician_user_id': self.technician_user_id.id, - 'maintenance_team_id': team.id, + 'user_id': self.technician_user_id.id, + 'maintenance_team_id': team_id, 'maintenance_kind_id': maintenance_plan.maintenance_kind_id.id, 'duration': maintenance_plan.duration, } diff --git a/maintenance_plan/static/description/index.html b/maintenance_plan/static/description/index.html index 532ce9bfa..e3db0f28b 100644 --- a/maintenance_plan/static/description/index.html +++ b/maintenance_plan/static/description/index.html @@ -367,7 +367,7 @@

Maintenance Plan

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/maintenance Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/maintenance Translate me on Weblate Try me on Runbot

This module extends the functionality of Odoo Maintenance module by allowing an equipment to have different preventive maintenance kinds.

Table of contents

@@ -422,7 +422,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -448,7 +448,7 @@

Maintainers

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/maintenance project on GitHub.

+

This module is part of the OCA/maintenance project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/maintenance_plan/tests/test_maintenance_plan.py b/maintenance_plan/tests/test_maintenance_plan.py index c6b93ce8d..4ffba0f3e 100644 --- a/maintenance_plan/tests/test_maintenance_plan.py +++ b/maintenance_plan/tests/test_maintenance_plan.py @@ -11,29 +11,38 @@ class TestMaintenancePlan(test_common.TransactionCase): def setUp(self): super().setUp() self.printer1 = self.env.ref('maintenance.equipment_printer1') + self.monitor1 = self.env.ref('maintenance.equipment_monitor1') self.cron = self.env.ref('maintenance.maintenance_requests_cron') + self.kind_quarterly = self.env['maintenance.kind'].create({ + 'name': 'Quarterly', + 'active': True, + }) + self.monitor1.maintenance_plan_ids = [(0, 0, { + 'maintenance_kind_id': self.kind_quarterly.id, + 'period': 90, + 'duration': 3 + })] + def test_next_maintenance_date(self): today = fields.Date.today() - today_date = fields.Date.from_string(today) - for plan in self.printer1.maintenance_plan_ids: + plan_ids = self.printer1.maintenance_plan_ids + \ + self.monitor1.maintenance_plan_ids + for plan in plan_ids: self.assertEqual(plan.next_maintenance_date, - fields.Date.to_string( - today_date + timedelta(days=plan.period))) + today + timedelta(days=plan.period)) def test_generate_requests(self): self.cron.method_direct_trigger() generated_requests = self.env['maintenance.request'].search( - ['|', - ('maintenance_kind_id', '=', self.env.ref( - 'maintenance_plan.maintenance_kind_monthly').id), - ('maintenance_kind_id', '=', self.env.ref( - 'maintenance_plan.maintenance_kind_weekly').id) - ]) + [('maintenance_kind_id', 'in', [ + self.env.ref('maintenance_plan.maintenance_kind_monthly').id, + self.env.ref('maintenance_plan.maintenance_kind_weekly').id, + self.kind_quarterly.id])]) for req in generated_requests: for plan in req.equipment_id.maintenance_plan_ids: diff --git a/maintenance_plan/views/maintenance.xml b/maintenance_plan/views/maintenance.xml index 108a32aa7..72a631a49 100644 --- a/maintenance_plan/views/maintenance.xml +++ b/maintenance_plan/views/maintenance.xml @@ -6,7 +6,7 @@ maintenance.kind.tree maintenance.kind - + @@ -15,7 +15,7 @@ - Maintenance kinds + Maintenance Kinds maintenance.kind tree @@ -23,7 +23,6 @@ @@ -34,7 +33,7 @@ maintenance.plan.form maintenance.plan -
+ @@ -49,7 +48,7 @@ maintenance.plan.tree maintenance.plan - + @@ -60,12 +59,14 @@ - equipment.form.inherit maintenance.equipment - - + + 1 + + + @@ -78,7 +79,6 @@ - equipment.request.form.inherit maintenance.request From 6b8159423605c8d532af4dba891cf71a6d5bf80c Mon Sep 17 00:00:00 2001 From: lromero-solvos Date: Fri, 26 Jul 2019 11:54:01 +0000 Subject: [PATCH 006/129] Added translation using Weblate (Spanish) --- maintenance_plan/i18n/es.po | 177 ++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 maintenance_plan/i18n/es.po diff --git a/maintenance_plan/i18n/es.po b/maintenance_plan/i18n/es.po new file mode 100644 index 000000000..324a9d927 --- /dev/null +++ b/maintenance_plan/i18n/es.po @@ -0,0 +1,177 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * maintenance_plan +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__active +msgid "Active Kind" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__create_uid +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__create_uid +msgid "Created by" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__create_date +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__create_date +msgid "Created on" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,help:maintenance_plan.field_maintenance_plan__period +msgid "Days between each maintenance" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__display_name +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__display_name +msgid "Display Name" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__duration +msgid "Duration" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__equipment_id +msgid "Equipment" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__id +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__id +msgid "ID" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind____last_update +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan____last_update +msgid "Last Modified on" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__write_uid +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__write_date +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__write_date +msgid "Last Updated on" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model,name:maintenance_plan.model_maintenance_equipment +msgid "Maintenance Equipment" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model,name:maintenance_plan.model_maintenance_kind +msgid "Maintenance Kind" +msgstr "" + +#. module: maintenance_plan +#: model:ir.actions.act_window,name:maintenance_plan.maintenance_kind_action +#: model:ir.ui.menu,name:maintenance_plan.menu_maintenance_kind_configuration +msgid "Maintenance Kinds" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model,name:maintenance_plan.model_maintenance_plan +msgid "Maintenance Plan" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model,name:maintenance_plan.model_maintenance_request +msgid "Maintenance Request" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_equipment__maintenance_team_required +msgid "Maintenance Team Required" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,help:maintenance_plan.field_maintenance_plan__duration +msgid "Maintenance duration in hours" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__maintenance_kind_id +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_request__maintenance_kind_id +msgid "Maintenance kind" +msgstr "" + +#. module: maintenance_plan +#: sql_constraint:maintenance.kind:0 +msgid "Maintenance kind name already exists." +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_equipment__maintenance_plan_ids +msgid "Maintenance plan" +msgstr "" + +#. module: maintenance_plan +#: model:maintenance.kind,name:maintenance_plan.maintenance_kind_monthly +msgid "Monthly" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__name +msgid "Name" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__next_maintenance_date +msgid "Next maintenance date" +msgstr "" + +#. module: maintenance_plan +#: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__period +msgid "Period" +msgstr "" + +#. module: maintenance_plan +#: code:addons/maintenance_plan/models/maintenance.py:151 +#, python-format +msgid "Preventive Maintenance (%s) - %s" +msgstr "" + +#. module: maintenance_plan +#: code:addons/maintenance_plan/models/maintenance.py:116 +#, python-format +msgid "The maintenance plan %s of equipment %s has generated a request which is not done yet. You should either set the request as done, remove its maintenance kind or delete it first." +msgstr "" + +#. module: maintenance_plan +#: model:maintenance.kind,name:maintenance_plan.maintenance_kind_weekly +msgid "Weekly" +msgstr "" + +#. module: maintenance_plan +#: sql_constraint:maintenance.plan:0 +msgid "You cannot define multiple times the same maintenance kind on an equipment maintenance plan." +msgstr "" + +#. module: maintenance_plan +#: code:addons/maintenance_plan/hooks.py:31 +#, python-format +msgid "You have multiple preventive maintenance requests on equipment %s next action date (%s). Please leave only one preventive request on the date of equipment's next action to install the module." +msgstr "" From 5cc0bc0b2279d33c8f88e55d05b50440299dce9c Mon Sep 17 00:00:00 2001 From: lromero-solvos Date: Fri, 26 Jul 2019 11:55:56 +0000 Subject: [PATCH 007/129] Translated using Weblate (Spanish) Currently translated at 100.0% (30 of 30 strings) Translation: maintenance-12.0/maintenance-12.0-maintenance_plan Translate-URL: https://translation.odoo-community.org/projects/maintenance-12-0/maintenance-12-0-maintenance_plan/es/ [UPD] README.rst --- maintenance_plan/i18n/es.po | 66 +++++++++++-------- .../static/description/index.html | 2 +- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/maintenance_plan/i18n/es.po b/maintenance_plan/i18n/es.po index 324a9d927..39e5dd86a 100644 --- a/maintenance_plan/i18n/es.po +++ b/maintenance_plan/i18n/es.po @@ -6,172 +6,182 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2019-07-26 14:43+0000\n" +"Last-Translator: lromero-solvos \n" "Language-Team: none\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.7.1\n" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__active msgid "Active Kind" -msgstr "" +msgstr "Tipo activo" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__create_uid #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__create_uid msgid "Created by" -msgstr "" +msgstr "Creado por" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__create_date #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__create_date msgid "Created on" -msgstr "" +msgstr "Creado en" #. module: maintenance_plan #: model:ir.model.fields,help:maintenance_plan.field_maintenance_plan__period msgid "Days between each maintenance" -msgstr "" +msgstr "Días entre cada mantenimiento" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__display_name #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__display_name msgid "Display Name" -msgstr "" +msgstr "Nombre a mostrar" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__duration msgid "Duration" -msgstr "" +msgstr "Duración" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__equipment_id msgid "Equipment" -msgstr "" +msgstr "Equipo" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__id #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__id msgid "ID" -msgstr "" +msgstr "ID" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind____last_update #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan____last_update msgid "Last Modified on" -msgstr "" +msgstr "Última modificación en" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__write_uid #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__write_uid msgid "Last Updated by" -msgstr "" +msgstr "Última modificación por" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__write_date #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__write_date msgid "Last Updated on" -msgstr "" +msgstr "Última actualización en" #. module: maintenance_plan #: model:ir.model,name:maintenance_plan.model_maintenance_equipment msgid "Maintenance Equipment" -msgstr "" +msgstr "Equipo" #. module: maintenance_plan #: model:ir.model,name:maintenance_plan.model_maintenance_kind msgid "Maintenance Kind" -msgstr "" +msgstr "Tipo de mantenimiento" #. module: maintenance_plan #: model:ir.actions.act_window,name:maintenance_plan.maintenance_kind_action #: model:ir.ui.menu,name:maintenance_plan.menu_maintenance_kind_configuration msgid "Maintenance Kinds" -msgstr "" +msgstr "Tipos de mantenimiento" #. module: maintenance_plan #: model:ir.model,name:maintenance_plan.model_maintenance_plan msgid "Maintenance Plan" -msgstr "" +msgstr "Plan de mantenimiento" #. module: maintenance_plan #: model:ir.model,name:maintenance_plan.model_maintenance_request msgid "Maintenance Request" -msgstr "" +msgstr "Peticiones de mantenimiento" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_equipment__maintenance_team_required msgid "Maintenance Team Required" -msgstr "" +msgstr "Equipo de mantenimiento exigido" #. module: maintenance_plan #: model:ir.model.fields,help:maintenance_plan.field_maintenance_plan__duration msgid "Maintenance duration in hours" -msgstr "" +msgstr "Duración del mantenimiento en horas" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__maintenance_kind_id #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_request__maintenance_kind_id msgid "Maintenance kind" -msgstr "" +msgstr "Tipo de mantenimiento" #. module: maintenance_plan #: sql_constraint:maintenance.kind:0 msgid "Maintenance kind name already exists." -msgstr "" +msgstr "Ya existe ese nombre de tipo de mantenimiento" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_equipment__maintenance_plan_ids msgid "Maintenance plan" -msgstr "" +msgstr "Plan de mantenimiento" #. module: maintenance_plan #: model:maintenance.kind,name:maintenance_plan.maintenance_kind_monthly msgid "Monthly" -msgstr "" +msgstr "Mensual" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_kind__name msgid "Name" -msgstr "" +msgstr "Nombre" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__next_maintenance_date msgid "Next maintenance date" -msgstr "" +msgstr "Próximo mantenimiento" #. module: maintenance_plan #: model:ir.model.fields,field_description:maintenance_plan.field_maintenance_plan__period msgid "Period" -msgstr "" +msgstr "Periodo" #. module: maintenance_plan #: code:addons/maintenance_plan/models/maintenance.py:151 #, python-format msgid "Preventive Maintenance (%s) - %s" -msgstr "" +msgstr "Mantenimiento preventivo (%s) - %s" #. module: maintenance_plan #: code:addons/maintenance_plan/models/maintenance.py:116 #, python-format msgid "The maintenance plan %s of equipment %s has generated a request which is not done yet. You should either set the request as done, remove its maintenance kind or delete it first." msgstr "" +"El plan de mantenimiento %s del equipo %s ha generado una petición que no ha " +"sido hecha todavía. Se deberían marcar la petición como hecha, borrar su " +"tipo de mantenimiento o eliminarlo primero" #. module: maintenance_plan #: model:maintenance.kind,name:maintenance_plan.maintenance_kind_weekly msgid "Weekly" -msgstr "" +msgstr "Semanal" #. module: maintenance_plan #: sql_constraint:maintenance.plan:0 msgid "You cannot define multiple times the same maintenance kind on an equipment maintenance plan." msgstr "" +"No se pueden definir varias veces el mismo tipo de mantenimiento en el plan " +"de mantenimiento de un equipo" #. module: maintenance_plan #: code:addons/maintenance_plan/hooks.py:31 #, python-format msgid "You have multiple preventive maintenance requests on equipment %s next action date (%s). Please leave only one preventive request on the date of equipment's next action to install the module." msgstr "" +"Hay varias peticiones de mantenimiento preventivo en el equipo %s, próxima " +"fecha de acción (%s). Por favor, deja solo una petición de preventivo en la " +"fecha de la próxima acción del equipo para poder instalar el módulo" diff --git a/maintenance_plan/static/description/index.html b/maintenance_plan/static/description/index.html index e3db0f28b..15727fa75 100644 --- a/maintenance_plan/static/description/index.html +++ b/maintenance_plan/static/description/index.html @@ -3,7 +3,7 @@ - + Maintenance Plan