mirror of
https://github.com/bringout/oca-project.git
synced 2026-04-18 15:42:07 +02:00
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
98 lines
3.8 KiB
Python
98 lines
3.8 KiB
Python
# Copyright 2023 Moduon Team S.L.
|
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)
|
|
|
|
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class ProjectProject(models.Model):
|
|
_inherit = "project.project"
|
|
_sql_constraints = [
|
|
# Ensure compatibility with other modules that always expect a value in name
|
|
("name_required", "CHECK(name IS NOT NULL)", "Project name is required"),
|
|
(
|
|
"sequence_code_unique",
|
|
"UNIQUE(sequence_code)",
|
|
"Sequence code must be unique",
|
|
),
|
|
]
|
|
|
|
sequence_code = fields.Char(
|
|
copy=False,
|
|
readonly=True,
|
|
)
|
|
name = fields.Char(
|
|
# We actually require it with the SQL constraint, but it is disabled
|
|
# here to let users create/write projects without name, and let this module
|
|
# add a default name if needed
|
|
required=False,
|
|
)
|
|
|
|
def _sync_analytic_account_name(self):
|
|
"""Set analytic account name equal to project's display name."""
|
|
for rec in self:
|
|
if not rec.analytic_account_id:
|
|
continue
|
|
rec.analytic_account_id.name = rec.display_name
|
|
|
|
def name_get(self):
|
|
"""Prefix name with sequence code if they are different."""
|
|
old_result = super().name_get()
|
|
result = []
|
|
sequence_pattern = (
|
|
self.env["ir.config_parameter"]
|
|
.sudo()
|
|
.get_param(
|
|
"project_sequence.display_name_pattern",
|
|
default="%(sequence_code)s - %(name)s",
|
|
)
|
|
)
|
|
for id_, name in old_result:
|
|
project = self.browse(id_)
|
|
if project.sequence_code and project.sequence_code != name:
|
|
name = sequence_pattern % {
|
|
"name": name,
|
|
"sequence_code": project.sequence_code,
|
|
}
|
|
result.append((id_, name))
|
|
return result
|
|
|
|
@api.model
|
|
def name_search(self, name="", args=None, operator="ilike", limit=100):
|
|
"""Allow searching by sequence code by default."""
|
|
# Do not add any domain when user just clicked on search widget
|
|
if not (name == "" and operator == "ilike"):
|
|
# The dangling | is needed to combine with the domain added by super()
|
|
args = (args or []) + ["|", ("sequence_code", operator, name)]
|
|
return super().name_search(name, args, operator, limit)
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
"""Apply sequence code and a default name if not set."""
|
|
# It is important to set sequence_code before calling super() because
|
|
# other modules such as hr_timesheet expect the name to always have a value
|
|
for vals in vals_list:
|
|
if not vals.get("sequence_code", False):
|
|
vals["sequence_code"] = self.env["ir.sequence"].next_by_code(
|
|
"project.sequence"
|
|
)
|
|
if not vals.get("name"):
|
|
vals["name"] = vals["sequence_code"]
|
|
res = super().create(vals_list)
|
|
# The analytic account is created with just the project name, but
|
|
# it is more useful to let it contain the project sequence too
|
|
res._sync_analytic_account_name()
|
|
return res
|
|
|
|
def write(self, vals):
|
|
"""Sync name and analytic account name when name is changed."""
|
|
# If name isn't changing, nothing special to do
|
|
if "name" not in vals and "sequence_name" not in vals:
|
|
return super().write(vals)
|
|
# When changing name, we need to update the analytic account name too
|
|
for one in self:
|
|
sequence_code = vals.get("sequence_code", one.sequence_code)
|
|
name = vals.get("name") or sequence_code
|
|
super().write(dict(vals, name=name))
|
|
self._sync_analytic_account_name()
|
|
return True
|