mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-22 00:32:06 +02:00
200 lines
7.9 KiB
Python
200 lines
7.9 KiB
Python
# Copyright 2017 Camptocamp SA
|
|
# Copyright 2019-20 ForgeFlow S.L. (https://www.forgeflow.com)
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class MaintenanceEquipment(models.Model):
|
|
|
|
_inherit = "maintenance.equipment"
|
|
|
|
maintenance_plan_ids = fields.One2many(
|
|
string="Maintenance plan",
|
|
comodel_name="maintenance.plan",
|
|
inverse_name="equipment_id",
|
|
)
|
|
maintenance_plan_count = fields.Integer(
|
|
compute="_compute_maintenance_plan_count",
|
|
store=True,
|
|
)
|
|
search_maintenance_plan_count = fields.Integer(
|
|
compute="_compute_search_maintenance_plan_count",
|
|
string="Maintenance All Plan Count",
|
|
)
|
|
maintenance_team_required = fields.Boolean(compute="_compute_team_required")
|
|
notes = fields.Text()
|
|
|
|
@api.depends("maintenance_plan_ids", "maintenance_plan_ids.active")
|
|
def _compute_maintenance_plan_count(self):
|
|
for equipment in self:
|
|
equipment.maintenance_plan_count = len(
|
|
equipment.with_context(active_test=False).maintenance_plan_ids
|
|
)
|
|
|
|
@api.depends("maintenance_plan_ids")
|
|
def _compute_search_maintenance_plan_count(self):
|
|
for equipment in self:
|
|
equipment.search_maintenance_plan_count = (
|
|
self.env["maintenance.plan"]
|
|
.with_context(active_test=False)
|
|
.search_count([("search_equipment_id", "=", equipment.id)])
|
|
)
|
|
|
|
@api.depends("maintenance_plan_ids")
|
|
def _compute_team_required(self):
|
|
for equipment in self:
|
|
equipment.maintenance_team_required = (
|
|
len(
|
|
equipment.maintenance_plan_ids.filtered(
|
|
lambda r: not r.maintenance_team_id
|
|
)
|
|
)
|
|
>= 1
|
|
)
|
|
|
|
@api.constrains("company_id", "maintenance_plan_ids")
|
|
def _check_company_id(self):
|
|
for rec in self:
|
|
if rec.company_id and not all(
|
|
rec.company_id == p.company_id for p in rec.maintenance_plan_ids
|
|
):
|
|
raise ValidationError(
|
|
_(
|
|
"Some maintenance plan's company is incompatible with "
|
|
"the company of this equipment."
|
|
)
|
|
)
|
|
|
|
def _prepare_requests_from_plan(self, maintenance_plan, next_maintenance_date):
|
|
if self:
|
|
return self._prepare_request_from_plan(
|
|
maintenance_plan, next_maintenance_date
|
|
)
|
|
equipments = maintenance_plan._get_maintenance_equipments()
|
|
return [
|
|
equipment._prepare_request_from_plan(
|
|
maintenance_plan, next_maintenance_date
|
|
)
|
|
for equipment in equipments
|
|
]
|
|
|
|
def _prepare_request_from_plan(self, maintenance_plan, next_maintenance_date):
|
|
team_id = maintenance_plan.maintenance_team_id.id or self.maintenance_team_id.id
|
|
request_model = self.env["maintenance.request"]
|
|
if not team_id:
|
|
team_id = request_model._get_default_team_id()
|
|
|
|
description = self.name if self else maintenance_plan.name
|
|
kind = maintenance_plan.maintenance_kind_id.name or _("Unspecified kind")
|
|
name = _(
|
|
"Preventive Maintenance (%(kind)s) - %(description)s",
|
|
kind=kind,
|
|
description=description,
|
|
)
|
|
|
|
data = {
|
|
"name": name,
|
|
"request_date": next_maintenance_date,
|
|
"schedule_date": 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,
|
|
"user_id": self.technician_user_id.id,
|
|
"maintenance_team_id": team_id,
|
|
"maintenance_kind_id": maintenance_plan.maintenance_kind_id.id,
|
|
"maintenance_plan_id": maintenance_plan.id,
|
|
"duration": maintenance_plan.duration,
|
|
"note": maintenance_plan.note,
|
|
"company_id": maintenance_plan.company_id.id or self.company_id.id,
|
|
}
|
|
# This field comes from maintenance_timesheet for avoiding a glue module
|
|
if "planned_hours" in request_model._fields:
|
|
data["planned_hours"] = maintenance_plan.duration
|
|
return data
|
|
|
|
def _create_new_request(self, mtn_plan):
|
|
# Compute horizon date adding to today the planning horizon
|
|
horizon_date = fields.Date.today() + mtn_plan.get_relativedelta(
|
|
mtn_plan.maintenance_plan_horizon, mtn_plan.planning_step or "year"
|
|
)
|
|
# We check maintenance request already created and create until
|
|
# planning horizon is met
|
|
start_maintenance_date_plan = mtn_plan.start_maintenance_date
|
|
furthest_maintenance_request = self.env["maintenance.request"].search(
|
|
[
|
|
("maintenance_plan_id", "=", mtn_plan.id),
|
|
("request_date", ">=", start_maintenance_date_plan),
|
|
],
|
|
order="request_date desc",
|
|
limit=1,
|
|
)
|
|
if furthest_maintenance_request:
|
|
next_maintenance_date = (
|
|
furthest_maintenance_request.request_date
|
|
+ mtn_plan.get_relativedelta(
|
|
mtn_plan.interval, mtn_plan.interval_step or "year"
|
|
)
|
|
)
|
|
else:
|
|
next_maintenance_date = mtn_plan.next_maintenance_date
|
|
skip_notify_follower = mtn_plan.skip_notify_follower_on_requests
|
|
# Skip assigned mail + Activity mail
|
|
request_model = self.env["maintenance.request"].with_context(
|
|
mail_activity_quick_update=skip_notify_follower,
|
|
mail_auto_subscribe_no_notify=skip_notify_follower,
|
|
)
|
|
requests = request_model
|
|
# Create maintenance request until we reach planning horizon
|
|
while next_maintenance_date <= horizon_date:
|
|
if next_maintenance_date >= fields.Date.today():
|
|
vals = self._prepare_requests_from_plan(mtn_plan, next_maintenance_date)
|
|
requests |= request_model.create(vals)
|
|
next_maintenance_date = next_maintenance_date + mtn_plan.get_relativedelta(
|
|
mtn_plan.interval, mtn_plan.interval_step or "year"
|
|
)
|
|
return requests
|
|
|
|
@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"]
|
|
.sudo()
|
|
.search([("interval", ">", 0)])
|
|
.filtered(lambda x: True if not x.equipment_id else x.equipment_id.active)
|
|
):
|
|
equipment = plan.equipment_id
|
|
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)
|