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.
Files changed (26) hide show
  1. odoo/addons/base_tier_validation/README.rst +2 -1
  2. odoo/addons/base_tier_validation/__manifest__.py +2 -1
  3. odoo/addons/base_tier_validation/i18n/base_tier_validation.pot +117 -2
  4. odoo/addons/base_tier_validation/i18n/es.po +122 -3
  5. odoo/addons/base_tier_validation/i18n/es_MX.po +122 -3
  6. odoo/addons/base_tier_validation/i18n/fr.po +122 -3
  7. odoo/addons/base_tier_validation/i18n/it.po +140 -5
  8. odoo/addons/base_tier_validation/i18n/nl_NL.po +122 -3
  9. odoo/addons/base_tier_validation/i18n/sv.po +122 -3
  10. odoo/addons/base_tier_validation/i18n/tr.po +122 -3
  11. odoo/addons/base_tier_validation/i18n/zh_CN.po +122 -3
  12. odoo/addons/base_tier_validation/models/__init__.py +1 -0
  13. odoo/addons/base_tier_validation/models/tier_definition.py +4 -2
  14. odoo/addons/base_tier_validation/models/tier_validation.py +129 -4
  15. odoo/addons/base_tier_validation/models/tier_validation_exception.py +95 -0
  16. odoo/addons/base_tier_validation/readme/CONTRIBUTORS.md +1 -0
  17. odoo/addons/base_tier_validation/security/ir.model.access.csv +2 -0
  18. odoo/addons/base_tier_validation/static/description/index.html +9 -5
  19. odoo/addons/base_tier_validation/tests/test_tier_validation.py +59 -2
  20. odoo/addons/base_tier_validation/tests/tier_validation_tester.py +2 -0
  21. odoo/addons/base_tier_validation/views/tier_definition_view.xml +1 -0
  22. odoo/addons/base_tier_validation/views/tier_validation_exception_view.xml +112 -0
  23. {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
  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}/RECORD +26 -24
  25. {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
  26. {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/tier_validation.py:0
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 "The operation is under validation."
593
- msgstr "该操作正在审批中。"
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 待审批"
@@ -1,6 +1,7 @@
1
1
  # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
2
2
 
3
3
  from . import tier_definition
4
+ from . import tier_validation_exception
4
5
  from . import tier_review
5
6
  from . import tier_validation
6
7
  from . import res_users
@@ -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 = self.env["ir.model.fields"].search(
112
- [("model", "=", rec.model), ("relation", "=", "res.users")]
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 ["message_follower_ids", "access_token"]
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
- raise ValidationError(_("The operation is under validation."))
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
- return self._add_comment("validate", reviews)
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
+ ]
@@ -10,3 +10,4 @@
10
10
  - bosd
11
11
  - Evan Soh \<<evan.soh@omnisoftsolution.com>\>
12
12
  - Manuel Regidor \<<manuel.regidor@sygel.es>\>
13
+ - Eduardo de Miguel \<<edu@moduon.team>\>
@@ -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 8954 2022-01-20 10:10:25Z milde $
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: grey; } /* line numbers */
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:985b9816d91b596431cb157813581e485b5dee02ac1d0625e208d1516f970a34
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&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
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 &lt;<a class="reference external" href="mailto:evan.soh&#64;omnisoftsolution.com">evan.soh&#64;omnisoftsolution.com</a>&gt;</li>
590
591
  <li>Manuel Regidor &lt;<a class="reference external" href="mailto:manuel.regidor&#64;sygel.es">manuel.regidor&#64;sygel.es</a>&gt;</li>
592
+ <li>Eduardo de Miguel &lt;<a class="reference external" href="mailto:edu&#64;moduon.team">edu&#64;moduon.team</a>&gt;</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"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
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>