mirror of
https://github.com/bringout/oca-workflow-process.git
synced 2026-04-18 16:52:03 +02:00
208 lines
6.7 KiB
Python
208 lines
6.7 KiB
Python
# Copyright 2017 - 2018 Modoolar <info@modoolar.com>
|
|
# License LGPLv3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.en.html).
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.tools import config
|
|
|
|
|
|
class Project(models.Model):
|
|
_inherit = "project.project"
|
|
_rec_names_search = ["key", "name", "id"]
|
|
|
|
task_key_sequence_id = fields.Many2one(
|
|
comodel_name="ir.sequence", string="Key Sequence", ondelete="restrict"
|
|
)
|
|
|
|
key = fields.Char(size=10, required=False, index=True, copy=False)
|
|
|
|
_sql_constraints = [
|
|
("project_key_unique", "UNIQUE(key)", "Project key must be unique")
|
|
]
|
|
|
|
@api.onchange("name")
|
|
def _onchange_project_name(self):
|
|
for rec in self:
|
|
if rec.key:
|
|
continue
|
|
|
|
if rec.name:
|
|
rec.key = self.generate_project_key(rec.name)
|
|
else:
|
|
rec.key = ""
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
for vals in vals_list:
|
|
key = vals.get("key", False)
|
|
if not key:
|
|
vals["key"] = self.generate_project_key(vals["name"])
|
|
|
|
# Tasks must be created after the project.
|
|
if vals.get("task_ids", False):
|
|
task_vals = vals.pop("task_ids")
|
|
else:
|
|
task_vals = []
|
|
|
|
# The key sequences to create stories and tasks with keys, created with
|
|
# a project, must be linked to the project company to avoid security
|
|
# issues.
|
|
# Propagate the company ID, using the context key, to fill the
|
|
# sequences company.
|
|
company_id = vals.get("company_id")
|
|
if company_id:
|
|
self = self.with_context(project_sequence_company=company_id)
|
|
|
|
new_project = super(Project, self).create(vals)
|
|
new_project.create_sequence()
|
|
|
|
# Tasks must be created after the project.
|
|
if task_vals:
|
|
new_project.write({"task_ids": task_vals})
|
|
|
|
return new_project
|
|
|
|
def write(self, values):
|
|
update_key = False
|
|
|
|
if "key" in values:
|
|
key = values["key"]
|
|
update_key = self.key != key
|
|
|
|
res = super(Project, self).write(values)
|
|
|
|
if update_key:
|
|
# Here we don't expect to have more than one record
|
|
# because we can not have multiple projects with the same KEY.
|
|
self.update_sequence()
|
|
self._update_task_keys()
|
|
|
|
return res
|
|
|
|
def unlink(self):
|
|
for project in self:
|
|
sequence = project.task_key_sequence_id
|
|
project.task_key_sequence_id = False
|
|
sequence.sudo().unlink()
|
|
return super(Project, self).unlink()
|
|
|
|
def create_sequence(self):
|
|
"""
|
|
This method creates ir.sequence fot the current project
|
|
:return: Returns create sequence
|
|
"""
|
|
self.ensure_one()
|
|
sequence_data = self._prepare_sequence_data()
|
|
sequence = self.env["ir.sequence"].sudo().create(sequence_data)
|
|
self.write({"task_key_sequence_id": sequence.id})
|
|
return sequence
|
|
|
|
def update_sequence(self):
|
|
"""
|
|
This method updates existing task sequence
|
|
:return:
|
|
"""
|
|
sequence_data = self._prepare_sequence_data(init=False)
|
|
self.task_key_sequence_id.sudo().write(sequence_data)
|
|
|
|
def _prepare_sequence_data(self, init=True):
|
|
"""
|
|
This method prepares data for create/update_sequence methods
|
|
:param init: Set to False in case you don't want to set initial values
|
|
for number_increment and number_next_actual
|
|
"""
|
|
values = {
|
|
"name": "{} {}".format(_("Project task sequence for project"), self.name),
|
|
"implementation": "standard",
|
|
"code": "project.task.key.{}".format(self.id),
|
|
"prefix": "{}-".format(self.key),
|
|
"use_date_range": False,
|
|
}
|
|
|
|
# The key sequences to create stories and tasks with keys, created with
|
|
# a project, must be linked to the project company to avoid security
|
|
# issues.
|
|
company_id = self.env.context.get("project_sequence_company")
|
|
if company_id:
|
|
values["company_id"] = company_id
|
|
|
|
if init:
|
|
values.update(dict(number_increment=1, number_next_actual=1))
|
|
|
|
return values
|
|
|
|
def get_next_task_key(self):
|
|
test_project_key = self.env.context.get("test_project_key")
|
|
if (config["test_enable"] and not test_project_key) or (
|
|
config["demo"].get("project_key") and not test_project_key
|
|
):
|
|
return False
|
|
return self.sudo().task_key_sequence_id.next_by_id()
|
|
|
|
def generate_project_key(self, text):
|
|
test_project_key = self.env.context.get("test_project_key")
|
|
if (config["test_enable"] and not test_project_key) or (
|
|
config["demo"].get("project_key") and not test_project_key
|
|
):
|
|
return False
|
|
|
|
if not text:
|
|
return ""
|
|
|
|
data = text.split(" ")
|
|
if len(data) == 1:
|
|
return self._generate_project_unique_key(data[0][:3].upper())
|
|
|
|
key = []
|
|
for item in data:
|
|
key.append(item[:1].upper())
|
|
return self._generate_project_unique_key("".join(key))
|
|
|
|
def _generate_project_unique_key(self, text):
|
|
self_context = self.with_context(active_test=False)
|
|
res = text
|
|
unique_key = False
|
|
counter = 0
|
|
while not unique_key:
|
|
if counter != 0:
|
|
res = "%s%s" % (text, counter)
|
|
unique_key = not bool(self_context.search([("key", "=", res)]))
|
|
counter += 1
|
|
|
|
return res
|
|
|
|
def _update_task_keys(self):
|
|
"""
|
|
This method will update task keys of the current project.
|
|
"""
|
|
self.ensure_one()
|
|
self.flush_model()
|
|
reindex_query = """
|
|
UPDATE project_task
|
|
SET key = x.key
|
|
FROM (
|
|
SELECT t.id, p.key || '-' || split_part(t.key, '-', 2) AS key
|
|
FROM project_task t
|
|
INNER JOIN project_project p ON t.project_id = p.id
|
|
WHERE t.project_id = %s
|
|
) AS x
|
|
WHERE project_task.id = x.id;
|
|
"""
|
|
|
|
self.env.cr.execute(reindex_query, (self.id,))
|
|
self.task_ids.invalidate_model(["key"])
|
|
|
|
@api.model
|
|
def _set_default_project_key(self):
|
|
"""
|
|
This method will be called from the post_init hook in order to set
|
|
default values on project.project and
|
|
project.task, so we leave those tables nice and clean after module
|
|
installation.
|
|
:return:
|
|
"""
|
|
for project in self.search([("key", "=", False)]):
|
|
project.key = self.generate_project_key(project.name)
|
|
project.create_sequence()
|
|
|
|
for task in project.task_ids:
|
|
task.key = project.get_next_task_key()
|