odoo-addon-base-tier-validation 17.0.1.5.1.4__py3-none-any.whl → 17.0.2.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/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/es.po +122 -3
- odoo/addons/base_tier_validation/i18n/es_MX.po +122 -3
- odoo/addons/base_tier_validation/i18n/fr.po +122 -3
- odoo/addons/base_tier_validation/i18n/it.po +140 -5
- odoo/addons/base_tier_validation/i18n/nl_NL.po +122 -3
- odoo/addons/base_tier_validation/i18n/sv.po +122 -3
- odoo/addons/base_tier_validation/i18n/tr.po +122 -3
- odoo/addons/base_tier_validation/i18n/zh_CN.po +122 -3
- 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.4.dist-info → odoo_addon_base_tier_validation-17.0.2.0.0.2.dist-info}/METADATA +3 -2
- {odoo_addon_base_tier_validation-17.0.1.5.1.4.dist-info → odoo_addon_base_tier_validation-17.0.2.0.0.2.dist-info}/RECORD +26 -24
- {odoo_addon_base_tier_validation-17.0.1.5.1.4.dist-info → odoo_addon_base_tier_validation-17.0.2.0.0.2.dist-info}/WHEEL +0 -0
- {odoo_addon_base_tier_validation-17.0.1.5.1.4.dist-info → odoo_addon_base_tier_validation-17.0.2.0.0.2.dist-info}/top_level.txt +0 -0
@@ -42,6 +42,11 @@ msgid ""
|
|
42
42
|
" !"
|
43
43
|
msgstr ""
|
44
44
|
|
45
|
+
#. module: base_tier_validation
|
46
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_form
|
47
|
+
msgid "<span class=\"oe_edit_only\">Model</span>"
|
48
|
+
msgstr ""
|
49
|
+
|
45
50
|
#. module: base_tier_validation
|
46
51
|
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_definition_view_form
|
47
52
|
msgid "<span class=\"oe_edit_only\">Name</span>"
|
@@ -156,6 +161,15 @@ msgstr "已批准"
|
|
156
161
|
msgid "Archived"
|
157
162
|
msgstr ""
|
158
163
|
|
164
|
+
#. module: base_tier_validation
|
165
|
+
#. odoo-python
|
166
|
+
#: code:addons/base_tier_validation/models/tier_validation_exception.py:0
|
167
|
+
#, python-format
|
168
|
+
msgid ""
|
169
|
+
"At least one of these fields must be checked! Write under Validation, Write "
|
170
|
+
"after Validation"
|
171
|
+
msgstr ""
|
172
|
+
|
159
173
|
#. module: base_tier_validation
|
160
174
|
#: model:ir.model.fields,help:base_tier_validation.field_tier_definition__approve_sequence_bypass
|
161
175
|
#: model:ir.model.fields,help:base_tier_validation.field_tier_review__approve_sequence_bypass
|
@@ -207,6 +221,8 @@ msgstr "审批意见"
|
|
207
221
|
#. module: base_tier_validation
|
208
222
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__company_id
|
209
223
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__company_id
|
224
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__company_id
|
225
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_search
|
210
226
|
msgid "Company"
|
211
227
|
msgstr "公司"
|
212
228
|
|
@@ -215,10 +231,16 @@ msgstr "公司"
|
|
215
231
|
msgid "Config Settings"
|
216
232
|
msgstr ""
|
217
233
|
|
234
|
+
#. module: base_tier_validation
|
235
|
+
#: model_terms:ir.actions.act_window,help:base_tier_validation.tier_validation_exception_action
|
236
|
+
msgid "Create a new Validation Exception!"
|
237
|
+
msgstr ""
|
238
|
+
|
218
239
|
#. module: base_tier_validation
|
219
240
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__create_uid
|
220
241
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__create_uid
|
221
242
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__create_uid
|
243
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__create_uid
|
222
244
|
msgid "Created by"
|
223
245
|
msgstr "创建人"
|
224
246
|
|
@@ -226,6 +248,7 @@ msgstr "创建人"
|
|
226
248
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__create_date
|
227
249
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__create_date
|
228
250
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__create_date
|
251
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__create_date
|
229
252
|
msgid "Created on"
|
230
253
|
msgstr "创建时间"
|
231
254
|
|
@@ -253,6 +276,7 @@ msgstr "说明"
|
|
253
276
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__display_name
|
254
277
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__display_name
|
255
278
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__display_name
|
279
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__display_name
|
256
280
|
msgid "Display Name"
|
257
281
|
msgstr "显示名称"
|
258
282
|
|
@@ -283,6 +307,11 @@ msgstr "审批人"
|
|
283
307
|
msgid "Field in related record"
|
284
308
|
msgstr ""
|
285
309
|
|
310
|
+
#. module: base_tier_validation
|
311
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__field_ids
|
312
|
+
msgid "Fields"
|
313
|
+
msgstr ""
|
314
|
+
|
286
315
|
#. module: base_tier_validation
|
287
316
|
#. odoo-python
|
288
317
|
#: code:addons/base_tier_validation/models/tier_review.py:0
|
@@ -309,6 +338,7 @@ msgstr ""
|
|
309
338
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__id
|
310
339
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__id
|
311
340
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__id
|
341
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__id
|
312
342
|
msgid "ID"
|
313
343
|
msgstr "ID"
|
314
344
|
|
@@ -353,10 +383,21 @@ msgid ""
|
|
353
383
|
"definition are restarted."
|
354
384
|
msgstr ""
|
355
385
|
|
386
|
+
#. module: base_tier_validation
|
387
|
+
#: model_terms:ir.actions.act_window,help:base_tier_validation.tier_validation_exception_action
|
388
|
+
msgid "It's fully validated"
|
389
|
+
msgstr ""
|
390
|
+
|
391
|
+
#. module: base_tier_validation
|
392
|
+
#: model_terms:ir.actions.act_window,help:base_tier_validation.tier_validation_exception_action
|
393
|
+
msgid "It's in the validation process"
|
394
|
+
msgstr ""
|
395
|
+
|
356
396
|
#. module: base_tier_validation
|
357
397
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__write_uid
|
358
398
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__write_uid
|
359
399
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__write_uid
|
400
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__write_uid
|
360
401
|
msgid "Last Updated by"
|
361
402
|
msgstr "最近更新人"
|
362
403
|
|
@@ -364,11 +405,14 @@ msgstr "最近更新人"
|
|
364
405
|
#: model:ir.model.fields,field_description:base_tier_validation.field_comment_wizard__write_date
|
365
406
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__write_date
|
366
407
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_review__write_date
|
408
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__write_date
|
367
409
|
msgid "Last Updated on"
|
368
410
|
msgstr "最近更新时间"
|
369
411
|
|
370
412
|
#. module: base_tier_validation
|
371
413
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__model
|
414
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__model_id
|
415
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__model_name
|
372
416
|
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_definition_view_search
|
373
417
|
msgid "Model"
|
374
418
|
msgstr "模型"
|
@@ -434,6 +478,13 @@ msgstr ""
|
|
434
478
|
msgid "Notify Reviewers on reaching Pending"
|
435
479
|
msgstr ""
|
436
480
|
|
481
|
+
#. module: base_tier_validation
|
482
|
+
#: model_terms:ir.actions.act_window,help:base_tier_validation.tier_validation_exception_action
|
483
|
+
msgid ""
|
484
|
+
"Once created, you can decide which fields you want to be editable when the "
|
485
|
+
"record:"
|
486
|
+
msgstr ""
|
487
|
+
|
437
488
|
#. module: base_tier_validation
|
438
489
|
#. odoo-python
|
439
490
|
#: code:addons/base_tier_validation/models/tier_validation.py:0
|
@@ -587,10 +638,13 @@ msgstr "状态"
|
|
587
638
|
|
588
639
|
#. module: base_tier_validation
|
589
640
|
#. odoo-python
|
590
|
-
#: code:addons/base_tier_validation/models/
|
641
|
+
#: code:addons/base_tier_validation/models/tier_validation_exception.py:0
|
642
|
+
#: model:ir.model.constraint,message:base_tier_validation.constraint_tier_validation_exception_model_company_under_after_unique
|
591
643
|
#, python-format
|
592
|
-
msgid "
|
593
|
-
|
644
|
+
msgid ""
|
645
|
+
"The model already exists for this company with this Write Validation "
|
646
|
+
"configuration!"
|
647
|
+
msgstr ""
|
594
648
|
|
595
649
|
#. module: base_tier_validation
|
596
650
|
#. odoo-python
|
@@ -663,6 +717,18 @@ msgstr "多层级审批(抽象)"
|
|
663
717
|
msgid "Tier Validation Accepted Notification"
|
664
718
|
msgstr "多层级审批(抽象)"
|
665
719
|
|
720
|
+
#. module: base_tier_validation
|
721
|
+
#: model:ir.actions.act_window,name:base_tier_validation.tier_validation_exception_action
|
722
|
+
#: model:ir.ui.menu,name:base_tier_validation.menu_tier_validation_exception
|
723
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_form
|
724
|
+
msgid "Tier Validation Exception"
|
725
|
+
msgstr ""
|
726
|
+
|
727
|
+
#. module: base_tier_validation
|
728
|
+
#: model:ir.model,name:base_tier_validation.model_tier_validation_exception
|
729
|
+
msgid "Tier Validation Exceptions"
|
730
|
+
msgstr ""
|
731
|
+
|
666
732
|
#. module: base_tier_validation
|
667
733
|
#: model:mail.message.subtype,name:base_tier_validation.mt_tier_validation_rejected
|
668
734
|
#, fuzzy
|
@@ -706,6 +772,11 @@ msgstr ""
|
|
706
772
|
msgid "User"
|
707
773
|
msgstr ""
|
708
774
|
|
775
|
+
#. module: base_tier_validation
|
776
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__valid_model_field_ids
|
777
|
+
msgid "Valid Model Field"
|
778
|
+
msgstr ""
|
779
|
+
|
709
780
|
#. module: base_tier_validation
|
710
781
|
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_definition__valid_reviewer_field_ids
|
711
782
|
msgid "Valid Reviewer Field"
|
@@ -772,11 +843,59 @@ msgstr ""
|
|
772
843
|
msgid "Without validation"
|
773
844
|
msgstr ""
|
774
845
|
|
846
|
+
#. module: base_tier_validation
|
847
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__allowed_to_write_after_validation
|
848
|
+
msgid "Write after Validation"
|
849
|
+
msgstr ""
|
850
|
+
|
851
|
+
#. module: base_tier_validation
|
852
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_search
|
853
|
+
msgid "Write after validation"
|
854
|
+
msgstr ""
|
855
|
+
|
856
|
+
#. module: base_tier_validation
|
857
|
+
#: model:ir.model.fields,field_description:base_tier_validation.field_tier_validation_exception__allowed_to_write_under_validation
|
858
|
+
msgid "Write under Validation"
|
859
|
+
msgstr ""
|
860
|
+
|
861
|
+
#. module: base_tier_validation
|
862
|
+
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_validation_exception_search
|
863
|
+
msgid "Write under validation"
|
864
|
+
msgstr ""
|
865
|
+
|
866
|
+
#. module: base_tier_validation
|
867
|
+
#. odoo-python
|
868
|
+
#: code:addons/base_tier_validation/models/tier_validation.py:0
|
869
|
+
#, python-format
|
870
|
+
msgid ""
|
871
|
+
"You are not allowed to write those fields after validation.\n"
|
872
|
+
"- %(not_allowed_fields)s\n"
|
873
|
+
"\n"
|
874
|
+
"Only those fields can be modified:\n"
|
875
|
+
"- %(allowed_fields)s"
|
876
|
+
msgstr ""
|
877
|
+
|
878
|
+
#. module: base_tier_validation
|
879
|
+
#. odoo-python
|
880
|
+
#: code:addons/base_tier_validation/models/tier_validation.py:0
|
881
|
+
#, python-format
|
882
|
+
msgid ""
|
883
|
+
"You are not allowed to write those fields under validation.\n"
|
884
|
+
"- %(not_allowed_fields)s\n"
|
885
|
+
"\n"
|
886
|
+
"Only those fields can be modified:\n"
|
887
|
+
"- %(allowed_fields)s"
|
888
|
+
msgstr ""
|
889
|
+
|
775
890
|
#. module: base_tier_validation
|
776
891
|
#: model_terms:ir.ui.view,arch_db:base_tier_validation.tier_definition_view_form
|
777
892
|
msgid "e.g. Tier Validation for..."
|
778
893
|
msgstr "例如:审批层级用于..."
|
779
894
|
|
895
|
+
#, python-format
|
896
|
+
#~ msgid "The operation is under validation."
|
897
|
+
#~ msgstr "该操作正在审批中。"
|
898
|
+
|
780
899
|
#, python-format
|
781
900
|
#~ msgid "0 Pending"
|
782
901
|
#~ msgstr "0 待审批"
|
@@ -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>
|