odoo-addon-base-tier-validation 17.0.1.5.1.3__py3-none-any.whl → 17.0.2.0.0__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/base_tier_validation/README.rst +2 -1
- odoo/addons/base_tier_validation/__manifest__.py +2 -1
- odoo/addons/base_tier_validation/i18n/base_tier_validation.pot +117 -2
- odoo/addons/base_tier_validation/i18n/it.po +2 -2
- odoo/addons/base_tier_validation/models/__init__.py +1 -0
- odoo/addons/base_tier_validation/models/tier_definition.py +4 -2
- odoo/addons/base_tier_validation/models/tier_validation.py +129 -4
- odoo/addons/base_tier_validation/models/tier_validation_exception.py +95 -0
- odoo/addons/base_tier_validation/readme/CONTRIBUTORS.md +1 -0
- odoo/addons/base_tier_validation/security/ir.model.access.csv +2 -0
- odoo/addons/base_tier_validation/static/description/index.html +9 -5
- odoo/addons/base_tier_validation/tests/test_tier_validation.py +59 -2
- odoo/addons/base_tier_validation/tests/tier_validation_tester.py +2 -0
- odoo/addons/base_tier_validation/views/tier_definition_view.xml +1 -0
- odoo/addons/base_tier_validation/views/tier_validation_exception_view.xml +112 -0
- {odoo_addon_base_tier_validation-17.0.1.5.1.3.dist-info → odoo_addon_base_tier_validation-17.0.2.0.0.dist-info}/METADATA +3 -2
- {odoo_addon_base_tier_validation-17.0.1.5.1.3.dist-info → odoo_addon_base_tier_validation-17.0.2.0.0.dist-info}/RECORD +19 -17
- {odoo_addon_base_tier_validation-17.0.1.5.1.3.dist-info → odoo_addon_base_tier_validation-17.0.2.0.0.dist-info}/WHEEL +0 -0
- {odoo_addon_base_tier_validation-17.0.1.5.1.3.dist-info → odoo_addon_base_tier_validation-17.0.2.0.0.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@ Base Tier Validation
|
|
7
7
|
!! This file is generated by oca-gen-addon-readme !!
|
8
8
|
!! changes will be overwritten. !!
|
9
9
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
10
|
-
!! source digest: sha256:
|
10
|
+
!! source digest: sha256:c6317aa94557d07370f45bb16d3bb54ddbd9f037937958680816482aba127ff2
|
11
11
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
12
12
|
|
13
13
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
|
@@ -235,6 +235,7 @@ Contributors
|
|
235
235
|
- bosd
|
236
236
|
- Evan Soh <evan.soh@omnisoftsolution.com>
|
237
237
|
- Manuel Regidor <manuel.regidor@sygel.es>
|
238
|
+
- Eduardo de Miguel <edu@moduon.team>
|
238
239
|
|
239
240
|
Maintainers
|
240
241
|
-----------
|
@@ -3,7 +3,7 @@
|
|
3
3
|
{
|
4
4
|
"name": "Base Tier Validation",
|
5
5
|
"summary": "Implement a validation process based on tiers.",
|
6
|
-
"version": "17.0.
|
6
|
+
"version": "17.0.2.0.0",
|
7
7
|
"development_status": "Mature",
|
8
8
|
"maintainers": ["LoisRForgeFlow"],
|
9
9
|
"category": "Tools",
|
@@ -20,6 +20,7 @@
|
|
20
20
|
"views/res_config_settings_views.xml",
|
21
21
|
"views/tier_definition_view.xml",
|
22
22
|
"views/tier_review_view.xml",
|
23
|
+
"views/tier_validation_exception_view.xml",
|
23
24
|
"wizard/comment_wizard_view.xml",
|
24
25
|
"templates/tier_validation_templates.xml",
|
25
26
|
],
|
@@ -39,6 +39,11 @@ msgid ""
|
|
39
39
|
" !"
|
40
40
|
msgstr ""
|
41
41
|
|
42
|
+
#. module: base_tier_validation
|
43
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_form
|
44
|
+
msgid "<span class=\"oe_edit_only\">Model</span>"
|
45
|
+
msgstr ""
|
46
|
+
|
42
47
|
#. module: base_tier_validation
|
43
48
|
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_definition_view_form
|
44
49
|
msgid "<span class=\"oe_edit_only\">Name</span>"
|
@@ -153,6 +158,15 @@ msgstr ""
|
|
153
158
|
msgid "Archived"
|
154
159
|
msgstr ""
|
155
160
|
|
161
|
+
#. module: base_tier_validation
|
162
|
+
#. odoo-python
|
163
|
+
#: code:addons/base_tier_validation/models/tier_validation_exception.py:0
|
164
|
+
#, python-format
|
165
|
+
msgid ""
|
166
|
+
"At least one of these fields must be checked! Write under Validation, Write "
|
167
|
+
"after Validation"
|
168
|
+
msgstr ""
|
169
|
+
|
156
170
|
#. module: base_tier_validation
|
157
171
|
#: model:ir.model.fields,help:base_tier_validation.field_tier_definition__approve_sequence_bypass
|
158
172
|
#: model:ir.model.fields,help:base_tier_validation.field_tier_review__approve_sequence_bypass
|
@@ -204,6 +218,8 @@ msgstr ""
|
|
204
218
|
#. module: base_tier_validation
|
205
219
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__company_id
|
206
220
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__company_id
|
221
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__company_id
|
222
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_search
|
207
223
|
msgid "Company"
|
208
224
|
msgstr ""
|
209
225
|
|
@@ -212,10 +228,16 @@ msgstr ""
|
|
212
228
|
msgid "Config Settings"
|
213
229
|
msgstr ""
|
214
230
|
|
231
|
+
#. module: base_tier_validation
|
232
|
+
#: model_terms:ir.actions.act_window,help:base_tier_validation.tier_validation_exception_action
|
233
|
+
msgid "Create a new Validation Exception!"
|
234
|
+
msgstr ""
|
235
|
+
|
215
236
|
#. module: base_tier_validation
|
216
237
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__create_uid
|
217
238
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__create_uid
|
218
239
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__create_uid
|
240
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__create_uid
|
219
241
|
msgid "Created by"
|
220
242
|
msgstr ""
|
221
243
|
|
@@ -223,6 +245,7 @@ msgstr ""
|
|
223
245
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__create_date
|
224
246
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__create_date
|
225
247
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__create_date
|
248
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__create_date
|
226
249
|
msgid "Created on"
|
227
250
|
msgstr ""
|
228
251
|
|
@@ -250,6 +273,7 @@ msgstr ""
|
|
250
273
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__display_name
|
251
274
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__display_name
|
252
275
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__display_name
|
276
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__display_name
|
253
277
|
msgid "Display Name"
|
254
278
|
msgstr ""
|
255
279
|
|
@@ -280,6 +304,11 @@ msgstr ""
|
|
280
304
|
msgid "Field in related record"
|
281
305
|
msgstr ""
|
282
306
|
|
307
|
+
#. module: base_tier_validation
|
308
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__field_ids
|
309
|
+
msgid "Fields"
|
310
|
+
msgstr ""
|
311
|
+
|
283
312
|
#. module: base_tier_validation
|
284
313
|
#. odoo-python
|
285
314
|
#: code:addons/base_tier_validation/models/tier_review.py:0
|
@@ -306,6 +335,7 @@ msgstr ""
|
|
306
335
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__id
|
307
336
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__id
|
308
337
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__id
|
338
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__id
|
309
339
|
msgid "ID"
|
310
340
|
msgstr ""
|
311
341
|
|
@@ -350,10 +380,21 @@ msgid ""
|
|
350
380
|
"definition are restarted."
|
351
381
|
msgstr ""
|
352
382
|
|
383
|
+
#. module: base_tier_validation
|
384
|
+
#: model_terms:ir.actions.act_window,help:base_tier_validation.tier_validation_exception_action
|
385
|
+
msgid "It's fully validated"
|
386
|
+
msgstr ""
|
387
|
+
|
388
|
+
#. module: base_tier_validation
|
389
|
+
#: model_terms:ir.actions.act_window,help:base_tier_validation.tier_validation_exception_action
|
390
|
+
msgid "It's in the validation process"
|
391
|
+
msgstr ""
|
392
|
+
|
353
393
|
#. module: base_tier_validation
|
354
394
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__write_uid
|
355
395
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__write_uid
|
356
396
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__write_uid
|
397
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__write_uid
|
357
398
|
msgid "Last Updated by"
|
358
399
|
msgstr ""
|
359
400
|
|
@@ -361,11 +402,14 @@ msgstr ""
|
|
361
402
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__write_date
|
362
403
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__write_date
|
363
404
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__write_date
|
405
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__write_date
|
364
406
|
msgid "Last Updated on"
|
365
407
|
msgstr ""
|
366
408
|
|
367
409
|
#. module: base_tier_validation
|
368
410
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__model
|
411
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__model_id
|
412
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__model_name
|
369
413
|
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_definition_view_search
|
370
414
|
msgid "Model"
|
371
415
|
msgstr ""
|
@@ -431,6 +475,13 @@ msgstr ""
|
|
431
475
|
msgid "Notify Reviewers on reaching Pending"
|
432
476
|
msgstr ""
|
433
477
|
|
478
|
+
#. module: base_tier_validation
|
479
|
+
#: model_terms:ir.actions.act_window,help:base_tier_validation.tier_validation_exception_action
|
480
|
+
msgid ""
|
481
|
+
"Once created, you can decide which fields you want to be editable when the "
|
482
|
+
"record:"
|
483
|
+
msgstr ""
|
484
|
+
|
434
485
|
#. module: base_tier_validation
|
435
486
|
#. odoo-python
|
436
487
|
#: code:addons/base_tier_validation/models/tier_validation.py:0
|
@@ -584,9 +635,12 @@ msgstr ""
|
|
584
635
|
|
585
636
|
#. module: base_tier_validation
|
586
637
|
#. odoo-python
|
587
|
-
#: code:addons/base_tier_validation/models/
|
638
|
+
#: code:addons/base_tier_validation/models/tier_validation_exception.py:0
|
639
|
+
#: model:ir.model.constraint,message:base_tier_validation.constraint_tier_validation_exception_model_company_under_after_unique
|
588
640
|
#, python-format
|
589
|
-
msgid "
|
641
|
+
msgid ""
|
642
|
+
"The model already exists for this company with this Write Validation "
|
643
|
+
"configuration!"
|
590
644
|
msgstr ""
|
591
645
|
|
592
646
|
#. module: base_tier_validation
|
@@ -657,6 +711,18 @@ msgstr ""
|
|
657
711
|
msgid "Tier Validation Accepted Notification"
|
658
712
|
msgstr ""
|
659
713
|
|
714
|
+
#. module: base_tier_validation
|
715
|
+
#: model:ir.actions.act_window,name:base_tier_validation.tier_validation_exception_action
|
716
|
+
#: model:ir.ui.menu,name:base_tier_validation.menu_tier_validation_exception
|
717
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_form
|
718
|
+
msgid "Tier Validation Exception"
|
719
|
+
msgstr ""
|
720
|
+
|
721
|
+
#. module: base_tier_validation
|
722
|
+
#: model:ir.model,name:base_tier_validation.model_tier_validation_exception
|
723
|
+
msgid "Tier Validation Exceptions"
|
724
|
+
msgstr ""
|
725
|
+
|
660
726
|
#. module: base_tier_validation
|
661
727
|
#: model:mail.message.subtype,name:base_tier_validation.mt_tier_validation_rejected
|
662
728
|
msgid "Tier Validation Rejected Notification"
|
@@ -699,6 +765,11 @@ msgstr ""
|
|
699
765
|
msgid "User"
|
700
766
|
msgstr ""
|
701
767
|
|
768
|
+
#. module: base_tier_validation
|
769
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__valid_model_field_ids
|
770
|
+
msgid "Valid Model Field"
|
771
|
+
msgstr ""
|
772
|
+
|
702
773
|
#. module: base_tier_validation
|
703
774
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__valid_reviewer_field_ids
|
704
775
|
msgid "Valid Reviewer Field"
|
@@ -765,6 +836,50 @@ msgstr ""
|
|
765
836
|
msgid "Without validation"
|
766
837
|
msgstr ""
|
767
838
|
|
839
|
+
#. module: base_tier_validation
|
840
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__allowed_to_write_after_validation
|
841
|
+
msgid "Write after Validation"
|
842
|
+
msgstr ""
|
843
|
+
|
844
|
+
#. module: base_tier_validation
|
845
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_search
|
846
|
+
msgid "Write after validation"
|
847
|
+
msgstr ""
|
848
|
+
|
849
|
+
#. module: base_tier_validation
|
850
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__allowed_to_write_under_validation
|
851
|
+
msgid "Write under Validation"
|
852
|
+
msgstr ""
|
853
|
+
|
854
|
+
#. module: base_tier_validation
|
855
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_search
|
856
|
+
msgid "Write under validation"
|
857
|
+
msgstr ""
|
858
|
+
|
859
|
+
#. module: base_tier_validation
|
860
|
+
#. odoo-python
|
861
|
+
#: code:addons/base_tier_validation/models/tier_validation.py:0
|
862
|
+
#, python-format
|
863
|
+
msgid ""
|
864
|
+
"You are not allowed to write those fields after validation.\n"
|
865
|
+
"- %(not_allowed_fields)s\n"
|
866
|
+
"\n"
|
867
|
+
"Only those fields can be modified:\n"
|
868
|
+
"- %(allowed_fields)s"
|
869
|
+
msgstr ""
|
870
|
+
|
871
|
+
#. module: base_tier_validation
|
872
|
+
#. odoo-python
|
873
|
+
#: code:addons/base_tier_validation/models/tier_validation.py:0
|
874
|
+
#, python-format
|
875
|
+
msgid ""
|
876
|
+
"You are not allowed to write those fields under validation.\n"
|
877
|
+
"- %(not_allowed_fields)s\n"
|
878
|
+
"\n"
|
879
|
+
"Only those fields can be modified:\n"
|
880
|
+
"- %(allowed_fields)s"
|
881
|
+
msgstr ""
|
882
|
+
|
768
883
|
#. module: base_tier_validation
|
769
884
|
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_definition_view_form
|
770
885
|
msgid "e.g. Tier Validation for..."
|
@@ -6,7 +6,7 @@ msgid ""
|
|
6
6
|
msgstr ""
|
7
7
|
"Project-Id-Version: Odoo Server 14.0\n"
|
8
8
|
"Report-Msgid-Bugs-To: \n"
|
9
|
-
"PO-Revision-Date: 2024-
|
9
|
+
"PO-Revision-Date: 2024-06-26 11:27+0000\n"
|
10
10
|
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
|
11
11
|
"Language-Team: none\n"
|
12
12
|
"Language: it\n"
|
@@ -676,7 +676,7 @@ msgstr "Formula livello"
|
|
676
676
|
#. module: base_tier_validation
|
677
677
|
#: model:ir.model,name:base_tier_validation.model_tier_review
|
678
678
|
msgid "Tier Review"
|
679
|
-
msgstr "
|
679
|
+
msgstr "Revisione livello"
|
680
680
|
|
681
681
|
#. module: base_tier_validation
|
682
682
|
#: model_terms:ir.ui.view,arch_db:base_tier_validation.res_config_settings_view_form_budget
|
@@ -108,6 +108,8 @@ class TierDefinition(models.Model):
|
|
108
108
|
@api.depends("review_type", "model_id")
|
109
109
|
def _compute_domain_reviewer_field(self):
|
110
110
|
for rec in self:
|
111
|
-
rec.valid_reviewer_field_ids =
|
112
|
-
[
|
111
|
+
rec.valid_reviewer_field_ids = (
|
112
|
+
self.env["ir.model.fields"]
|
113
|
+
.sudo()
|
114
|
+
.search([("model", "=", rec.model), ("relation", "=", "res.users")])
|
113
115
|
)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# Copyright 2017-19 ForgeFlow S.L. (https://www.forgeflow.com)
|
2
|
+
# Copyright 2024 Moduon Team (https://www.moduon.team)
|
2
3
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
3
4
|
|
4
5
|
from ast import literal_eval
|
@@ -9,6 +10,8 @@ from odoo import _, api, fields, models
|
|
9
10
|
from odoo.exceptions import ValidationError
|
10
11
|
from odoo.tools.misc import frozendict
|
11
12
|
|
13
|
+
BASE_EXCEPTION_FIELDS = ["message_follower_ids", "access_token"]
|
14
|
+
|
12
15
|
|
13
16
|
class TierValidation(models.AbstractModel):
|
14
17
|
_name = "tier.validation"
|
@@ -251,10 +254,43 @@ class TierValidation(models.AbstractModel):
|
|
251
254
|
else:
|
252
255
|
return self
|
253
256
|
|
257
|
+
@api.model
|
258
|
+
def _get_validation_exceptions(self, extra_domain=None, add_base_exceptions=True):
|
259
|
+
"""Return Tier Validation Exception field names that matchs custom domain."""
|
260
|
+
exception_fields = (
|
261
|
+
self.env["tier.validation.exception"]
|
262
|
+
.search(
|
263
|
+
[
|
264
|
+
("model_name", "=", self._name),
|
265
|
+
("company_id", "in", [False] + self.env.company.ids),
|
266
|
+
*(extra_domain or []),
|
267
|
+
]
|
268
|
+
)
|
269
|
+
.mapped("field_ids.name")
|
270
|
+
)
|
271
|
+
if add_base_exceptions:
|
272
|
+
exception_fields = list(set(exception_fields + BASE_EXCEPTION_FIELDS))
|
273
|
+
return exception_fields
|
274
|
+
|
275
|
+
@api.model
|
276
|
+
def _get_all_validation_exceptions(self):
|
277
|
+
"""Extend for more field exceptions to be written when on the entire
|
278
|
+
validation process."""
|
279
|
+
return self._get_validation_exceptions()
|
280
|
+
|
254
281
|
@api.model
|
255
282
|
def _get_under_validation_exceptions(self):
|
256
|
-
"""Extend for more field exceptions."""
|
257
|
-
return
|
283
|
+
"""Extend for more field exceptions to be written under validation."""
|
284
|
+
return self._get_validation_exceptions(
|
285
|
+
extra_domain=[("allowed_to_write_under_validation", "=", True)]
|
286
|
+
)
|
287
|
+
|
288
|
+
@api.model
|
289
|
+
def _get_after_validation_exceptions(self):
|
290
|
+
"""Extend for more field exceptions to be written after validation."""
|
291
|
+
return self._get_validation_exceptions(
|
292
|
+
extra_domain=[("allowed_to_write_after_validation", "=", True)]
|
293
|
+
)
|
258
294
|
|
259
295
|
def _check_allow_write_under_validation(self, vals):
|
260
296
|
"""Allow to add exceptions for fields that are allowed to be written
|
@@ -265,6 +301,36 @@ class TierValidation(models.AbstractModel):
|
|
265
301
|
return False
|
266
302
|
return True
|
267
303
|
|
304
|
+
def _check_allow_write_after_validation(self, vals):
|
305
|
+
"""Allow to add exceptions for fields that are allowed to be written
|
306
|
+
even when the record is after validation."""
|
307
|
+
exceptions = self._get_after_validation_exceptions()
|
308
|
+
for val in vals:
|
309
|
+
if val not in exceptions:
|
310
|
+
return False
|
311
|
+
return True
|
312
|
+
|
313
|
+
def _get_fields_to_write_validation(self, vals, records_exception_function):
|
314
|
+
"""Not allowed fields to write when validation depending
|
315
|
+
on the given function."""
|
316
|
+
exceptions = records_exception_function()
|
317
|
+
not_allowed_fields = []
|
318
|
+
for val in vals:
|
319
|
+
if val not in exceptions:
|
320
|
+
not_allowed_fields.append(val)
|
321
|
+
if not not_allowed_fields:
|
322
|
+
return []
|
323
|
+
|
324
|
+
not_allowed_field_names, allowed_field_names = [], []
|
325
|
+
for fld_name, fld_data in self.fields_get(
|
326
|
+
not_allowed_fields + exceptions
|
327
|
+
).items():
|
328
|
+
if fld_name in not_allowed_fields:
|
329
|
+
not_allowed_field_names.append(fld_data["string"])
|
330
|
+
else:
|
331
|
+
allowed_field_names.append(fld_data["string"])
|
332
|
+
return allowed_field_names, not_allowed_field_names
|
333
|
+
|
268
334
|
def write(self, vals):
|
269
335
|
for rec in self:
|
270
336
|
if rec._check_state_conditions(vals):
|
@@ -286,6 +352,7 @@ class TierValidation(models.AbstractModel):
|
|
286
352
|
"one record."
|
287
353
|
)
|
288
354
|
)
|
355
|
+
# Write under validation
|
289
356
|
if (
|
290
357
|
rec.review_ids
|
291
358
|
and getattr(rec, self._state_field) in self._state_from
|
@@ -294,7 +361,50 @@ class TierValidation(models.AbstractModel):
|
|
294
361
|
and not rec._check_allow_write_under_validation(vals)
|
295
362
|
and not rec._context.get("skip_validation_check")
|
296
363
|
):
|
297
|
-
|
364
|
+
(
|
365
|
+
allowed_fields,
|
366
|
+
not_allowed_fields,
|
367
|
+
) = rec._get_fields_to_write_validation(
|
368
|
+
vals, rec._get_under_validation_exceptions
|
369
|
+
)
|
370
|
+
raise ValidationError(
|
371
|
+
_(
|
372
|
+
"You are not allowed to write those fields under validation.\n"
|
373
|
+
"- %(not_allowed_fields)s\n\n"
|
374
|
+
"Only those fields can be modified:\n- %(allowed_fields)s"
|
375
|
+
)
|
376
|
+
% {
|
377
|
+
"not_allowed_fields": "\n- ".join(not_allowed_fields),
|
378
|
+
"allowed_fields": "\n- ".join(allowed_fields),
|
379
|
+
}
|
380
|
+
)
|
381
|
+
|
382
|
+
# Write after validation. Check only if Tier Validation Exception is created
|
383
|
+
if (
|
384
|
+
rec._get_validation_exceptions(add_base_exceptions=False)
|
385
|
+
and rec.validation_status == "validated"
|
386
|
+
and getattr(rec, self._state_field)
|
387
|
+
in (self._state_to + [self._cancel_state])
|
388
|
+
and not rec._check_allow_write_after_validation(vals)
|
389
|
+
and not rec._context.get("skip_validation_check")
|
390
|
+
):
|
391
|
+
(
|
392
|
+
allowed_fields,
|
393
|
+
not_allowed_fields,
|
394
|
+
) = rec._get_fields_to_write_validation(
|
395
|
+
vals, rec._get_after_validation_exceptions
|
396
|
+
)
|
397
|
+
raise ValidationError(
|
398
|
+
_(
|
399
|
+
"You are not allowed to write those fields after validation.\n"
|
400
|
+
"- %(not_allowed_fields)s\n\n"
|
401
|
+
"Only those fields can be modified:\n- %(allowed_fields)s"
|
402
|
+
)
|
403
|
+
% {
|
404
|
+
"not_allowed_fields": "\n- ".join(not_allowed_fields),
|
405
|
+
"allowed_fields": "\n- ".join(allowed_fields),
|
406
|
+
}
|
407
|
+
)
|
298
408
|
if rec._allow_to_remove_reviews(vals):
|
299
409
|
rec.mapped("review_ids").unlink()
|
300
410
|
return super().write(vals)
|
@@ -422,7 +532,10 @@ class TierValidation(models.AbstractModel):
|
|
422
532
|
lambda x: x.sequence in sequences or x.approve_sequence_bypass
|
423
533
|
)
|
424
534
|
if self.has_comment:
|
425
|
-
|
535
|
+
user_reviews = reviews.filtered(
|
536
|
+
lambda r: r.status == "pending" and (self.env.user in r.reviewer_ids)
|
537
|
+
)
|
538
|
+
return self._add_comment("validate", user_reviews)
|
426
539
|
self._validate_tier(reviews)
|
427
540
|
self._update_counter({"review_deleted": True})
|
428
541
|
|
@@ -622,6 +735,9 @@ class TierValidation(models.AbstractModel):
|
|
622
735
|
new_node = etree.fromstring(str_element)
|
623
736
|
return new_node
|
624
737
|
|
738
|
+
def _get_tier_validation_readonly_domain(self):
|
739
|
+
return "bool(review_ids)"
|
740
|
+
|
625
741
|
@api.model
|
626
742
|
def get_view(self, view_id=None, view_type="form", **options):
|
627
743
|
res = super().get_view(view_id=view_id, view_type=view_type, **options)
|
@@ -662,6 +778,15 @@ class TierValidation(models.AbstractModel):
|
|
662
778
|
all_models[model] = res["models"][model]
|
663
779
|
new_node = etree.fromstring(new_arch)
|
664
780
|
node.append(new_node)
|
781
|
+
excepted_fields = self._get_all_validation_exceptions()
|
782
|
+
for node in doc.xpath("//field[@name][not(ancestor::field)]"):
|
783
|
+
if node.attrib.get("name") in excepted_fields:
|
784
|
+
continue
|
785
|
+
new_r_modifier = self._get_tier_validation_readonly_domain()
|
786
|
+
old_r_modifier = node.attrib.get("readonly")
|
787
|
+
if old_r_modifier:
|
788
|
+
new_r_modifier = f"({old_r_modifier}) or ({new_r_modifier})"
|
789
|
+
node.attrib["readonly"] = new_r_modifier
|
665
790
|
res["arch"] = etree.tostring(doc)
|
666
791
|
res["models"] = frozendict(all_models)
|
667
792
|
return res
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Copyright 2024 Moduon Team (https://www.moduon.team)
|
2
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
3
|
+
|
4
|
+
from odoo import _, api, exceptions, fields, models
|
5
|
+
|
6
|
+
from .tier_validation import BASE_EXCEPTION_FIELDS
|
7
|
+
|
8
|
+
|
9
|
+
class TierValidationException(models.Model):
|
10
|
+
_name = "tier.validation.exception"
|
11
|
+
_description = "Tier Validation Exceptions"
|
12
|
+
_rec_name = "model_name"
|
13
|
+
|
14
|
+
@api.model
|
15
|
+
def _get_tier_validation_model_names(self):
|
16
|
+
return self.env["tier.definition"]._get_tier_validation_model_names()
|
17
|
+
|
18
|
+
model_id = fields.Many2one(
|
19
|
+
comodel_name="ir.model",
|
20
|
+
string="Model",
|
21
|
+
required=True,
|
22
|
+
ondelete="cascade",
|
23
|
+
domain=lambda self: [("model", "in", self._get_tier_validation_model_names())],
|
24
|
+
)
|
25
|
+
model_name = fields.Char(
|
26
|
+
related="model_id.model",
|
27
|
+
string="Model",
|
28
|
+
store=True,
|
29
|
+
readonly=True,
|
30
|
+
index=True,
|
31
|
+
)
|
32
|
+
field_ids = fields.Many2many(
|
33
|
+
comodel_name="ir.model.fields",
|
34
|
+
string="Fields",
|
35
|
+
domain="[('id', 'in', valid_model_field_ids)]",
|
36
|
+
required=True,
|
37
|
+
)
|
38
|
+
valid_model_field_ids = fields.One2many(
|
39
|
+
comodel_name="ir.model.fields",
|
40
|
+
compute="_compute_valid_model_field_ids",
|
41
|
+
)
|
42
|
+
company_id = fields.Many2one(
|
43
|
+
comodel_name="res.company",
|
44
|
+
string="Company",
|
45
|
+
default=lambda self: self.env.company,
|
46
|
+
)
|
47
|
+
allowed_to_write_under_validation = fields.Boolean(
|
48
|
+
string="Write under Validation",
|
49
|
+
default=True,
|
50
|
+
)
|
51
|
+
allowed_to_write_after_validation = fields.Boolean(
|
52
|
+
string="Write after Validation",
|
53
|
+
default=True,
|
54
|
+
)
|
55
|
+
|
56
|
+
@api.depends("model_id")
|
57
|
+
def _compute_valid_model_field_ids(self):
|
58
|
+
for record in self:
|
59
|
+
record.valid_model_field_ids = (
|
60
|
+
self.env["ir.model.fields"]
|
61
|
+
.sudo()
|
62
|
+
.search(
|
63
|
+
[
|
64
|
+
("model", "=", record.model_name),
|
65
|
+
("name", "not in", BASE_EXCEPTION_FIELDS),
|
66
|
+
]
|
67
|
+
)
|
68
|
+
)
|
69
|
+
|
70
|
+
@api.constrains(
|
71
|
+
"allowed_to_write_under_validation", "allowed_to_write_after_validation"
|
72
|
+
)
|
73
|
+
def _check_allowed_to_write(self):
|
74
|
+
if (
|
75
|
+
not self.allowed_to_write_under_validation
|
76
|
+
and not self.allowed_to_write_after_validation
|
77
|
+
):
|
78
|
+
raise exceptions.ValidationError(
|
79
|
+
_(
|
80
|
+
"At least one of these fields must be checked! "
|
81
|
+
"Write under Validation, Write after Validation"
|
82
|
+
)
|
83
|
+
)
|
84
|
+
|
85
|
+
_sql_constraints = [
|
86
|
+
(
|
87
|
+
"model_company_under_after_unique",
|
88
|
+
"unique(model_id, company_id, "
|
89
|
+
"allowed_to_write_under_validation, allowed_to_write_after_validation)",
|
90
|
+
_(
|
91
|
+
"The model already exists for this company with this "
|
92
|
+
"Write Validation configuration!"
|
93
|
+
),
|
94
|
+
)
|
95
|
+
]
|
@@ -7,3 +7,5 @@ access_tier_review,access.tier.review,model_tier_review,base.group_user,1,1,1,1
|
|
7
7
|
access_tier_definition_all,tier.definition.all,model_tier_definition,base.group_user,1,0,0,0
|
8
8
|
access_tier_definition_settings,tier.definition.settings,model_tier_definition,base.group_system,1,1,1,1
|
9
9
|
access_comment_wizard,access.comment.wizard,model_comment_wizard,base.group_user,1,1,1,1
|
10
|
+
access_tier_validation_exceptions_all,tier.validation.exceptions,model_tier_validation_exception,,1,0,0,0
|
11
|
+
access_tier_validation_exceptions_settings,tier.validation.exceptions,model_tier_validation_exception,base.group_system,1,1,1,1
|
@@ -8,10 +8,11 @@
|
|
8
8
|
|
9
9
|
/*
|
10
10
|
:Author: David Goodger (goodger@python.org)
|
11
|
-
:Id: $Id: html4css1.css
|
11
|
+
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
|
12
12
|
:Copyright: This stylesheet has been placed in the public domain.
|
13
13
|
|
14
14
|
Default cascading style sheet for the HTML output of Docutils.
|
15
|
+
Despite the name, some widely supported CSS2 features are used.
|
15
16
|
|
16
17
|
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
17
18
|
customize this style sheet.
|
@@ -274,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
|
|
274
275
|
margin-left: 2em ;
|
275
276
|
margin-right: 2em }
|
276
277
|
|
277
|
-
pre.code .ln { color:
|
278
|
+
pre.code .ln { color: gray; } /* line numbers */
|
278
279
|
pre.code, code { background-color: #eeeeee }
|
279
280
|
pre.code .comment, code .comment { color: #5C6576 }
|
280
281
|
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
@@ -300,7 +301,7 @@ span.option {
|
|
300
301
|
span.pre {
|
301
302
|
white-space: pre }
|
302
303
|
|
303
|
-
span.problematic {
|
304
|
+
span.problematic, pre.problematic {
|
304
305
|
color: red }
|
305
306
|
|
306
307
|
span.section-subtitle {
|
@@ -366,7 +367,7 @@ ul.auto-toc {
|
|
366
367
|
!! This file is generated by oca-gen-addon-readme !!
|
367
368
|
!! changes will be overwritten. !!
|
368
369
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
369
|
-
!! source digest: sha256:
|
370
|
+
!! source digest: sha256:c6317aa94557d07370f45bb16d3bb54ddbd9f037937958680816482aba127ff2
|
370
371
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
371
372
|
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Mature" src="https://img.shields.io/badge/maturity-Mature-brightgreen.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-ux/tree/17.0/base_tier_validation"><img alt="OCA/server-ux" src="https://img.shields.io/badge/github-OCA%2Fserver--ux-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-ux-17-0/server-ux-17-0-base_tier_validation"><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/server-ux&target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
372
373
|
<p>Validating some operations is a common need across different areas in a
|
@@ -588,12 +589,15 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|
588
589
|
<li>bosd</li>
|
589
590
|
<li>Evan Soh <<a class="reference external" href="mailto:evan.soh@omnisoftsolution.com">evan.soh@omnisoftsolution.com</a>></li>
|
590
591
|
<li>Manuel Regidor <<a class="reference external" href="mailto:manuel.regidor@sygel.es">manuel.regidor@sygel.es</a>></li>
|
592
|
+
<li>Eduardo de Miguel <<a class="reference external" href="mailto:edu@moduon.team">edu@moduon.team</a>></li>
|
591
593
|
</ul>
|
592
594
|
</div>
|
593
595
|
<div class="section" id="maintainers">
|
594
596
|
<h2><a class="toc-backref" href="#toc-entry-23">Maintainers</a></h2>
|
595
597
|
<p>This module is maintained by the OCA.</p>
|
596
|
-
<a class="reference external image-reference" href="https://odoo-community.org"
|
598
|
+
<a class="reference external image-reference" href="https://odoo-community.org">
|
599
|
+
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
600
|
+
</a>
|
597
601
|
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
598
602
|
mission is to support the collaborative development of Odoo features and
|
599
603
|
promote its widespread use.</p>
|
@@ -2,12 +2,16 @@
|
|
2
2
|
# Copyright (c) 2022 brain-tec AG (https://braintec.com)
|
3
3
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
|
4
4
|
|
5
|
+
from unittest import mock
|
6
|
+
|
5
7
|
from lxml import etree
|
6
8
|
|
7
9
|
from odoo.exceptions import ValidationError
|
8
10
|
from odoo.tests import Form
|
9
11
|
from odoo.tests.common import tagged
|
10
12
|
|
13
|
+
from ..models.tier_validation import BASE_EXCEPTION_FIELDS as BEF
|
14
|
+
from ..models.tier_validation import TierValidation as TV
|
11
15
|
from .common import CommonTierValidation
|
12
16
|
|
13
17
|
|
@@ -158,13 +162,14 @@ class TierTierValidation(CommonTierValidation):
|
|
158
162
|
self.assertTrue(review)
|
159
163
|
record = test_record.with_user(self.test_user_1.id)
|
160
164
|
record.invalidate_model()
|
165
|
+
review.invalidate_model()
|
161
166
|
res = record.validate_tier()
|
162
167
|
ctx = res.get("context")
|
163
168
|
wizard = Form(self.env["comment.wizard"].with_context(**ctx))
|
164
169
|
wizard.comment = "Test Comment"
|
165
170
|
wiz = wizard.save()
|
166
171
|
wiz.add_comment()
|
167
|
-
self.assertTrue(test_record.review_ids.
|
172
|
+
self.assertTrue(test_record.review_ids.filtered("comment"))
|
168
173
|
# Check notify
|
169
174
|
comment = test_record.with_user(
|
170
175
|
self.test_user_1.id
|
@@ -193,13 +198,14 @@ class TierTierValidation(CommonTierValidation):
|
|
193
198
|
self.assertTrue(review)
|
194
199
|
record = test_record.with_user(self.test_user_1.id)
|
195
200
|
record.invalidate_model()
|
201
|
+
review.invalidate_model()
|
196
202
|
res = record.reject_tier() # Rejection
|
197
203
|
ctx = res.get("context")
|
198
204
|
wizard = Form(self.env["comment.wizard"].with_context(**ctx))
|
199
205
|
wizard.comment = "Test Comment"
|
200
206
|
wiz = wizard.save()
|
201
207
|
wiz.add_comment()
|
202
|
-
self.assertTrue(test_record.review_ids.
|
208
|
+
self.assertTrue(test_record.review_ids.filtered("comment"))
|
203
209
|
# Check notify
|
204
210
|
comment = test_record.with_user(
|
205
211
|
self.test_user_1.id
|
@@ -917,6 +923,57 @@ class TierTierValidation(CommonTierValidation):
|
|
917
923
|
)
|
918
924
|
self.assertEqual(notifications_no_2, notifications_no_1)
|
919
925
|
|
926
|
+
def test_25_change_field_exception_validation(self):
|
927
|
+
"""Test under and after validations"""
|
928
|
+
# Cannot create `tier.validation.exception` records because
|
929
|
+
# `tier.validation.tester` are fake model and its fields are
|
930
|
+
# not propagated to the DDBB and cannot read from `ir.model.fields`.
|
931
|
+
# We will use the mock.patch instead.
|
932
|
+
_tvf = ["test_validation_field"]
|
933
|
+
_rv = _tvf + BEF
|
934
|
+
self.assertEqual(self.test_record.test_validation_field, 0)
|
935
|
+
self.assertFalse(self.test_record.review_ids)
|
936
|
+
reviews = self.test_record.with_user(self.test_user_2.id).request_validation()
|
937
|
+
self.assertTrue(reviews)
|
938
|
+
self.test_record.invalidate_model()
|
939
|
+
self.assertTrue(self.test_record.review_ids)
|
940
|
+
# Unable to write test_validation_field under validation
|
941
|
+
with self.assertRaises(ValidationError):
|
942
|
+
self.test_record.with_user(self.test_user_2.id).write(
|
943
|
+
{"test_validation_field": 1}
|
944
|
+
)
|
945
|
+
# Able to write test_validation_field under validation
|
946
|
+
with mock.patch.object(
|
947
|
+
TV, "_get_under_validation_exceptions", return_value=_rv
|
948
|
+
):
|
949
|
+
self.test_record.with_user(self.test_user_2.id).write(
|
950
|
+
{"test_validation_field": 2}
|
951
|
+
)
|
952
|
+
self.assertEqual(self.test_record.test_validation_field, 2)
|
953
|
+
# Validate record
|
954
|
+
record = self.test_record.with_user(self.test_user_1.id)
|
955
|
+
record.invalidate_model()
|
956
|
+
record.validate_tier()
|
957
|
+
record.action_confirm()
|
958
|
+
self.assertTrue(record.validated)
|
959
|
+
# Unable to write test_validation_field after validation
|
960
|
+
with self.assertRaises(ValidationError):
|
961
|
+
# Simulate there are fields, but not test_validation_field
|
962
|
+
with mock.patch.object(TV, "_get_validation_exceptions", return_value=BEF):
|
963
|
+
self.test_record.with_user(self.test_user_2.id).write(
|
964
|
+
{"test_validation_field": 3}
|
965
|
+
)
|
966
|
+
# Able to write test_validation_field after validation
|
967
|
+
with mock.patch.multiple(
|
968
|
+
TV,
|
969
|
+
_get_validation_exceptions=mock.MagicMock(return_value=_tvf),
|
970
|
+
_get_after_validation_exceptions=mock.MagicMock(return_value=_rv),
|
971
|
+
):
|
972
|
+
self.test_record.with_user(self.test_user_2.id).write(
|
973
|
+
{"test_validation_field": 4}
|
974
|
+
)
|
975
|
+
self.assertEqual(self.test_record.test_validation_field, 4)
|
976
|
+
|
920
977
|
|
921
978
|
@tagged("at_install")
|
922
979
|
class TierTierValidationView(CommonTierValidation):
|
@@ -18,6 +18,7 @@ class TierValidationTester(models.Model):
|
|
18
18
|
],
|
19
19
|
default="draft",
|
20
20
|
)
|
21
|
+
test_validation_field = fields.Integer(default=0)
|
21
22
|
test_field = fields.Float()
|
22
23
|
user_id = fields.Many2one(string="Assigned to:", comodel_name="res.users")
|
23
24
|
|
@@ -40,6 +41,7 @@ class TierValidationTester2(models.Model):
|
|
40
41
|
default="draft",
|
41
42
|
)
|
42
43
|
test_field = fields.Float()
|
44
|
+
test_validation_field = fields.Float()
|
43
45
|
user_id = fields.Many2one(string="Assigned to:", comodel_name="res.users")
|
44
46
|
|
45
47
|
def action_confirm(self):
|
@@ -0,0 +1,112 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<!-- Copyright 2024 Moduon Team (https://www.moduon.team)
|
3
|
+
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
4
|
+
<odoo>
|
5
|
+
<record id="tier_validation_exception_tree" model="ir.ui.view">
|
6
|
+
<field name="name">tier.validation.exception.tree</field>
|
7
|
+
<field name="model">tier.validation.exception</field>
|
8
|
+
<field name="arch" type="xml">
|
9
|
+
<tree>
|
10
|
+
<field name="model_id" />
|
11
|
+
<field name="field_ids" widget="many2many_tags" optional="show" />
|
12
|
+
<field name="company_id" groups="base.group_multi_company" />
|
13
|
+
<field name="allowed_to_write_under_validation" />
|
14
|
+
<field name="allowed_to_write_after_validation" />
|
15
|
+
</tree>
|
16
|
+
</field>
|
17
|
+
</record>
|
18
|
+
|
19
|
+
<record id="tier_validation_exception_form" model="ir.ui.view">
|
20
|
+
<field name="name">tier.validation.exception.form</field>
|
21
|
+
<field name="model">tier.validation.exception</field>
|
22
|
+
<field name="arch" type="xml">
|
23
|
+
<form string="Tier Validation Exception">
|
24
|
+
<sheet>
|
25
|
+
<div class="oe_title">
|
26
|
+
<span class="oe_edit_only">Model</span>
|
27
|
+
<h1>
|
28
|
+
<field
|
29
|
+
name="model_id"
|
30
|
+
options="{'no_create': True, 'no_open': True}"
|
31
|
+
/>
|
32
|
+
</h1>
|
33
|
+
</div>
|
34
|
+
<group>
|
35
|
+
<group name="left">
|
36
|
+
<field name="valid_model_field_ids" invisible="1" />
|
37
|
+
<field
|
38
|
+
name="field_ids"
|
39
|
+
widget="many2many_tags"
|
40
|
+
options="{'no_create': True}"
|
41
|
+
/>
|
42
|
+
<field
|
43
|
+
name="company_id"
|
44
|
+
groups="base.group_multi_company"
|
45
|
+
/>
|
46
|
+
</group>
|
47
|
+
<group name="right">
|
48
|
+
<field name="allowed_to_write_under_validation" />
|
49
|
+
<field name="allowed_to_write_after_validation" />
|
50
|
+
</group>
|
51
|
+
</group>
|
52
|
+
</sheet>
|
53
|
+
</form>
|
54
|
+
</field>
|
55
|
+
</record>
|
56
|
+
|
57
|
+
<record id="tier_validation_exception_search" model="ir.ui.view">
|
58
|
+
<field name="name">tier.validation.exception.search</field>
|
59
|
+
<field name="model">tier.validation.exception</field>
|
60
|
+
<field name="arch" type="xml">
|
61
|
+
<search>
|
62
|
+
<field name="model_id" />
|
63
|
+
<field name="field_ids" />
|
64
|
+
<field name="company_id" groups="base.group_multi_company" />
|
65
|
+
<separator />
|
66
|
+
<filter
|
67
|
+
string="Write under validation"
|
68
|
+
name="flt_allowed_to_write_under_validation_true"
|
69
|
+
domain="[('allowed_to_write_under_validation', '=', True)]"
|
70
|
+
/>
|
71
|
+
<filter
|
72
|
+
string="Write after validation"
|
73
|
+
name="flt_allowed_to_write_after_validation_true"
|
74
|
+
domain="[('allowed_to_write_after_validation', '=', True)]"
|
75
|
+
/>
|
76
|
+
<group>
|
77
|
+
<filter
|
78
|
+
string="Company"
|
79
|
+
name="grp_company"
|
80
|
+
domain="[]"
|
81
|
+
context="{'group_by': 'company_id'}"
|
82
|
+
/>
|
83
|
+
</group>
|
84
|
+
</search>
|
85
|
+
</field>
|
86
|
+
</record>
|
87
|
+
|
88
|
+
<record id="tier_validation_exception_action" model="ir.actions.act_window">
|
89
|
+
<field name="name">Tier Validation Exception</field>
|
90
|
+
<field name="type">ir.actions.act_window</field>
|
91
|
+
<field name="res_model">tier.validation.exception</field>
|
92
|
+
<field name="view_mode">tree,form</field>
|
93
|
+
<field name="help" type="html">
|
94
|
+
<p
|
95
|
+
class="o_view_nocontent_smiling_face"
|
96
|
+
>Create a new Validation Exception!</p>
|
97
|
+
<p
|
98
|
+
>Once created, you can decide which fields you want to be editable when the record:</p>
|
99
|
+
<ul>
|
100
|
+
<li>It's in the validation process</li>
|
101
|
+
<li>It's fully validated</li>
|
102
|
+
</ul>
|
103
|
+
</field>
|
104
|
+
</record>
|
105
|
+
|
106
|
+
<menuitem
|
107
|
+
id="menu_tier_validation_exception"
|
108
|
+
parent="menu_tier_confirmation"
|
109
|
+
action="tier_validation_exception_action"
|
110
|
+
sequence="20"
|
111
|
+
/>
|
112
|
+
</odoo>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: odoo-addon-base_tier_validation
|
3
|
-
Version: 17.0.
|
3
|
+
Version: 17.0.2.0.0
|
4
4
|
Requires-Python: >=3.10
|
5
5
|
Requires-Dist: odoo>=17.0a,<17.1dev
|
6
6
|
Summary: Implement a validation process based on tiers.
|
@@ -23,7 +23,7 @@ Base Tier Validation
|
|
23
23
|
!! This file is generated by oca-gen-addon-readme !!
|
24
24
|
!! changes will be overwritten. !!
|
25
25
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
26
|
-
!! source digest: sha256:
|
26
|
+
!! source digest: sha256:c6317aa94557d07370f45bb16d3bb54ddbd9f037937958680816482aba127ff2
|
27
27
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
28
28
|
|
29
29
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
|
@@ -251,6 +251,7 @@ Contributors
|
|
251
251
|
- bosd
|
252
252
|
- Evan Soh <evan.soh@omnisoftsolution.com>
|
253
253
|
- Manuel Regidor <manuel.regidor@sygel.es>
|
254
|
+
- Eduardo de Miguel <edu@moduon.team>
|
254
255
|
|
255
256
|
Maintainers
|
256
257
|
-----------
|
@@ -1,31 +1,32 @@
|
|
1
|
-
odoo/addons/base_tier_validation/README.rst,sha256=
|
1
|
+
odoo/addons/base_tier_validation/README.rst,sha256=_rWFCAo-c-7hzpvRCmjzhlBM2l6Sb4y1d9-b2z-_Hgo,7566
|
2
2
|
odoo/addons/base_tier_validation/__init__.py,sha256=rKfzYX9RhkkCxgh2f0PJLYN45Kw8T8-fwxw1pbjLuug,108
|
3
|
-
odoo/addons/base_tier_validation/__manifest__.py,sha256=
|
3
|
+
odoo/addons/base_tier_validation/__manifest__.py,sha256=ucZRGbnNu0J2mV4NgQDs7WpsRlGE59h8AEna26rdoFQ,1658
|
4
4
|
odoo/addons/base_tier_validation/data/mail_data.xml,sha256=UKzkLT8rYrFuThdp43v7nLW5SOco4vvIIAhbB_IAQZs,1414
|
5
|
-
odoo/addons/base_tier_validation/i18n/base_tier_validation.pot,sha256=
|
5
|
+
odoo/addons/base_tier_validation/i18n/base_tier_validation.pot,sha256=8v7x8P7bvRckBkHImSDiOALz-5viZ1Lq2Rkd_tkdsIA,31437
|
6
6
|
odoo/addons/base_tier_validation/i18n/es.po,sha256=1mrTc0uRWxDdBlub8QIZwsKoE6t28vT_YniNN1gnlr0,32571
|
7
7
|
odoo/addons/base_tier_validation/i18n/es_MX.po,sha256=jZqztOsZHTRMOY9d2iK1OG0HYCufAhuFK9cGoXvJ2KE,30201
|
8
8
|
odoo/addons/base_tier_validation/i18n/fr.po,sha256=nxS-gcZ8rtqdX6IJbIDRpj6tWw2s-d3GQTJ0IjFzZaA,31207
|
9
|
-
odoo/addons/base_tier_validation/i18n/it.po,sha256=
|
9
|
+
odoo/addons/base_tier_validation/i18n/it.po,sha256=4IqjboE5CTUuD7XDM_7zX1fcKtJ1Els3laTg8QfDEwM,32119
|
10
10
|
odoo/addons/base_tier_validation/i18n/nl_NL.po,sha256=8-gfWvAqGgFjX5EE9FMeypSFsAp_mSX6McCIdBFE5h0,30500
|
11
11
|
odoo/addons/base_tier_validation/i18n/sv.po,sha256=b9nhAtjUwRplMD4yygEQejqyFDK9X1PjBC5KOnS1hC8,32686
|
12
12
|
odoo/addons/base_tier_validation/i18n/tr.po,sha256=kJCCMKVkULuJjhh5SHf2SK7Pu03fmMaBuoNckKd2MSY,30073
|
13
13
|
odoo/addons/base_tier_validation/i18n/zh_CN.po,sha256=0gJMwbLvUSNpV64Yl9S49sr5Mb9mHeuPyFN9yE2lnQ4,28624
|
14
|
-
odoo/addons/base_tier_validation/models/__init__.py,sha256=
|
14
|
+
odoo/addons/base_tier_validation/models/__init__.py,sha256=X8c8CFM5eOXyIErFr7xsaGDBPZMBSKE2v4W-_2h9B2s,250
|
15
15
|
odoo/addons/base_tier_validation/models/res_config_settings.py,sha256=xMdQiCfU5p7Z5puKcSRvJihLpI9ulyVFUd_QJjAOuwc,619
|
16
16
|
odoo/addons/base_tier_validation/models/res_users.py,sha256=JhUZ0NxJ9EPwpkJ-mvsNTrE1avQncGNKqAF-xFxokEo,2638
|
17
|
-
odoo/addons/base_tier_validation/models/tier_definition.py,sha256=
|
17
|
+
odoo/addons/base_tier_validation/models/tier_definition.py,sha256=I-HeOZopA1n-bISs28XDeAosUrTnhL_mp_TB3awb2w0,4168
|
18
18
|
odoo/addons/base_tier_validation/models/tier_review.py,sha256=vuR832VVM-ZUDm-4j9zK1BSNnL0JfesxBSLyhW4Zia8,6754
|
19
|
-
odoo/addons/base_tier_validation/models/tier_validation.py,sha256=
|
19
|
+
odoo/addons/base_tier_validation/models/tier_validation.py,sha256=I-I5q68QdDAALJeUzgN-xSj-UQN7sOk0cx5QFdz-qOI,32602
|
20
|
+
odoo/addons/base_tier_validation/models/tier_validation_exception.py,sha256=wlzi9q3oS5YwYdJed6CqO9CRdj9MQWr5-Y0GIZnZkJE,2992
|
20
21
|
odoo/addons/base_tier_validation/readme/CONFIGURE.md,sha256=95NOZLcm0wpb4a8gC89YlSibj7GZ1kz5IbDsuqaaNII,752
|
21
|
-
odoo/addons/base_tier_validation/readme/CONTRIBUTORS.md,sha256=
|
22
|
+
odoo/addons/base_tier_validation/readme/CONTRIBUTORS.md,sha256=J7LBj933qFHjWwQrkaxWQUhFE-O3rqObqyRw96H5dpc,545
|
22
23
|
odoo/addons/base_tier_validation/readme/DESCRIPTION.md,sha256=nFbYOx89EsI26v6NJF9d-Wm-X2YtHduSRlV5Euk3WWc,651
|
23
24
|
odoo/addons/base_tier_validation/readme/HISTORY.md,sha256=P8GfoUhYG7QGIpa8Z0L67E3YEeZBFQCwpDXnt5WG-DY,1332
|
24
25
|
odoo/addons/base_tier_validation/readme/ROADMAP.md,sha256=HRRQQuOlSeOF5yfqG0KuANnvrde8y6Suz2pbrXB1OyU,864
|
25
|
-
odoo/addons/base_tier_validation/security/ir.model.access.csv,sha256=
|
26
|
+
odoo/addons/base_tier_validation/security/ir.model.access.csv,sha256=g6B58IuYYqxD54e9I9vyre7mD74tkpauqTqMAH4Oey0,1134
|
26
27
|
odoo/addons/base_tier_validation/security/tier_validation_security.xml,sha256=eWFwz-osHgYFmVoEVzOSboO9oqUMtQ8oygyaz0os50Y,806
|
27
28
|
odoo/addons/base_tier_validation/static/description/icon.png,sha256=6xBPJauaFOF0KDHfHgQopSc28kKvxMaeoQFQWZtfZDo,9455
|
28
|
-
odoo/addons/base_tier_validation/static/description/index.html,sha256=
|
29
|
+
odoo/addons/base_tier_validation/static/description/index.html,sha256=IpKrO7kJcxmH9DDFqbPtiR0Nxo_xUiAILXHRqeIskSw,21892
|
29
30
|
odoo/addons/base_tier_validation/static/src/components/tier_review_menu/tier_review_menu.esm.js,sha256=MNfjKSg-9h3JfeXiYlf15SAdVHjj3aUvedj0BqVvJrk,2254
|
30
31
|
odoo/addons/base_tier_validation/static/src/components/tier_review_menu/tier_review_menu.xml,sha256=_wIy5Gv2VUJEXD5_FGphx1J19-Y8uzFlWryuPqlIh8c,2798
|
31
32
|
odoo/addons/base_tier_validation/static/src/components/tier_review_widget/tier_review_widget.esm.js,sha256=MDWUp2ozeRdBoLeCfTcOnD-bKnk3yF6pHwtTAnsLZmg,1090
|
@@ -35,15 +36,16 @@ odoo/addons/base_tier_validation/static/src/js/services/tier_review_service.esm.
|
|
35
36
|
odoo/addons/base_tier_validation/templates/tier_validation_templates.xml,sha256=VI6kY0V6nVSz6KQ9GRxY_9TZkRrJgzBzsl9xFKtA__Y,3620
|
36
37
|
odoo/addons/base_tier_validation/tests/__init__.py,sha256=3z2_lQ9JiDSFDam4p24qDw5j02iaPb4m2naxv9DkbGA,122
|
37
38
|
odoo/addons/base_tier_validation/tests/common.py,sha256=Q0g3zv6cYrSPx8QHwsikFxRmi7TtmuUr4ID_9WvImd8,4504
|
38
|
-
odoo/addons/base_tier_validation/tests/test_tier_validation.py,sha256=
|
39
|
-
odoo/addons/base_tier_validation/tests/tier_validation_tester.py,sha256=
|
39
|
+
odoo/addons/base_tier_validation/tests/test_tier_validation.py,sha256=7l1kfCv31dqzNgAirZMaQM5OVvaA2OvJ7uAc0O7PLYw,41566
|
40
|
+
odoo/addons/base_tier_validation/tests/tier_validation_tester.py,sha256=3usFbhfDhlKIWbVu--3qsbsm52B6RwTP4zy244dY1yk,1757
|
40
41
|
odoo/addons/base_tier_validation/views/res_config_settings_views.xml,sha256=5HbrsAVaXRoQNX7utIQ_EzZrqzKnwBrV9uHsi-PHb9M,2640
|
41
|
-
odoo/addons/base_tier_validation/views/tier_definition_view.xml,sha256=
|
42
|
+
odoo/addons/base_tier_validation/views/tier_definition_view.xml,sha256=FHpO2tW8FYKQffayERVlQEJH_ip8baZ7nC1NcFDsP7Y,7635
|
42
43
|
odoo/addons/base_tier_validation/views/tier_review_view.xml,sha256=tPzmpz-kbQwOOtJrAcsTJEP9bJLcfzWAITCpI86kZU4,966
|
44
|
+
odoo/addons/base_tier_validation/views/tier_validation_exception_view.xml,sha256=aLh_jOIpEl4ScujerORyc2e4ANNVce3GVVf7Jo3waPg,4685
|
43
45
|
odoo/addons/base_tier_validation/wizard/__init__.py,sha256=52q6-LAjYeJ1Vu5ahon_jnhds9VsoJvYaQCiZc82WKw,95
|
44
46
|
odoo/addons/base_tier_validation/wizard/comment_wizard.py,sha256=gj7zCcpe47-2ifxSRlE6okQ1wtq5Ok3JBVg2CtN0ZIU,879
|
45
47
|
odoo/addons/base_tier_validation/wizard/comment_wizard_view.xml,sha256=9XFTqrNwDCZH2IEX3HutaznSkBYk-6RERXzUDwObz4I,979
|
46
|
-
odoo_addon_base_tier_validation-17.0.
|
47
|
-
odoo_addon_base_tier_validation-17.0.
|
48
|
-
odoo_addon_base_tier_validation-17.0.
|
49
|
-
odoo_addon_base_tier_validation-17.0.
|
48
|
+
odoo_addon_base_tier_validation-17.0.2.0.0.dist-info/METADATA,sha256=aeKefD3we4EbPnj3PBs4Fm05tiFqOZiBOVq3KgE5e40,8162
|
49
|
+
odoo_addon_base_tier_validation-17.0.2.0.0.dist-info/WHEEL,sha256=8Rd4enx1PCuyDWP4SABqO5Fv8rpaknqp3VzjoFFLa6c,83
|
50
|
+
odoo_addon_base_tier_validation-17.0.2.0.0.dist-info/top_level.txt,sha256=QE6RBQ0QX5f4eFuUcGgU5Kbq1A_qJcDs-e_vpr6pmfU,4
|
51
|
+
odoo_addon_base_tier_validation-17.0.2.0.0.dist-info/RECORD,,
|
File without changes
|