Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][IMP] maintenance_project: Remove the Project > Administrator permission dependency #424

Merged
merged 4 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion maintenance_project/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Maintenance Projects

This module extends the functionality of Odoo Maintenance module adding this features:

- Adds a project to an equipment. The project can be automatically created from the equipment definition.
- Adds a project to an equipment. You can link an existing project or create a new one (with the Create project button) after creating the equipment.
- Adds project and task to a maintenance request. The default project for a request will be the equipment one, including the preventive requests periodically created.

This is is a technical addon to allow timesheet assignment to a maintenance request.
Expand Down
1 change: 0 additions & 1 deletion maintenance_project/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"website": "https://github.com/OCA/maintenance",
"depends": ["base_maintenance", "project"],
"data": [
"security/maintenance_project_security.xml",
"views/maintenance_equipment_views.xml",
"views/maintenance_request_views.xml",
"views/project_project_views.xml",
Expand Down
8 changes: 5 additions & 3 deletions maintenance_project/data/demo_maintenance_project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
<field name="assign_date" eval="time.strftime('%Y-%m-10')" />
<field name="serial_no">S/N 1</field>
<field name="model">MODEL1</field>
<field name="create_project_from_equipment" eval="False" />
<field name="project_id" ref="maintenance_project.project_project_1" />
</record>
<record id="equipment_2" model="maintenance.equipment">
Expand All @@ -36,7 +35,6 @@
<field name="assign_date" eval="time.strftime('%Y-%m-10')" />
<field name="serial_no">S/N 2</field>
<field name="model">MODEL2</field>
<field name="create_project_from_equipment" eval="False" />
<field name="project_id" ref="maintenance_project.project_project_1" />
<field name="period" eval="30" />
<field name="maintenance_duration" eval="2" />
Expand All @@ -53,6 +51,10 @@
<field name="assign_date" eval="time.strftime('%Y-%m-10')" />
<field name="serial_no">S/N 3</field>
<field name="model">MODEL3</field>
<field name="create_project_from_equipment" eval="True" />
</record>
<function
model="maintenance.equipment"
name="action_create_project"
eval="[[ref('equipment_3')]]"
/>
</odoo>
24 changes: 10 additions & 14 deletions maintenance_project/models/maintenance_equipment.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
# Copyright 2019 Solvos Consultoría Informática (<http://www.solvos.es>)
# Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import api, fields, models
from odoo import fields, models


class MaintenanceEquipment(models.Model):
_inherit = "maintenance.equipment"

project_id = fields.Many2one(comodel_name="project.project", ondelete="restrict")
create_project_from_equipment = fields.Boolean(default=True)
preventive_default_task_id = fields.Many2one(
string="Default Task", comodel_name="project.task"
)

@api.model_create_multi
def create(self, vals_list):
project_obj = self.env["project.project"]
for values in vals_list:
if values.get("create_project_from_equipment"):
new_project = project_obj.create(
self._prepare_project_from_equipment_values(values)
)
values["project_id"] = new_project.id
return super().create(vals_list)
def action_create_project(self):
self.ensure_one()
if not self.project_id:
self.project_id = self.env["project.project"].create(
self._prepare_project_from_equipment_values()
)

def _prepare_project_from_equipment_values(self, values):
def _prepare_project_from_equipment_values(self):
"""
Default project data creation hook
"""
return {"name": values.get("name")}
return {"name": self.name}
2 changes: 1 addition & 1 deletion maintenance_project/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
This module extends the functionality of Odoo Maintenance module adding this features:

- Adds a project to an equipment. The project can be automatically created from the equipment definition.
- Adds a project to an equipment. You can link an existing project or create a new one (with the Create project button) after creating the equipment.
- Adds project and task to a maintenance request. The default project for a request will be the equipment one, including the preventive requests periodically created.

This is is a technical addon to allow timesheet assignment to a maintenance request.
6 changes: 0 additions & 6 deletions maintenance_project/security/maintenance_project_security.xml

This file was deleted.

3 changes: 1 addition & 2 deletions maintenance_project/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
Expand Down Expand Up @@ -372,7 +371,7 @@ <h1 class="title">Maintenance Projects</h1>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/maintenance/tree/16.0/maintenance_project"><img alt="OCA/maintenance" src="https://img.shields.io/badge/github-OCA%2Fmaintenance-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/maintenance-16-0/maintenance-16-0-maintenance_project"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/maintenance&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module extends the functionality of Odoo Maintenance module adding this features:</p>
<ul class="simple">
<li>Adds a project to an equipment. The project can be automatically created from the equipment definition.</li>
<li>Adds a project to an equipment. You can link an existing project or create a new one (with the Create project button) after creating the equipment.</li>
<li>Adds project and task to a maintenance request. The default project for a request will be the equipment one, including the preventive requests periodically created.</li>
</ul>
<p>This is is a technical addon to allow timesheet assignment to a maintenance request.</p>
Expand Down
90 changes: 57 additions & 33 deletions maintenance_project/tests/test_maintenance_project.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
# Copyright 2019 Solvos Consultor??a Inform??tica (<http://www.solvos.es>)
# Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

import odoo.tests.common as test_common
from odoo.tests import Form, new_test_user
from odoo.tests.common import users

from odoo.addons.base.tests.common import BaseCommon

class TestMaintenanceProject(test_common.TransactionCase):

class TestMaintenanceProject(BaseCommon):
@classmethod
def setUpClass(cls):
super(TestMaintenanceProject, cls).setUpClass()

super().setUpClass()
cls.cron = cls.env.ref("maintenance.maintenance_requests_cron")
cls.project1 = cls.env["project.project"].create({"name": "My project"})
cls.project_demo1 = cls.env.ref("maintenance_project.project_project_1")

cls.project_demo = cls.env.ref("maintenance_project.project_project_1")
new_test_user(
cls.env,
login="test-user",
groups="maintenance.group_equipment_manager,project.group_project_user",
)
new_test_user(
cls.env,
login="test-project_manager-user",
groups="maintenance.group_equipment_manager,project.group_project_manager",
)
cls.equipment1 = cls.env["maintenance.equipment"].create(
{
"name": "My equipment",
"create_project_from_equipment": True,
"maintenance_team_id": cls.env.ref(
"maintenance.equipment_team_metrology"
).id,
Expand All @@ -27,50 +38,64 @@ def setUpClass(cls):
cls.equipment2 = cls.env["maintenance.equipment"].create(
{
"name": "My equipment without project",
"create_project_from_equipment": False,
}
)
cls.equipment3 = cls.env["maintenance.equipment"].create(
{
"name": "My equipment with related project",
"create_project_from_equipment": False,
"project_id": cls.project1.id,
}
)
cls.equipment_demo = cls.env.ref("maintenance_project.equipment_3")

cls.equipment_demo1 = cls.env.ref("maintenance_project.equipment_1")
cls.equipment_demo2 = cls.env.ref("maintenance_project.equipment_2")
cls.equipment_demo3 = cls.env.ref("maintenance_project.equipment_3")

def test_maintenance_equipment_project(self):
self.assertEqual(self.equipment1.name, self.equipment1.project_id.name)
def test_maintenance_equipment_project_misc(self):
self.assertFalse(self.equipment1.project_id)
self.assertFalse(self.equipment2.project_id)
self.assertEqual(self.equipment3.project_id, self.project1)
self.assertEqual(
self.equipment_demo3.name, self.equipment_demo3.project_id.name
self.assertEqual(self.equipment_demo.name, self.equipment_demo.project_id.name)

@users("test-project_manager-user")
def test_maintenance_equipment_project_admin(self):
equipment_a = self.env["maintenance.equipment"].create(
{
"name": "Test equipment A",
}
)
self.assertFalse(equipment_a.project_id)
equipment_a.action_create_project()
self.assertTrue(equipment_a.project_id)
self.assertEqual(equipment_a.name, equipment_a.project_id.name)
equipment_b = self.env["maintenance.equipment"].create(
{
"name": "Test equipment b",
"project_id": self.project1.id,
}
)
self.assertEqual(equipment_b.project_id, self.project1)
equipment_b.action_create_project()
self.assertEqual(equipment_b.project_id, self.project1)

def test_project_equipment_count(self):
self.equipment1.action_create_project()
self.assertEqual(self.project1.equipment_count, 1)
self.assertEqual(self.equipment1.project_id.equipment_count, 1)
self.assertEqual(self.project_demo1.equipment_count, 2)
self.assertEqual(self.equipment_demo3.project_id.equipment_count, 1)
self.assertEqual(self.project_demo.equipment_count, 2)
self.assertEqual(self.equipment_demo.project_id.equipment_count, 1)

def test_request_onchange_equipment(self):
req1 = self.env["maintenance.request"].new({"name": "My test request #1"})
self.assertFalse(req1.project_id)
req1.equipment_id = self.equipment1
req1.onchange_equipment_id()
self.assertEqual(req1.project_id, self.equipment1.project_id)

req2 = self.env["maintenance.request"].new({"name": "My test request #2"})
req2.equipment_id = self.equipment2
req2.onchange_equipment_id()
self.assertFalse(req2.project_id)
@users("test-user")
def test_request_equipment(self):
request_form_1 = Form(self.env["maintenance.request"])
request_form_1.name = "My test request #1"
self.assertFalse(request_form_1.project_id)
request_form_1.equipment_id = self.equipment1
self.assertEqual(request_form_1.project_id, self.equipment1.project_id)
request_form_2 = Form(self.env["maintenance.request"])
request_form_2.name = "My test request #2"
request_form_2.equipment_id = self.equipment2
self.assertFalse(request_form_2.project_id)

def test_generate_requests(self):
self.cron.method_direct_trigger()

generated_requests = self.env["maintenance.request"].search(
[("project_id", "!=", False)]
)
Expand All @@ -79,12 +104,11 @@ def test_generate_requests(self):
self.assertEqual(req.task_id, req.equipment_id.preventive_default_task_id)
self.assertEqual(req.project_id.maintenance_request_count, 1)

def test_action_views(self):
def test_project_action_views(self):
act1 = self.project1.action_view_equipment_ids()
self.assertEqual(act1["domain"][0][2], self.project1.id)
self.assertEqual(act1["context"]["default_project_id"], self.project1.id)
self.assertFalse(act1["context"]["default_create_project_from_equipment"])

act2 = self.project1.action_view_maintenance_request_ids()
self.assertEqual(act2["domain"][0][2], self.project1.id)
self.assertEqual(act2["context"]["default_project_id"], self.project1.id)
38 changes: 26 additions & 12 deletions maintenance_project/views/maintenance_equipment_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<field name="inherit_id" ref="maintenance.hr_equipment_view_search" />
<field name="arch" type="xml">
<xpath expr="//field[@name='owner_user_id']" position="after">
<field name="project_id" />
<field name="project_id" groups="project.group_project_user" />
</xpath>
</field>
</record>
Expand All @@ -14,7 +14,7 @@
<field name="inherit_id" ref="maintenance.hr_equipment_view_tree" />
<field name="arch" type="xml">
<xpath expr="//field[@name='category_id']" position="after">
<field name="project_id" />
<field name="project_id" groups="project.group_project_user" />
</xpath>
</field>
</record>
Expand All @@ -23,10 +23,13 @@
<field name="inherit_id" ref="maintenance.hr_equipment_view_kanban" />
<field name="arch" type="xml">
<xpath expr="//field[@name='activity_state']" position="after">
<field name="project_id" />
<field name="project_id" groups="project.group_project_user" />
</xpath>
<xpath expr="//div[hasclass('o_kanban_record_body')]" position="inside">
<div t-if="record.project_id.raw_value">
<div
t-if="record.project_id.raw_value"
groups="project.group_project_user"
>
<small>Project: <t t-raw="record.project_id.value" /></small>
</div>
</xpath>
Expand All @@ -37,21 +40,32 @@
<field name="inherit_id" ref="maintenance.hr_equipment_view_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='location']" position="after">
<field
name="create_project_from_equipment"
attrs="{'invisible': [('id', '!=', False)]}"
/>
<field
name="project_id"
attrs="{'invisible': [('create_project_from_equipment', '=', True), ('id', '=', False)]}"
/>
<field name="project_id" invisible="1" />
victoralmau marked this conversation as resolved.
Show resolved Hide resolved
<label for="project_id" groups="project.group_project_user" />
<div>
<field
name="project_id"
groups="project.group_project_user"
class="oe_inline"
/>
<button
name="action_create_project"
groups="project.group_project_manager"
type="object"
class="oe_link"
attrs="{'invisible': ['|', ('id', '=', False),('project_id', '!=', False)]}"
>
<span class="fa fa-plus" /><span> Create project</span>
</button>
</div>
</xpath>
<xpath expr="//group[@name='maintenance']" position="after">
<group name="project_task">
<field
name="preventive_default_task_id"
domain="[('project_id', '=', project_id)]"
context="{'default_project_id': project_id}"
groups="project.group_project_user"
/>
</group>
</xpath>
Expand Down
16 changes: 11 additions & 5 deletions maintenance_project/views/maintenance_request_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_search" />
<field name="arch" type="xml">
<xpath expr="//field[@name='maintenance_team_id']" position="after">
<field name="project_id" />
<field name="project_id" groups="project.group_project_user" />
</xpath>
</field>
</record>
Expand All @@ -14,7 +14,7 @@
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_tree" />
<field name="arch" type="xml">
<xpath expr="//field[@name='category_id']" position="after">
<field name="project_id" />
<field name="project_id" groups="project.group_project_user" />
</xpath>
</field>
</record>
Expand All @@ -23,10 +23,13 @@
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_kanban" />
<field name="arch" type="xml">
<xpath expr="//field[@name='activity_state']" position="after">
<field name="project_id" />
<field name="project_id" groups="project.group_project_user" />
</xpath>
<xpath expr="//div[hasclass('o_kanban_record_body')]" position="inside">
<div t-if="record.project_id.raw_value">
<div
t-if="record.project_id.raw_value"
groups="project.group_project_user"
>
<small>Project: <t t-raw="record.project_id.value" /></small>
</div>
</xpath>
Expand All @@ -37,11 +40,14 @@
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='priority']" position="after">
<field name="project_id" />
<field name="project_id" invisible="1" />
<field name="project_id" groups="project.group_project_user" />
<field name="task_id" invisible="1" />
<field
name="task_id"
domain="[('project_id', '=', project_id)]"
context="{'default_project_id': project_id}"
groups="project.group_project_user"
/>
</xpath>
</field>
Expand Down
Loading
Loading