odoo-addon-dms 17.0.1.2.0__py3-none-any.whl → 18.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.
Files changed (59) hide show
  1. odoo/addons/dms/README.rst +69 -62
  2. odoo/addons/dms/__manifest__.py +1 -5
  3. odoo/addons/dms/data/onboarding_data.xml +0 -1
  4. odoo/addons/dms/i18n/de.po +0 -203
  5. odoo/addons/dms/i18n/dms.pot +51 -55
  6. odoo/addons/dms/i18n/es.po +0 -214
  7. odoo/addons/dms/i18n/fr.po +0 -45
  8. odoo/addons/dms/i18n/he_IL.po +0 -139
  9. odoo/addons/dms/i18n/it.po +0 -219
  10. odoo/addons/dms/i18n/nl.po +0 -6
  11. odoo/addons/dms/i18n/pt.po +0 -215
  12. odoo/addons/dms/i18n/pt_BR.po +0 -201
  13. odoo/addons/dms/models/access_groups.py +9 -8
  14. odoo/addons/dms/models/directory.py +21 -23
  15. odoo/addons/dms/models/dms_category.py +2 -2
  16. odoo/addons/dms/models/dms_file.py +15 -16
  17. odoo/addons/dms/models/dms_security_mixin.py +46 -20
  18. odoo/addons/dms/models/ir_binary.py +2 -2
  19. odoo/addons/dms/models/mixins_thumbnail.py +1 -1
  20. odoo/addons/dms/models/storage.py +3 -3
  21. odoo/addons/dms/readme/CONTRIBUTORS.md +2 -0
  22. odoo/addons/dms/readme/ROADMAP.md +2 -0
  23. odoo/addons/dms/static/description/index.html +13 -6
  24. odoo/addons/dms/static/src/js/fields/path_json/path_owl.esm.js +5 -5
  25. odoo/addons/dms/static/src/js/fields/preview_binary/preview_record.esm.js +2 -4
  26. odoo/addons/dms/static/src/js/views/dms_file_upload.esm.js +2 -5
  27. odoo/addons/dms/static/src/js/views/file_kanban_controller.esm.js +0 -2
  28. odoo/addons/dms/static/src/js/views/file_kanban_record.esm.js +0 -2
  29. odoo/addons/dms/static/src/js/views/file_kanban_renderer.esm.js +0 -2
  30. odoo/addons/dms/static/src/js/views/file_kanban_view.esm.js +0 -2
  31. odoo/addons/dms/static/src/js/views/file_list_controller.esm.js +0 -2
  32. odoo/addons/dms/static/src/js/views/file_list_renderer.esm.js +0 -2
  33. odoo/addons/dms/static/src/js/views/file_list_view.esm.js +0 -2
  34. odoo/addons/dms/static/src/js/views/search_panel.esm.js +1 -5
  35. odoo/addons/dms/static/src/models/attachment.esm.js +0 -2
  36. odoo/addons/dms/static/src/models/attachment_image.esm.js +0 -2
  37. odoo/addons/dms/static/src/models/attachment_viewer_viewable.esm.js +0 -2
  38. odoo/addons/dms/static/tests/tours/dms_portal_tour.esm.js +3 -7
  39. odoo/addons/dms/template/portal.xml +8 -6
  40. odoo/addons/dms/tests/common.py +9 -10
  41. odoo/addons/dms/tests/test_benchmark.py +19 -1
  42. odoo/addons/dms/tests/test_directory.py +8 -5
  43. odoo/addons/dms/tests/test_file_database.py +1 -1
  44. odoo/addons/dms/tests/test_portal.py +16 -17
  45. odoo/addons/dms/views/dms_access_groups_views.xml +13 -13
  46. odoo/addons/dms/views/dms_category.xml +5 -5
  47. odoo/addons/dms/views/dms_directory.xml +101 -110
  48. odoo/addons/dms/views/dms_file.xml +66 -84
  49. odoo/addons/dms/views/dms_tag.xml +14 -33
  50. odoo/addons/dms/views/menu.xml +22 -13
  51. odoo/addons/dms/views/storage.xml +189 -193
  52. odoo/addons/dms/wizards/wizard_dms_file_move_views.xml +1 -1
  53. {odoo_addon_dms-17.0.1.2.0.dist-info → odoo_addon_dms-18.0.1.0.0.2.dist-info}/METADATA +72 -65
  54. {odoo_addon_dms-17.0.1.2.0.dist-info → odoo_addon_dms-18.0.1.0.0.2.dist-info}/RECORD +56 -59
  55. odoo/addons/dms/static/src/scss/directory_kanban.scss +0 -53
  56. odoo/addons/dms/static/src/scss/dms_common.scss +0 -69
  57. odoo/addons/dms/static/src/scss/file_kanban.scss +0 -70
  58. {odoo_addon_dms-17.0.1.2.0.dist-info → odoo_addon_dms-18.0.1.0.0.2.dist-info}/WHEEL +0 -0
  59. {odoo_addon_dms-17.0.1.2.0.dist-info → odoo_addon_dms-18.0.1.0.0.2.dist-info}/top_level.txt +0 -0
@@ -367,9 +367,9 @@ ul.auto-toc {
367
367
  !! This file is generated by oca-gen-addon-readme !!
368
368
  !! changes will be overwritten. !!
369
369
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
370
- !! source digest: sha256:a80857552a72c549c1408dee6bba18376f617070f6175b601833510cb99d8e4f
370
+ !! source digest: sha256:904150d6b7037648a3ed02450c9b27d802f4cee614b59b1fa582f48093e1a0ed
371
371
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
372
- <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/dms/tree/17.0/dms"><img alt="OCA/dms" src="https://img.shields.io/badge/github-OCA%2Fdms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/dms-17-0/dms-17-0-dms"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/dms&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
372
+ <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/dms/tree/18.0/dms"><img alt="OCA/dms" src="https://img.shields.io/badge/github-OCA%2Fdms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/dms-18-0/dms-18-0-dms"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/dms&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
373
373
  <p>DMS is a module for creating, managing and viewing document files
374
374
  directly within Odoo. This module is only the basis for an entire
375
375
  ecosystem of apps that extend and seamlessly integrate with the document
@@ -444,8 +444,8 @@ Access Groups</em>.<ul>
444
444
  <li>Create a new group, name it appropriately, and turn on all three
445
445
  permissions (Create, Write and Unlink. Read is implied and always
446
446
  enabled).</li>
447
- <li>Add any other top-level administrative users to the group if
448
- needed (your user should already be there).</li>
447
+ <li>Add any other top-level administrative users to the group if needed
448
+ (your user should already be there).</li>
449
449
  <li>You can create other groups in here later for fine-grained access
450
450
  control.</li>
451
451
  </ul>
@@ -534,6 +534,9 @@ secrets, remember to forbid access to the secrets fields by other
534
534
  means. It would be nice to be able to remove that rule at some point.</li>
535
535
  <li>Searchpanel in files: Highlight items (shading) without records when
536
536
  filtering something (by name for example).</li>
537
+ <li>Accessing the clipboard (for example copy share link of
538
+ file/directory) is limited to secure connections. It also happens in
539
+ any part of Odoo.</li>
537
540
  </ul>
538
541
  </div>
539
542
  <div class="section" id="bug-tracker">
@@ -541,7 +544,7 @@ filtering something (by name for example).</li>
541
544
  <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/dms/issues">GitHub Issues</a>.
542
545
  In case of trouble, please check there if your issue has already been reported.
543
546
  If you spotted it first, help us to smash it by providing a detailed and welcomed
544
- <a class="reference external" href="https://github.com/OCA/dms/issues/new?body=module:%20dms%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
547
+ <a class="reference external" href="https://github.com/OCA/dms/issues/new?body=module:%20dms%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
545
548
  <p>Do not contact contributors directly about support or help with technical issues.</p>
546
549
  </div>
547
550
  <div class="section" id="credits">
@@ -576,6 +579,10 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
576
579
  <li>Timothée Vannier &lt;<a class="reference external" href="mailto:tva&#64;subteno.com">tva&#64;subteno.com</a>&gt;</li>
577
580
  </ul>
578
581
  </li>
582
+ <li><a class="reference external" href="https://www.kencove.com">Kencove</a>:<ul>
583
+ <li>Mohamed Alkobrosli &lt;<a class="reference external" href="mailto:malkobrosly&#64;kencove.com">malkobrosly&#64;kencove.com</a>&gt;</li>
584
+ </ul>
585
+ </li>
579
586
  </ul>
580
587
  </div>
581
588
  <div class="section" id="other-credits">
@@ -598,7 +605,7 @@ DMS icon</li>
598
605
  <p>OCA, or the Odoo Community Association, is a nonprofit organization whose
599
606
  mission is to support the collaborative development of Odoo features and
600
607
  promote its widespread use.</p>
601
- <p>This module is part of the <a class="reference external" href="https://github.com/OCA/dms/tree/17.0/dms">OCA/dms</a> project on GitHub.</p>
608
+ <p>This module is part of the <a class="reference external" href="https://github.com/OCA/dms/tree/18.0/dms">OCA/dms</a> project on GitHub.</p>
602
609
  <p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
603
610
  </div>
604
611
  </div>
@@ -1,10 +1,9 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
6
4
  // **********************************************************************************/
7
5
  import {Component, onWillUpdateProps} from "@odoo/owl";
6
+ import {_t} from "@web/core/l10n/translation";
8
7
  import {registry} from "@web/core/registry";
9
8
  import {standardFieldProps} from "@web/views/fields/standard_field_props";
10
9
  import {useService} from "@web/core/utils/hooks";
@@ -24,10 +23,11 @@ class DmsPathField extends Component {
24
23
 
25
24
  _onNodeClicked(event) {
26
25
  event.preventDefault();
26
+ const target = event.currentTarget;
27
27
  this.action.doAction({
28
28
  type: "ir.actions.act_window",
29
- res_model: $(event.currentTarget).data("model"),
30
- res_id: $(event.currentTarget).data("id"),
29
+ res_model: target.getAttribute("data-model"),
30
+ res_id: Number(target.getAttribute("data-id")),
31
31
  views: [[false, "form"]],
32
32
  target: "current",
33
33
  context: {},
@@ -42,7 +42,7 @@ DmsPathField.props = {
42
42
 
43
43
  const dmsPathField = {
44
44
  component: DmsPathField,
45
- display_name: "Dms Path Field",
45
+ displayName: _t("Dms Path Field"),
46
46
  supportedTypes: ["text"],
47
47
  extractProps: () => {
48
48
  return {};
@@ -1,10 +1,9 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
6
4
  // **********************************************************************************/
7
5
  import {BinaryField} from "@web/views/fields/binary/binary_field";
6
+ import {_t} from "@web/core/l10n/translation";
8
7
  import {registry} from "@web/core/registry";
9
8
  import {standardFieldProps} from "@web/views/fields/standard_field_props";
10
9
  import {useFileViewer} from "@web/core/file_viewer/file_viewer_hook";
@@ -37,8 +36,7 @@ PreviewRecordField.props = {
37
36
 
38
37
  const previewRecordField = {
39
38
  component: PreviewRecordField,
40
- dependencies: [BinaryField],
41
- display_name: "Preview Record",
39
+ displayName: _t("Preview Record"),
42
40
  supportedTypes: ["binary"],
43
41
  extractProps: () => {
44
42
  return {};
@@ -1,15 +1,12 @@
1
- /** @odoo-module */
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
6
4
  // **********************************************************************************/
7
5
 
8
6
  import {useBus, useService} from "@web/core/utils/hooks";
7
+ import {useEffect, useRef, useState} from "@odoo/owl";
9
8
  import {_t} from "@web/core/l10n/translation";
10
9
 
11
- const {useRef, useEffect, useState} = owl;
12
-
13
10
  export function createFileDropZoneExtension() {
14
11
  return {
15
12
  setup() {
@@ -36,7 +33,7 @@ export function createFileDropZoneExtension() {
36
33
  el.removeEventListener("drop", drop);
37
34
  };
38
35
  },
39
-
36
+ // eslint-disable-next-line no-undef
40
37
  () => [document.querySelector(".o_content")]
41
38
  );
42
39
  },
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2020 Creu Blanca
5
3
  // Copyright 2017-2019 MuK IT GmbH
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
@@ -1,5 +1,3 @@
1
- /** @odoo-module */
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2020 Creu Blanca
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2020 Creu Blanca
5
3
  // Copyright 2017-2019 MuK IT GmbH
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2020 Creu Blanca
5
3
  // Copyright 2017-2019 MuK IT GmbH
@@ -1,5 +1,3 @@
1
- /** @odoo-module */
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2020 Creu Blanca
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2020 Creu Blanca
5
3
  // Copyright 2017-2019 MuK IT GmbH
@@ -1,12 +1,10 @@
1
- /** @odoo-module **/
2
1
  /* Copyright 2021-2024 Tecnativa - Víctor Martínez
3
2
  * Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
4
3
  * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
5
4
 
6
5
  import {SearchModel} from "@web/search/search_model";
7
- import {registry} from "@web/core/registry";
8
6
 
9
- class DMSSearchPanel extends SearchModel {
7
+ export class DMSSearchPanel extends SearchModel {
10
8
  _getCategoryDomain(excludedCategoryId) {
11
9
  const domain = super._getCategoryDomain(...arguments);
12
10
  for (const category of this.categories) {
@@ -24,5 +22,3 @@ class DMSSearchPanel extends SearchModel {
24
22
  return domain;
25
23
  }
26
24
  }
27
-
28
- registry.category("views").add("dms_search_panel", DMSSearchPanel);
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
@@ -1,5 +1,3 @@
1
- /** @odoo-module **/
2
-
3
1
  // /** ********************************************************************************
4
2
  // Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
5
3
  // License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
@@ -12,12 +10,11 @@ registry.category("web_tour.tours").add("dms_portal_mail_tour", {
12
10
  steps: () => [
13
11
  {
14
12
  content: "Go to Mails directory",
15
- extra_trigger: "li.breadcrumb-item:contains('Documents')",
16
13
  trigger: ".tr_dms_directory_link:contains('Mails')",
14
+ run: "click",
17
15
  },
18
16
  {
19
17
  content: "Go to Mail_01.eml",
20
- extra_trigger: "li.breadcrumb-item:contains('Mails')",
21
18
  trigger: ".tr_dms_file_link:contains('Mail_01.eml')",
22
19
  },
23
20
  ],
@@ -29,17 +26,16 @@ registry.category("web_tour.tours").add("dms_portal_partners_tour", {
29
26
  steps: () => [
30
27
  {
31
28
  content: "Go to Partners directory",
32
- extra_trigger: "li.breadcrumb-item:contains('Documents')",
33
29
  trigger: ".tr_dms_directory_link:contains('Partners')",
30
+ run: "click",
34
31
  },
35
32
  {
36
33
  content: "Go to Joel Willis",
37
- extra_trigger: "li.breadcrumb-item:contains('Partners')",
38
34
  trigger: ".tr_dms_directory_link:contains('Joel Willis')",
35
+ run: "click",
39
36
  },
40
37
  {
41
38
  content: "Go to test.txt",
42
- extra_trigger: "li.breadcrumb-item:contains('Joel Willis')",
43
39
  trigger: ".tr_dms_file_link:contains('test.txt')",
44
40
  },
45
41
  ],
@@ -10,8 +10,8 @@
10
10
  inherit_id="portal.portal_my_home"
11
11
  priority="20"
12
12
  >
13
- <xpath expr="//div[@id='portal_client_category']" position="after">
14
- <div class="o_portal_dms row g-2 mt-3" id="portal_dms_category">
13
+ <div id="portal_common_category" position="after">
14
+ <div class="o_portal_category row g-2 mt-3" id="portal_dms_category">
15
15
  <t t-call="portal.portal_docs_entry">
16
16
  <t t-set="title">Documents</t>
17
17
  <t t-set="text" t-value="'Manage your documents'" />
@@ -23,7 +23,7 @@
23
23
  <t t-set="placeholder_count" t-value="'dms_directory_count'" />
24
24
  </t>
25
25
  </div>
26
- </xpath>
26
+ </div>
27
27
  </template>
28
28
  <template
29
29
  id="portal_my_dms_breadcrumbs"
@@ -43,7 +43,9 @@
43
43
  </li>
44
44
  </t>
45
45
  <t t-foreach="dms_parent_categories" t-as="dms_parent_category">
46
- <li class="breadcrumb-item">
46
+ <li
47
+ t-attf-class="breadcrumb-item #{'active 'if not dms_directory else ''}"
48
+ >
47
49
  <t t-if="dms_parent_category.id != dms_directory.id">
48
50
  <a
49
51
  t-attf-href="/my/dms/directory/#{dms_parent_category.id}?{{ keep_query() }}"
@@ -52,7 +54,7 @@
52
54
  <span t-esc="dms_parent_category.name" />
53
55
  </a>
54
56
  </t>
55
- <t t-if="dms_parent_category.id == dms_directory.id">
57
+ <t t-else="">
56
58
  <span t-esc="dms_parent_category.name" />
57
59
  </t>
58
60
  </li>
@@ -115,7 +117,7 @@
115
117
  class="o_portal_contact_img"
116
118
  t-att-src="dms_file.icon_url + (('&amp;access_token=' + access_token) if access_token else '')"
117
119
  />
118
- <span t-esc="dms_file.name" />
120
+ <span t-esc="dms_file.name" />
119
121
  </a>
120
122
  </td>
121
123
  <td>
@@ -32,21 +32,20 @@ def track_function(
32
32
  threading.current_thread().query_count = 0
33
33
  threading.current_thread().perf_t0 = time.time()
34
34
  result = func(*args, **kwargs)
35
- message = "%s" % func.__name__
35
+ message = f"{func.__name__}"
36
36
  if args and hasattr(args[0], "uid"):
37
- message = " (%s)" % args[0].uid
37
+ message = f" ({args[0].uid})"
38
38
  if hasattr(threading.current_thread(), "query_count"):
39
39
  query_count = threading.current_thread().query_count
40
40
  query_time = threading.current_thread().query_time
41
41
  perf_t0 = threading.current_thread().perf_t0
42
42
  remaining_time = time.time() - perf_t0 - query_time
43
43
  time_taken = query_time + remaining_time
44
- message += " - {} Q {:.3f}s QT {:.3f}s OT {:.3f}s TT".format(
45
- query_count,
46
- query_time,
47
- remaining_time,
48
- time_taken,
44
+ message += (
45
+ f" - {query_count} Q {query_time:.3f}s"
46
+ f"QT {remaining_time:.3f}s OT {time_taken:.3f}s TT"
49
47
  )
48
+
50
49
  tracking_parameters += [
51
50
  query_count,
52
51
  query_time,
@@ -54,13 +53,13 @@ def track_function(
54
53
  time_taken,
55
54
  ]
56
55
  if max_query_count and query_count > max_query_count:
57
- raise AssertionError("More than %s queries" % max_query_count)
56
+ raise AssertionError(f"More than {max_query_count} queries")
58
57
  if max_query_time and query_time > max_query_time:
59
58
  raise AssertionError(
60
- "Queries took longer than %.3fs" % max_query_time
59
+ f"Queries took longer than {max_query_time:.3f}s"
61
60
  )
62
61
  if max_time and time_taken > max_time:
63
- raise AssertionError("Function took longer than %.3fs" % max_time)
62
+ raise AssertionError("Function took longer than {max_time:.3f}s")
64
63
  if not return_tracking:
65
64
  _logger.info(message)
66
65
  if return_tracking:
@@ -3,19 +3,37 @@
3
3
  # Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
4
4
  # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
5
5
 
6
+ import cProfile
6
7
  import logging
7
8
  import os
8
9
  import unittest
10
+ import warnings
11
+ from functools import wraps
9
12
 
10
13
  from odoo.tests import common, tagged
11
14
  from odoo.tools import convert_file
12
- from odoo.tools.misc import profile
13
15
 
14
16
  from .common import track_function
15
17
 
16
18
  _logger = logging.getLogger(__name__)
17
19
 
18
20
 
21
+ class profile:
22
+ def __init__(self, fname=None):
23
+ warnings.warn("Since 16.0.", DeprecationWarning, stacklevel=2)
24
+ self.fname = fname
25
+
26
+ def __call__(self, f):
27
+ @wraps(f)
28
+ def wrapper(*args, **kwargs):
29
+ profile = cProfile.Profile()
30
+ result = profile.runcall(f, *args, **kwargs)
31
+ profile.dump_stats(self.fname or (f"{f.__name__}.cprof"))
32
+ return result
33
+
34
+ return wrapper
35
+
36
+
19
37
  # This tests will only be executed if --test-tags benchmark is defined
20
38
  @tagged("-standard", "benchmark")
21
39
  class BenchmarkTestCase(common.TransactionCase):
@@ -87,7 +87,7 @@ class DirectoryTestCaseBase(StorageDatabaseBaseCase):
87
87
  @users("dms-manager", "dms-user")
88
88
  def test_rename_directory(self):
89
89
  path_names = self.subdirectory.complete_name
90
- self.directory.write({"name": "New Test Name %s" % self.env.user.login})
90
+ self.directory.write({"name": f"New Test Name {self.env.user.login}"})
91
91
  self.assertNotEqual(
92
92
  path_names,
93
93
  self.subdirectory.complete_name,
@@ -273,13 +273,13 @@ class DirectoryMailTestCase(StorageDatabaseBaseCase):
273
273
  super().setUpClass()
274
274
  cls.params = cls.env["ir.config_parameter"].sudo()
275
275
  cls.params.set_param("mail.catchall.domain", "dmstest.com")
276
- domain = cls.env["mail.alias.domain"].create({"name": "dmstest.com"})
277
- cls.env["mail.alias"].create(
276
+ cls.domain = cls.env["mail.alias.domain"].create({"name": "dmstest.com"})
277
+ cls.alias = cls.env["mail.alias"].create(
278
278
  {
279
279
  "alias_model_id": cls.env["ir.model"]
280
280
  .search([("model", "=", "dms.directory")])
281
281
  .id,
282
- "alias_domain_id": domain.id,
282
+ "alias_domain_id": cls.domain.id,
283
283
  }
284
284
  )
285
285
 
@@ -299,4 +299,7 @@ class DirectoryMailTestCase(StorageDatabaseBaseCase):
299
299
  self.directory.write(
300
300
  {"alias_process": "directory", "alias_name": "directory+test"}
301
301
  )
302
- self._handle_mail_reception()
302
+ self.assertEqual(
303
+ self.directory.alias_id.display_name,
304
+ f"{self.directory.alias_name}@{self.domain.name}",
305
+ )
@@ -52,7 +52,7 @@ class FileDatabaseTestCase(StorageDatabaseBaseCase):
52
52
  def test_rename_file(self):
53
53
  file = self.create_file(directory=self.directory)
54
54
  extension = file.extension
55
- file.write({"name": "test-%s.jpg" % self.env.user.login})
55
+ file.write({"name": f"test-{self.env.user.login}.jpg"})
56
56
  self.assertNotEqual(file.extension, extension, "Extension should be different")
57
57
 
58
58
  @users("dms-manager", "dms-user")
@@ -1,9 +1,10 @@
1
- # Copyright 2021-2022 Tecnativa - Víctor Martínez
1
+ # Copyright 2021-2025 Tecnativa - Víctor Martínez
2
2
  # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl)
3
3
 
4
4
  import odoo.tests
5
5
  from odoo.exceptions import AccessError
6
6
  from odoo.tests.common import users
7
+ from odoo.tools import mute_logger
7
8
 
8
9
  from .common import StorageAttachmentBaseCase
9
10
 
@@ -15,9 +16,6 @@ class TestDmsPortal(odoo.tests.HttpCase, StorageAttachmentBaseCase):
15
16
  super().setUpClass()
16
17
  cls.partner = cls.env.ref("base.partner_demo_portal")
17
18
  cls.portal_user = cls.partner.user_ids
18
- cls.other_portal_user = cls.other_partner.user_ids
19
- cls.portal_user.login = "portal"
20
- cls.other_portal_user.login = "other_portal"
21
19
  cls._create_attachment("test.txt")
22
20
  cls._create_attachment("test2.txt", cls.other_partner)
23
21
  cls.directory_partner = cls._get_partner_directory()
@@ -29,7 +27,7 @@ class TestDmsPortal(odoo.tests.HttpCase, StorageAttachmentBaseCase):
29
27
  self.authenticate("portal", "portal")
30
28
  # 404: Incorrect access_token
31
29
  file_text = self.create_file(directory=self.directory_partner)
32
- url = "%s&access_token=abc-def" % (file_text.access_url)
30
+ url = f"{file_text.access_url}&access_token=abc-def"
33
31
  response = self.url_open(url, timeout=20)
34
32
  self.assertEqual(
35
33
  response.status_code, 404, "Can't access file with incorrect access_token"
@@ -51,41 +49,42 @@ class TestDmsPortal(odoo.tests.HttpCase, StorageAttachmentBaseCase):
51
49
  self.start_tour("/my", tour, login="portal")
52
50
 
53
51
  @users("portal")
52
+ @mute_logger("odoo.addons.base.models.ir_rule")
54
53
  def test_permission_portal_user_access_own_attachment(self):
55
54
  """
56
55
  The user can access its own attachments, even if its access group are not set
57
56
  """
58
57
  # Has to manually su=False because the portal user is not a superuser,
59
58
  # but odoo uses somewhere sudo() internally
60
- file = self.file_partner.with_user(self.portal_user).with_env(
61
- self.env(su=False)
62
- )
63
- directory = self.directory_partner.with_user(self.portal_user).with_env(
59
+ file = self.file_partner.with_user(self.env.user).with_env(self.env(su=False))
60
+ directory = self.directory_partner.with_user(self.env.user).with_env(
64
61
  self.env(su=False)
65
62
  )
66
63
  # Portal user can only read
67
- file.check_access_rule("read")
64
+ file.check_access("read")
68
65
 
69
66
  # Portal user can't do anything else
70
67
  with self.assertRaises(AccessError, msg="Portal user should not have access"):
71
- file.check_access_rule("write")
72
- file.check_access_rule("unlink")
73
- directory.check_access_rule("create")
68
+ file.check_access("write")
69
+ file.check_access("unlink")
70
+ directory.check_access("create")
74
71
 
75
72
  @users("portal")
73
+ @mute_logger("odoo.addons.base.models.ir_rule")
76
74
  def test_permission_portal_user_access_other_attachment(self):
77
75
  """
78
76
  The user can't access other attachments if its access group are not set
79
77
  """
80
78
  # Has to manually su=False because the portal user is not a superuser,
81
79
  # but odoo uses somewhere sudo() internally
82
- file = self.other_file_partner.with_user(self.portal_user).with_env(
80
+ file = self.other_file_partner.with_user(self.env.user).with_env(
83
81
  self.env(su=False)
84
82
  )
83
+ # file.invalidate_recordset()
85
84
  # Portal user can't do anything
86
85
  with self.assertRaises(AccessError, msg="Portal user should not have access"):
87
- file.check_access_rule("read")
86
+ file.check_access("read")
88
87
  with self.assertRaises(AccessError, msg="Portal user should not have access"):
89
- file.check_access_rule("write")
88
+ file.check_access("write")
90
89
  with self.assertRaises(AccessError, msg="Portal user should not have access"):
91
- file.check_access_rule("unlink")
90
+ file.check_access("unlink")
@@ -8,17 +8,17 @@
8
8
  -->
9
9
  <odoo>
10
10
  <record id="view_dms_access_groups_tree" model="ir.ui.view">
11
- <field name="name">dms_access_groups.tree</field>
11
+ <field name="name">dms_access_groups.list</field>
12
12
  <field name="model">dms.access.group</field>
13
13
  <field name="arch" type="xml">
14
- <tree>
14
+ <list>
15
15
  <field name="name" />
16
16
  <field name="perm_create" />
17
17
  <field name="perm_write" />
18
18
  <field name="perm_unlink" />
19
19
  <field name="count_users" />
20
20
  <field name="count_directories" />
21
- </tree>
21
+ </list>
22
22
  </field>
23
23
  </record>
24
24
  <record id="view_dms_access_groups_form" model="ir.ui.view">
@@ -53,41 +53,41 @@
53
53
  <notebook>
54
54
  <page name="users" string="Users">
55
55
  <field name="users">
56
- <tree>
56
+ <list>
57
57
  <field name="name" />
58
58
  <field name="login" />
59
59
  <field name="lang" />
60
60
  <field name="login_date" />
61
- </tree>
61
+ </list>
62
62
  </field>
63
63
  </page>
64
64
  <page name="groups" string="Groups">
65
65
  <field name="group_ids">
66
- <tree>
66
+ <list>
67
67
  <field name="name" />
68
68
  <field name="comment" />
69
- </tree>
69
+ </list>
70
70
  </field>
71
71
  </page>
72
72
  <page name="extra_users" string="Explicit Users">
73
73
  <field name="explicit_user_ids">
74
- <tree>
74
+ <list>
75
75
  <field name="name" />
76
76
  <field name="login" />
77
77
  <field name="lang" />
78
78
  <field name="login_date" />
79
- </tree>
79
+ </list>
80
80
  </field>
81
81
  </page>
82
82
  <page name="childs" string="Child Groups">
83
83
  <field name="child_group_ids">
84
- <tree>
84
+ <list>
85
85
  <field name="name" />
86
86
  <field name="perm_create" />
87
87
  <field name="perm_write" />
88
88
  <field name="perm_unlink" />
89
89
  <field name="count_users" />
90
- </tree>
90
+ </list>
91
91
  </field>
92
92
  </page>
93
93
  <page string="Directories">
@@ -101,11 +101,11 @@
101
101
  <record id="action_dms_access_groups" model="ir.actions.act_window">
102
102
  <field name="name">Access Groups</field>
103
103
  <field name="res_model">dms.access.group</field>
104
- <field name="view_mode">tree,form</field>
104
+ <field name="view_mode">list,form</field>
105
105
  <field
106
106
  name="view_ids"
107
107
  eval="[(5, 0, 0),
108
- (0, 0, {'view_mode': 'tree', 'view_id': ref('view_dms_access_groups_tree')}),
108
+ (0, 0, {'view_mode': 'list', 'view_id': ref('view_dms_access_groups_tree')}),
109
109
  (0, 0, {'view_mode': 'form', 'view_id': ref('view_dms_access_groups_form')})]"
110
110
  />
111
111
  </record>