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

[17.0][IMP] maintenance_project: Remove the Project > Administrator permission dependency #429

Merged
merged 4 commits into from
Sep 25, 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
5 changes: 3 additions & 2 deletions maintenance_project/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ 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.
Expand Down
3 changes: 1 addition & 2 deletions maintenance_project/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
{
"name": "Maintenance Projects",
"summary": "Adds projects to maintenance equipments and requests",
"version": "17.0.1.0.0",
"version": "17.0.2.0.0",
"author": "Odoo Community Association (OCA), Solvos",
"license": "AGPL-3",
"category": "Maintenance",
"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/demo/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="preventive_default_task_id"
Expand All @@ -51,6 +49,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>
11 changes: 11 additions & 0 deletions maintenance_project/migrations/17.0.2.0.0/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from openupgradelib import openupgrade


@openupgrade.migrate()
def migrate(env, version):
env.ref("maintenance.group_equipment_manager").write(
{"implied_ids": [(3, env.ref("project.group_project_manager").id)]}
)
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}
5 changes: 3 additions & 2 deletions maintenance_project/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
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.
Expand Down
6 changes: 0 additions & 6 deletions maintenance_project/security/maintenance_project_security.xml

This file was deleted.

16 changes: 7 additions & 9 deletions maintenance_project/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.

See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
Expand Down Expand Up @@ -275,7 +274,7 @@
margin-left: 2em ;
margin-right: 2em }

pre.code .ln { color: gray; } /* line numbers */
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
Expand All @@ -301,7 +300,7 @@
span.pre {
white-space: pre }

span.problematic, pre.problematic {
span.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -373,8 +372,9 @@ <h1 class="title">Maintenance Projects</h1>
<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>
Expand Down Expand Up @@ -418,9 +418,7 @@ <h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>
Expand Down
87 changes: 56 additions & 31 deletions maintenance_project/tests/test_maintenance_project.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
# 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().setUpClass()

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 @@ -24,46 +35,61 @@ 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)

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)
self.assertEqual(self.project_demo.equipment_count, 2)
self.assertEqual(self.equipment_demo.project_id.equipment_count, 1)

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):
req_name = "My new recurring test request"
Expand Down Expand Up @@ -95,12 +121,11 @@ def test_generate_requests(self):
my_requests = request_obj.search(domain)
self.assertEqual(len(my_requests), 2)

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)
35 changes: 26 additions & 9 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-out="record.project_id.value" /></small>
</div>
</xpath>
Expand All @@ -37,18 +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" invisible="id" />
<field
name="project_id"
invisible="create_project_from_equipment and not id"
/>
<field name="project_id" invisible="1" />
<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"
invisible="not id or project_id"
>
<span class="fa fa-plus" /><span> Create project</span>
</button>
</div>
</xpath>
<xpath expr="//group[@name='statistics']" 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
Loading
Loading