odoo-addon-dms 16.0.1.8.0.3__py3-none-any.whl → 17.0.1.0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odoo/addons/dms/README.rst +132 -78
- odoo/addons/dms/__manifest__.py +34 -16
- odoo/addons/dms/actions/file.xml +1 -3
- odoo/addons/dms/controllers/main.py +0 -34
- odoo/addons/dms/controllers/portal.py +178 -92
- odoo/addons/dms/data/onboarding_data.xml +77 -0
- odoo/addons/dms/demo/access_group.xml +3 -9
- odoo/addons/dms/i18n/de.po +13 -117
- odoo/addons/dms/i18n/dms.pot +137 -174
- odoo/addons/dms/i18n/es.po +15 -58
- odoo/addons/dms/i18n/fr.po +296 -450
- odoo/addons/dms/i18n/he_IL.po +13 -117
- odoo/addons/dms/i18n/it.po +15 -131
- odoo/addons/dms/i18n/nl.po +13 -117
- odoo/addons/dms/i18n/pt.po +13 -121
- odoo/addons/dms/i18n/pt_BR.po +28 -147
- odoo/addons/dms/i18n/ru.po +13 -117
- odoo/addons/dms/models/__init__.py +7 -1
- odoo/addons/dms/models/abstract_dms_mixin.py +1 -1
- odoo/addons/dms/models/access_groups.py +18 -11
- odoo/addons/dms/models/base.py +10 -2
- odoo/addons/dms/models/directory.py +46 -75
- odoo/addons/dms/models/{category.py → dms_category.py} +10 -42
- odoo/addons/dms/models/dms_file.py +125 -147
- odoo/addons/dms/models/dms_security_mixin.py +26 -22
- odoo/addons/dms/models/ir_attachment.py +0 -1
- odoo/addons/dms/models/ir_binary.py +19 -0
- odoo/addons/dms/models/mail_thread.py +2 -4
- odoo/addons/dms/models/mixins_thumbnail.py +13 -8
- odoo/addons/dms/models/onboarding_onboarding.py +16 -0
- odoo/addons/dms/models/onboarding_onboarding_step.py +50 -0
- odoo/addons/dms/models/res_company.py +22 -47
- odoo/addons/dms/models/res_config_settings.py +0 -1
- odoo/addons/dms/models/storage.py +4 -24
- odoo/addons/dms/models/tag.py +1 -1
- odoo/addons/dms/readme/CONFIGURE.md +59 -0
- odoo/addons/dms/readme/CONTRIBUTORS.md +14 -0
- odoo/addons/dms/readme/CREDITS.md +6 -0
- odoo/addons/dms/readme/DESCRIPTION.md +9 -0
- odoo/addons/dms/readme/INSTALL.md +4 -0
- odoo/addons/dms/readme/ROADMAP.md +19 -0
- odoo/addons/dms/readme/USAGE.md +11 -0
- odoo/addons/dms/security/security.xml +1 -0
- odoo/addons/dms/static/description/icon.png +0 -0
- odoo/addons/dms/static/description/icon.svg +4 -1
- odoo/addons/dms/static/description/index.html +133 -88
- odoo/addons/dms/static/description/portal_icon.svg +12 -0
- odoo/addons/dms/static/src/js/fields/{path_owl.esm.js → path_json/path_owl.esm.js} +22 -4
- odoo/addons/dms/static/src/js/fields/{path_owl.xml → path_json/path_owl.xml} +7 -4
- odoo/addons/dms/static/src/js/fields/preview_binary/preview_record.esm.js +47 -0
- odoo/addons/dms/static/src/js/{views/fields/binary → fields/preview_binary}/preview_record.xml +5 -4
- odoo/addons/dms/static/src/js/views/dms_file_upload.esm.js +155 -148
- odoo/addons/dms/static/src/js/views/file_kanban_controller.xml +0 -1
- odoo/addons/dms/static/src/js/views/file_kanban_record.esm.js +26 -27
- odoo/addons/dms/static/src/js/views/file_kanban_renderer.esm.js +1 -2
- odoo/addons/dms/static/src/js/views/file_kanban_renderer.xml +12 -16
- odoo/addons/dms/static/src/js/views/file_kanban_view.esm.js +11 -9
- odoo/addons/dms/static/src/js/views/file_list_controller.esm.js +1 -1
- odoo/addons/dms/static/src/js/views/file_list_renderer.xml +1 -7
- odoo/addons/dms/static/src/js/views/file_list_view.esm.js +11 -9
- odoo/addons/dms/static/src/js/views/search_panel.esm.js +9 -10
- odoo/addons/dms/static/src/models/attachment.esm.js +83 -82
- odoo/addons/dms/static/src/models/attachment_image.esm.js +30 -28
- odoo/addons/dms/static/src/models/attachment_viewer_viewable.esm.js +27 -25
- odoo/addons/dms/static/src/scss/directory_kanban.scss +28 -73
- odoo/addons/dms/static/src/scss/dms_common.scss +69 -0
- odoo/addons/dms/static/src/scss/file_kanban.scss +22 -34
- odoo/addons/dms/static/src/scss/portal.scss +12 -0
- odoo/addons/dms/static/tests/tours/dms_portal_tour.esm.js +46 -0
- odoo/addons/dms/{views/dms_portal_templates.xml → template/portal.xml} +13 -3
- odoo/addons/dms/tests/common.py +20 -4
- odoo/addons/dms/tests/data/mail01.eml +2 -2
- odoo/addons/dms/tests/data/mail02.eml +2 -2
- odoo/addons/dms/tests/test_benchmark.py +16 -21
- odoo/addons/dms/tests/test_directory.py +128 -40
- odoo/addons/dms/tests/test_file.py +112 -30
- odoo/addons/dms/tests/test_file_database.py +50 -24
- odoo/addons/dms/tests/test_portal.py +50 -37
- odoo/addons/dms/tests/test_storage_attachment.py +85 -63
- odoo/addons/dms/tests/test_storage_database.py +89 -35
- odoo/addons/dms/tools/file.py +63 -11
- odoo/addons/dms/views/dms_access_groups_views.xml +2 -17
- odoo/addons/dms/views/{category.xml → dms_category.xml} +4 -9
- odoo/addons/dms/views/{directory.xml → dms_directory.xml} +168 -176
- odoo/addons/dms/views/dms_file.xml +170 -191
- odoo/addons/dms/views/{tag.xml → dms_tag.xml} +50 -53
- odoo/addons/dms/views/menu.xml +52 -21
- odoo/addons/dms/views/res_config_settings.xml +31 -82
- odoo/addons/dms/views/storage.xml +7 -13
- odoo_addon_dms-17.0.1.0.0.2.dist-info/METADATA +257 -0
- {odoo_addon_dms-16.0.1.8.0.3.dist-info → odoo_addon_dms-17.0.1.0.0.2.dist-info}/RECORD +93 -93
- {odoo_addon_dms-16.0.1.8.0.3.dist-info → odoo_addon_dms-17.0.1.0.0.2.dist-info}/WHEEL +1 -1
- odoo_addon_dms-17.0.1.0.0.2.dist-info/top_level.txt +1 -0
- odoo/addons/dms/readme/CONFIGURE.rst +0 -40
- odoo/addons/dms/readme/CONTRIBUTORS.rst +0 -16
- odoo/addons/dms/readme/CREDITS.rst +0 -6
- odoo/addons/dms/readme/DESCRIPTION.rst +0 -6
- odoo/addons/dms/readme/INSTALL.rst +0 -9
- odoo/addons/dms/readme/ROADMAP.rst +0 -8
- odoo/addons/dms/readme/USAGE.rst +0 -8
- odoo/addons/dms/static/src/js/components/path/path.esm.js +0 -0
- odoo/addons/dms/static/src/js/dms_portal_tour.js +0 -57
- odoo/addons/dms/static/src/js/fields/path.js +0 -81
- odoo/addons/dms/static/src/js/views/fields/binary/preview_record.esm.js +0 -35
- odoo/addons/dms/static/src/js/views/many_drop_target.js +0 -98
- odoo/addons/dms/static/src/scss/variables.scss +0 -9
- odoo/addons/dms/static/src/xml/views.xml +0 -72
- odoo/addons/dms/template/assets.xml +0 -44
- odoo/addons/dms/template/onboarding.xml +0 -97
- odoo_addon_dms-16.0.1.8.0.3.dist-info/METADATA +0 -203
- odoo_addon_dms-16.0.1.8.0.3.dist-info/top_level.txt +0 -1
@@ -1,13 +1,16 @@
|
|
1
1
|
# Copyright 2017-2019 MuK IT GmbH.
|
2
2
|
# Copyright 2020 Creu Blanca
|
3
3
|
# Copyright 2021 Tecnativa - Víctor Martínez
|
4
|
+
# Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
4
5
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
5
6
|
|
6
7
|
import ast
|
7
8
|
import base64
|
8
9
|
import logging
|
10
|
+
import os
|
9
11
|
from ast import literal_eval
|
10
12
|
from collections import defaultdict
|
13
|
+
from typing import Literal # noqa # pylint: disable=unused-import
|
11
14
|
|
12
15
|
from odoo import _, api, fields, models, tools
|
13
16
|
from odoo.exceptions import UserError, ValidationError
|
@@ -19,6 +22,7 @@ from odoo.addons.http_routing.models.ir_http import slugify
|
|
19
22
|
from ..tools.file import check_name, unique_name
|
20
23
|
|
21
24
|
_logger = logging.getLogger(__name__)
|
25
|
+
_path = os.path.dirname(os.path.dirname(__file__))
|
22
26
|
|
23
27
|
|
24
28
|
class DmsDirectory(models.Model):
|
@@ -115,7 +119,7 @@ class DmsDirectory(models.Model):
|
|
115
119
|
inverse_name="parent_id",
|
116
120
|
string="Subdirectories",
|
117
121
|
auto_join=False,
|
118
|
-
copy=
|
122
|
+
copy=True,
|
119
123
|
)
|
120
124
|
|
121
125
|
tag_ids = fields.Many2many(
|
@@ -152,7 +156,7 @@ class DmsDirectory(models.Model):
|
|
152
156
|
inverse_name="directory_id",
|
153
157
|
string="Files",
|
154
158
|
auto_join=False,
|
155
|
-
copy=
|
159
|
+
copy=True,
|
156
160
|
)
|
157
161
|
|
158
162
|
count_directories = fields.Integer(
|
@@ -248,15 +252,16 @@ class DmsDirectory(models.Model):
|
|
248
252
|
item = items[0]
|
249
253
|
if item.id == self.id:
|
250
254
|
return True
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
return True
|
256
|
-
directory_item = directory_item.parent_id
|
257
|
-
# Fix last level
|
255
|
+
# sudo because the user might not usually have access to the record but
|
256
|
+
# now the token is valid.
|
257
|
+
directory_item = self.sudo()
|
258
|
+
while directory_item.parent_id:
|
258
259
|
if directory_item.id == item.id:
|
259
260
|
return True
|
261
|
+
directory_item = directory_item.parent_id
|
262
|
+
# Fix last level
|
263
|
+
if directory_item.id == item.id:
|
264
|
+
return True
|
260
265
|
return res
|
261
266
|
|
262
267
|
@api.model
|
@@ -332,28 +337,16 @@ class DmsDirectory(models.Model):
|
|
332
337
|
for record in self:
|
333
338
|
record.res_model = record.model_id.model
|
334
339
|
|
335
|
-
def name_get(self):
|
336
|
-
if not self.env.context.get("directory_short_name", False):
|
337
|
-
return super().name_get()
|
338
|
-
vals = []
|
339
|
-
for record in self:
|
340
|
-
vals.append(tuple([record.id, record.name]))
|
341
|
-
return vals
|
342
|
-
|
343
340
|
def toggle_starred(self):
|
344
341
|
updates = defaultdict(set)
|
345
342
|
for record in self:
|
346
343
|
vals = {"starred": not record.starred}
|
347
344
|
updates[tools.frozendict(vals)].add(record.id)
|
348
|
-
|
349
|
-
|
350
|
-
self.browse(ids).write(dict(vals))
|
345
|
+
for vals, ids in updates.items():
|
346
|
+
self.browse(ids).write(dict(vals))
|
351
347
|
self.flush_recordset()
|
352
348
|
|
353
|
-
# ----------------------------------------------------------
|
354
349
|
# SearchPanel
|
355
|
-
# ----------------------------------------------------------
|
356
|
-
|
357
350
|
@api.model
|
358
351
|
def search_panel_select_range(self, field_name, **kwargs):
|
359
352
|
context = {}
|
@@ -369,19 +362,13 @@ class DmsDirectory(models.Model):
|
|
369
362
|
DmsDirectory, self.with_context(category_short_name=True)
|
370
363
|
).search_panel_select_multi_range(field_name, **kwargs)
|
371
364
|
|
372
|
-
# ----------------------------------------------------------
|
373
365
|
# Actions
|
374
|
-
# ----------------------------------------------------------
|
375
|
-
|
376
366
|
def action_save_onboarding_directory_step(self):
|
377
367
|
self.env.user.company_id.set_onboarding_step_done(
|
378
368
|
"documents_onboarding_directory_state"
|
379
369
|
)
|
380
370
|
|
381
|
-
# ----------------------------------------------------------
|
382
371
|
# SearchPanel
|
383
|
-
# ----------------------------------------------------------
|
384
|
-
|
385
372
|
@api.model
|
386
373
|
def _search_panel_directory(self, **kwargs):
|
387
374
|
search_domain = (kwargs.get("search_domain", []),)
|
@@ -391,10 +378,7 @@ class DmsDirectory(models.Model):
|
|
391
378
|
return domain[1], domain[2]
|
392
379
|
return None, None
|
393
380
|
|
394
|
-
# ----------------------------------------------------------
|
395
381
|
# Search
|
396
|
-
# ----------------------------------------------------------
|
397
|
-
|
398
382
|
@api.model
|
399
383
|
def _search_starred(self, operator, operand):
|
400
384
|
if operator == "=" and operand:
|
@@ -443,9 +427,7 @@ class DmsDirectory(models.Model):
|
|
443
427
|
@api.depends("child_directory_ids", "file_ids")
|
444
428
|
def _compute_count_elements(self):
|
445
429
|
for record in self:
|
446
|
-
|
447
|
-
elements += record.count_directories
|
448
|
-
record.count_elements = elements
|
430
|
+
record.count_elements = record.count_files + record.count_directories
|
449
431
|
|
450
432
|
def _compute_count_total_directories(self):
|
451
433
|
for record in self:
|
@@ -466,9 +448,9 @@ class DmsDirectory(models.Model):
|
|
466
448
|
|
467
449
|
def _compute_count_total_elements(self):
|
468
450
|
for record in self:
|
469
|
-
|
470
|
-
|
471
|
-
|
451
|
+
record.count_total_elements = (
|
452
|
+
record.count_total_files + record.count_total_directories
|
453
|
+
)
|
472
454
|
|
473
455
|
def _compute_size(self):
|
474
456
|
sudo_model = self.env["dms.file"].sudo()
|
@@ -502,10 +484,7 @@ class DmsDirectory(models.Model):
|
|
502
484
|
groups |= one.parent_id.complete_group_ids
|
503
485
|
self.complete_group_ids = groups
|
504
486
|
|
505
|
-
# ----------------------------------------------------------
|
506
487
|
# View
|
507
|
-
# ----------------------------------------------------------
|
508
|
-
|
509
488
|
@api.depends("is_root_directory")
|
510
489
|
def _compute_parent_id(self):
|
511
490
|
for record in self:
|
@@ -530,7 +509,8 @@ class DmsDirectory(models.Model):
|
|
530
509
|
def _compute_tags(self):
|
531
510
|
for record in self:
|
532
511
|
tags = record.tag_ids.filtered(
|
533
|
-
lambda rec: not rec.category_id
|
512
|
+
lambda rec, record=record: not rec.category_id
|
513
|
+
or rec.category_id == record.category_id
|
534
514
|
)
|
535
515
|
record.tag_ids = tags
|
536
516
|
|
@@ -547,10 +527,7 @@ class DmsDirectory(models.Model):
|
|
547
527
|
def _onchange_model_id(self):
|
548
528
|
self._inverse_model_id()
|
549
529
|
|
550
|
-
# ----------------------------------------------------------
|
551
530
|
# Constrains
|
552
|
-
# ----------------------------------------------------------
|
553
|
-
|
554
531
|
@api.constrains("parent_id")
|
555
532
|
def _check_directory_recursion(self):
|
556
533
|
if not self._check_recursion():
|
@@ -559,9 +536,9 @@ class DmsDirectory(models.Model):
|
|
559
536
|
|
560
537
|
@api.constrains("storage_id", "model_id")
|
561
538
|
def _check_storage_id_attachment_model_id(self):
|
562
|
-
for record in self
|
563
|
-
|
564
|
-
|
539
|
+
for record in self.filtered(
|
540
|
+
lambda directory: directory.storage_id.save_type == "attachment"
|
541
|
+
):
|
565
542
|
if not record.model_id:
|
566
543
|
raise ValidationError(
|
567
544
|
_("A directory has to have model in attachment storage.")
|
@@ -593,23 +570,19 @@ class DmsDirectory(models.Model):
|
|
593
570
|
if self.env.context.get("check_name", True) and not check_name(record.name):
|
594
571
|
raise ValidationError(_("The directory name is invalid."))
|
595
572
|
if record.is_root_directory:
|
596
|
-
|
573
|
+
children = record.sudo().storage_id.root_directory_ids
|
597
574
|
else:
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
)
|
575
|
+
children = record.sudo().parent_id.child_directory_ids
|
576
|
+
|
577
|
+
if children.filtered(
|
578
|
+
lambda child, record=record: child.name == record.name
|
579
|
+
and child != record
|
604
580
|
):
|
605
581
|
raise ValidationError(
|
606
582
|
_("A directory with the same name already exists.")
|
607
583
|
)
|
608
584
|
|
609
|
-
# ----------------------------------------------------------
|
610
585
|
# Create, Update, Delete
|
611
|
-
# ----------------------------------------------------------
|
612
|
-
|
613
586
|
def _inverse_starred(self):
|
614
587
|
starred_records = self.env["dms.directory"].sudo()
|
615
588
|
not_starred_records = self.env["dms.directory"].sudo()
|
@@ -625,19 +598,14 @@ class DmsDirectory(models.Model):
|
|
625
598
|
self.ensure_one()
|
626
599
|
default = dict(default or [])
|
627
600
|
if "parent_id" in default:
|
628
|
-
parent_directory = self.browse(default
|
601
|
+
parent_directory = self.browse(default.get("parent_id"))
|
629
602
|
names = parent_directory.sudo().child_directory_ids.mapped("name")
|
630
603
|
elif self.is_root_directory:
|
631
604
|
names = self.sudo().storage_id.root_directory_ids.mapped("name")
|
632
605
|
else:
|
633
606
|
names = self.sudo().parent_id.child_directory_ids.mapped("name")
|
634
607
|
default.update({"name": unique_name(self.name, names)})
|
635
|
-
|
636
|
-
for record in self.file_ids:
|
637
|
-
record.copy({"directory_id": new.id})
|
638
|
-
for record in self.child_directory_ids:
|
639
|
-
record.copy({"parent_id": new.id})
|
640
|
-
return new
|
608
|
+
return super().copy(default)
|
641
609
|
|
642
610
|
def _alias_get_creation_values(self):
|
643
611
|
values = super()._alias_get_creation_values()
|
@@ -652,7 +620,7 @@ class DmsDirectory(models.Model):
|
|
652
620
|
@api.model
|
653
621
|
def message_new(self, msg_dict, custom_values=None):
|
654
622
|
custom_values = custom_values if custom_values is not None else {}
|
655
|
-
parent_directory_id = custom_values.get("parent_id"
|
623
|
+
parent_directory_id = custom_values.get("parent_id")
|
656
624
|
parent_directory = self.sudo().browse(parent_directory_id)
|
657
625
|
if not parent_directory_id or not parent_directory.exists():
|
658
626
|
raise ValueError("No directory could be found!")
|
@@ -697,11 +665,12 @@ class DmsDirectory(models.Model):
|
|
697
665
|
# Hack to prevent error related to mail_message parent not exists in some cases
|
698
666
|
ctx = dict(self.env.context).copy()
|
699
667
|
ctx.update({"default_parent_id": False})
|
668
|
+
self.env.registry.clear_cache()
|
700
669
|
res = super(DmsDirectory, self.with_context(**ctx)).create(vals_list)
|
701
670
|
return res
|
702
671
|
|
703
672
|
def write(self, vals):
|
704
|
-
if any(
|
673
|
+
if any(k in vals.keys() for k in ["storage_id", "parent_id"]):
|
705
674
|
for item in self:
|
706
675
|
new_storage_id = vals.get("storage_id", item.storage_id.id)
|
707
676
|
new_parent_id = vals.get("parent_id", item.parent_id.id)
|
@@ -711,17 +680,19 @@ class DmsDirectory(models.Model):
|
|
711
680
|
if new_parent_id:
|
712
681
|
if old_storage_id != self.browse(new_parent_id).storage_id.id:
|
713
682
|
raise UserError(
|
714
|
-
_(
|
683
|
+
_(
|
684
|
+
"It is not possible to change to a parent "
|
685
|
+
"with other storage."
|
686
|
+
)
|
715
687
|
)
|
716
688
|
elif old_storage_id != new_storage_id:
|
717
689
|
raise UserError(_("It is not possible to change the storage."))
|
718
690
|
# Groups part
|
719
691
|
if any(key in vals for key in ["group_ids", "inherit_group_ids"]):
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
records.modified(["group_ids"])
|
692
|
+
res = super().write(vals)
|
693
|
+
domain = [("id", "child_of", self.ids)]
|
694
|
+
records = self.sudo().search(domain)
|
695
|
+
records.modified(["group_ids"])
|
725
696
|
records.flush_recordset()
|
726
697
|
else:
|
727
698
|
res = super().write(vals)
|
@@ -736,14 +707,14 @@ class DmsDirectory(models.Model):
|
|
736
707
|
self.file_ids.unlink()
|
737
708
|
if self.child_directory_ids:
|
738
709
|
self.child_directory_ids.unlink()
|
739
|
-
return super().unlink()
|
710
|
+
return super(DmsDirectory, self.exists()).unlink()
|
740
711
|
|
741
712
|
@api.model
|
742
713
|
def _search_panel_domain_image(
|
743
714
|
self, field_name, domain, set_count=False, limit=False
|
744
715
|
):
|
745
716
|
"""We need to overwrite function from directories because odoo only return
|
746
|
-
records with
|
717
|
+
records with children (very weird for user perspective).
|
747
718
|
All records are returned now.
|
748
719
|
"""
|
749
720
|
if field_name == "parent_id":
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# Copyright 2020 Creu Blanca
|
2
2
|
# Copyright 2017-2019 MuK IT GmbH
|
3
|
+
# Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
3
4
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
4
5
|
|
5
6
|
import logging
|
@@ -10,7 +11,7 @@ from odoo.exceptions import ValidationError
|
|
10
11
|
_logger = logging.getLogger(__name__)
|
11
12
|
|
12
13
|
|
13
|
-
class
|
14
|
+
class DMSCategory(models.Model):
|
14
15
|
_name = "dms.category"
|
15
16
|
_description = "Document Category"
|
16
17
|
|
@@ -20,12 +21,7 @@ class Category(models.Model):
|
|
20
21
|
_order = "complete_name asc"
|
21
22
|
_rec_name = "complete_name"
|
22
23
|
|
23
|
-
# ----------------------------------------------------------
|
24
|
-
# Database
|
25
|
-
# ----------------------------------------------------------
|
26
|
-
|
27
24
|
name = fields.Char(required=True, translate=True)
|
28
|
-
|
29
25
|
active = fields.Boolean(
|
30
26
|
default=True,
|
31
27
|
help="The active field allows you to hide the category without removing it.",
|
@@ -34,65 +30,49 @@ class Category(models.Model):
|
|
34
30
|
compute="_compute_complete_name", store=True, recursive=True
|
35
31
|
)
|
36
32
|
parent_id = fields.Many2one(
|
37
|
-
comodel_name="dms.category",
|
38
33
|
string="Parent Category",
|
34
|
+
comodel_name="dms.category",
|
39
35
|
ondelete="cascade",
|
40
36
|
index="btree",
|
41
37
|
)
|
42
|
-
|
43
38
|
child_category_ids = fields.One2many(
|
39
|
+
string="Child Categories",
|
44
40
|
comodel_name="dms.category",
|
45
41
|
inverse_name="parent_id",
|
46
|
-
string="Child Categories",
|
47
42
|
)
|
48
|
-
|
49
43
|
parent_path = fields.Char(index="btree", unaccent=False)
|
50
44
|
tag_ids = fields.One2many(
|
51
|
-
comodel_name="dms.tag", inverse_name="category_id"
|
45
|
+
string="Tags", comodel_name="dms.tag", inverse_name="category_id"
|
52
46
|
)
|
53
47
|
directory_ids = fields.One2many(
|
48
|
+
string="Directories",
|
54
49
|
comodel_name="dms.directory",
|
55
50
|
inverse_name="category_id",
|
56
|
-
string="Directories",
|
57
51
|
readonly=True,
|
58
52
|
)
|
59
|
-
|
60
53
|
file_ids = fields.One2many(
|
54
|
+
string="Files",
|
61
55
|
comodel_name="dms.file",
|
62
56
|
inverse_name="category_id",
|
63
|
-
string="Files",
|
64
57
|
readonly=True,
|
65
58
|
)
|
66
|
-
|
67
59
|
count_categories = fields.Integer(
|
68
|
-
|
60
|
+
string="Count Subcategories", compute="_compute_count_categories"
|
69
61
|
)
|
70
|
-
|
71
62
|
count_tags = fields.Integer(compute="_compute_count_tags")
|
72
|
-
|
73
63
|
count_directories = fields.Integer(compute="_compute_count_directories")
|
74
|
-
|
75
64
|
count_files = fields.Integer(compute="_compute_count_files")
|
76
65
|
|
77
|
-
# ----------------------------------------------------------
|
78
|
-
# Constrains
|
79
|
-
# ----------------------------------------------------------
|
80
|
-
|
81
66
|
_sql_constraints = [
|
82
67
|
("name_uniq", "unique (name)", "Category name already exists!"),
|
83
68
|
]
|
84
69
|
|
85
|
-
# ----------------------------------------------------------
|
86
|
-
# Read
|
87
|
-
# ----------------------------------------------------------
|
88
|
-
|
89
70
|
@api.depends("name", "parent_id.complete_name")
|
90
71
|
def _compute_complete_name(self):
|
91
72
|
for category in self:
|
92
73
|
if category.parent_id:
|
93
|
-
category.complete_name =
|
94
|
-
category.parent_id.complete_name
|
95
|
-
category.name,
|
74
|
+
category.complete_name = (
|
75
|
+
f"{category.parent_id.complete_name} / {category.name}"
|
96
76
|
)
|
97
77
|
else:
|
98
78
|
category.complete_name = category.name
|
@@ -117,18 +97,6 @@ class Category(models.Model):
|
|
117
97
|
for record in self:
|
118
98
|
record.count_files = len(record.file_ids)
|
119
99
|
|
120
|
-
def name_get(self):
|
121
|
-
if not self.env.context.get("category_short_name", False):
|
122
|
-
return super().name_get()
|
123
|
-
vals = []
|
124
|
-
for record in self:
|
125
|
-
vals.append(tuple([record.id, record.name]))
|
126
|
-
return vals
|
127
|
-
|
128
|
-
# ----------------------------------------------------------
|
129
|
-
# Create
|
130
|
-
# ----------------------------------------------------------
|
131
|
-
|
132
100
|
@api.constrains("parent_id")
|
133
101
|
def _check_category_recursion(self):
|
134
102
|
if not self._check_recursion():
|