Wipe addons/: full reset for clean re-upload
This commit is contained in:
@@ -1,243 +0,0 @@
|
||||
# Copyright (C) 2024 Cetmix OÜ
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
from .cx_tower_file import TEMPLATE_FILE_FIELD_MAPPING
|
||||
|
||||
|
||||
class CxTowerFileTemplate(models.Model):
|
||||
"""File template to manage multiple files at once"""
|
||||
|
||||
_name = "cx.tower.file.template"
|
||||
_inherit = [
|
||||
"cx.tower.reference.mixin",
|
||||
"cx.tower.key.mixin",
|
||||
"cx.tower.template.mixin",
|
||||
"cx.tower.access.role.mixin",
|
||||
"cx.tower.tag.mixin",
|
||||
]
|
||||
_description = "Cetmix Tower File Template"
|
||||
_order = "name"
|
||||
|
||||
active = fields.Boolean(default=True)
|
||||
file_name = fields.Char(
|
||||
help="Default full file name with file type for example: test.txt",
|
||||
)
|
||||
code = fields.Text(string="File content")
|
||||
server_dir = fields.Char(string="Directory on server")
|
||||
file_ids = fields.One2many("cx.tower.file", "template_id")
|
||||
file_count = fields.Integer(
|
||||
"File(s)",
|
||||
compute="_compute_file_count",
|
||||
)
|
||||
tag_ids = fields.Many2many(
|
||||
relation="cx_tower_file_template_tag_rel",
|
||||
column1="file_template_id",
|
||||
column2="tag_id",
|
||||
)
|
||||
note = fields.Text(help="This field is used to put some notes regarding template.")
|
||||
keep_when_deleted = fields.Boolean(
|
||||
help="File will be kept on server when deleted in Tower",
|
||||
)
|
||||
auto_sync = fields.Boolean(
|
||||
help="If enabled, files created from this template will have "
|
||||
"Auto Sync enabled by default. Used only with 'Tower' source.",
|
||||
)
|
||||
file_type = fields.Selection(
|
||||
selection=lambda self: self.env["cx.tower.file"]._selection_file_type(),
|
||||
default=lambda self: self.env["cx.tower.file"]._default_file_type(),
|
||||
required=True,
|
||||
)
|
||||
source = fields.Selection(
|
||||
[
|
||||
("tower", "Tower"),
|
||||
("server", "Server"),
|
||||
],
|
||||
required=True,
|
||||
default="tower",
|
||||
)
|
||||
variable_ids = fields.Many2many(
|
||||
comodel_name="cx.tower.variable",
|
||||
relation="cx_tower_file_template_variable_rel",
|
||||
column1="file_template_id",
|
||||
column2="variable_id",
|
||||
)
|
||||
|
||||
# ---- Access. Add relation for mixin fields
|
||||
user_ids = fields.Many2many(
|
||||
relation="cx_tower_file_template_user_rel",
|
||||
domain=lambda self: [
|
||||
("groups_id", "in", [self.env.ref("cetmix_tower_server.group_manager").id])
|
||||
],
|
||||
)
|
||||
manager_ids = fields.Many2many(
|
||||
relation="cx_tower_file_template_manager_rel",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _get_depends_fields(cls):
|
||||
"""
|
||||
Define dependent fields for computing
|
||||
`variable_ids` in file template-related models.
|
||||
|
||||
This implementation specifies that the fields `code`, `server_dir`,
|
||||
and `file_name` are used to compute the
|
||||
variables associated with a file template.
|
||||
|
||||
Returns:
|
||||
list: A list of field names (str) representing the dependencies.
|
||||
|
||||
Example:
|
||||
The following fields trigger recomputation
|
||||
of `variable_ids`:
|
||||
- `code`: The template content for the file.
|
||||
- `server_dir`: The target directory on the
|
||||
server where the template is applied.
|
||||
- `file_name`: The name of the generated file.
|
||||
"""
|
||||
return ["code", "server_dir", "file_name"]
|
||||
|
||||
# -- Computes
|
||||
@api.depends("file_ids")
|
||||
def _compute_file_count(self):
|
||||
"""
|
||||
Compute total template files
|
||||
"""
|
||||
for template in self:
|
||||
template.file_count = len(template.file_ids)
|
||||
|
||||
# -- Create/Write/Unlink
|
||||
def write(self, vals):
|
||||
"""
|
||||
Override to update files related with the templates
|
||||
"""
|
||||
result = super().write(vals)
|
||||
if any(field_ in vals for field_ in TEMPLATE_FILE_FIELD_MAPPING):
|
||||
for file in self.mapped("file_ids"):
|
||||
file.write(file._get_file_values_from_related_template())
|
||||
return result
|
||||
|
||||
# -- Actions
|
||||
def action_open_files(self):
|
||||
"""
|
||||
Open current template files
|
||||
"""
|
||||
action = self.env["ir.actions.actions"]._for_xml_id(
|
||||
"cetmix_tower_server.cx_tower_file_action"
|
||||
)
|
||||
action["domain"] = [("id", "in", self.file_ids.ids)]
|
||||
return action
|
||||
|
||||
# -- Business logic
|
||||
def create_file(
|
||||
self, server, server_dir="", if_file_exists="raise", jet_template=None, jet=None
|
||||
):
|
||||
"""
|
||||
Create a new file using the current template for the selected server.
|
||||
If the same file already exists, just ignore it or raise an error based on the
|
||||
parameter.
|
||||
|
||||
:param server: recordset
|
||||
The server (cx.tower.server) on which the file should be created. This is a
|
||||
required parameter.
|
||||
:param if_file_exists: str, optional
|
||||
Defines the behavior if the file already exists on the server.
|
||||
:param server_dir: str, optional
|
||||
The directory on the server where the file should be created. If not set,
|
||||
the server_dir field of the template will be used.
|
||||
:param jet_template: cx.tower.jet.template, optional
|
||||
The jet template to use for creating the new file.
|
||||
:param jet: cx.tower.jet, optional
|
||||
The jet to use for creating the new file.
|
||||
|
||||
:return: cx.tower.file
|
||||
Returns the newly created file record (cx.tower.file) if the file was
|
||||
created successfully or if_file_exists is set to "overwrite".
|
||||
Returns the existing file record if the file already exists
|
||||
and if_file_exists is set to "skip".
|
||||
|
||||
:raises ValidationError:
|
||||
If the file already exists on the server if_file_exists is set to "raise".
|
||||
"""
|
||||
self.ensure_one()
|
||||
# Explicit guard against invalid behavior values
|
||||
valid_behaviors = {"skip", "raise", "overwrite"}
|
||||
if if_file_exists not in valid_behaviors:
|
||||
raise ValidationError(
|
||||
f"Invalid if_file_exists value: {if_file_exists}. "
|
||||
f"Expected one of {valid_behaviors}."
|
||||
)
|
||||
file_model = self.env["cx.tower.file"]
|
||||
existing_files = file_model.search(
|
||||
[
|
||||
("server_id", "=", server.id),
|
||||
("source", "=", self.source),
|
||||
],
|
||||
order="id DESC",
|
||||
)
|
||||
existing_dir = server_dir or self.server_dir
|
||||
|
||||
# Render the server directory and file name from the template
|
||||
variables = list(
|
||||
set(
|
||||
self.get_variables_from_code(self.file_name)
|
||||
+ self.get_variables_from_code(existing_dir)
|
||||
)
|
||||
)
|
||||
var_vals = self.env["cx.tower.variable"]._get_variable_values_by_references(
|
||||
variables,
|
||||
server=server,
|
||||
jet_template=jet_template,
|
||||
jet=jet,
|
||||
)
|
||||
|
||||
unrendered_path = (
|
||||
f"{existing_dir}/{self.file_name}" if existing_dir else self.file_name
|
||||
)
|
||||
rendered_path = self.render_code_custom(unrendered_path, **var_vals)
|
||||
|
||||
# Filter existing files by rendered path
|
||||
existing_files = existing_files.filtered(
|
||||
lambda f: f.full_server_path == rendered_path
|
||||
)
|
||||
|
||||
# Filter existing files by template if it exists, otherwise take the first one
|
||||
existing_file = (
|
||||
existing_files.filtered(lambda f: f.template_id == self)[:1]
|
||||
or existing_files[:1]
|
||||
)
|
||||
|
||||
if existing_file and if_file_exists == "skip":
|
||||
return existing_file.with_context(file_creation_skipped=True)
|
||||
|
||||
if existing_file and if_file_exists == "raise":
|
||||
raise ValidationError(_("File already exists on server."))
|
||||
|
||||
if existing_file and if_file_exists == "overwrite":
|
||||
existing_file.with_context(is_custom_server_dir=True).write(
|
||||
{
|
||||
"template_id": self.id, # pylint: disable=no-member
|
||||
"jet_template_id": jet_template.id if jet_template else None,
|
||||
"jet_id": jet.id if jet else None,
|
||||
}
|
||||
)
|
||||
return existing_file
|
||||
|
||||
vals = {
|
||||
"name": self.file_name,
|
||||
"server_id": server.id,
|
||||
"server_dir": existing_dir,
|
||||
"template_id": self.id, # pylint: disable=no-member
|
||||
"code": self.code,
|
||||
"file_type": self.file_type,
|
||||
"source": self.source,
|
||||
"auto_sync": self.auto_sync,
|
||||
"jet_template_id": jet_template.id if jet_template else None,
|
||||
"jet_id": jet.id if jet else None,
|
||||
}
|
||||
|
||||
new_file = file_model.with_context(is_custom_server_dir=True).create(vals)
|
||||
# Return new_file if no file exists
|
||||
return new_file
|
||||
Reference in New Issue
Block a user