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

+
This module extends the functionality of Odoo Maintenance module by allowing
+an equipment to have different preventive maintenance kinds.
+
Table of contents
+
+
+
+
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.
+
+
+
+
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 !
+
+
+
+
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.
+
+
+
+
+
+
+
+
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.
+
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. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-

+

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