You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.9 KiB

6 years ago
  1. ###################################################################################
  2. #
  3. # Copyright (C) 2018 MuK IT GmbH
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #
  18. ###################################################################################
  19. import logging
  20. from collections import defaultdict
  21. from odoo import api, models, fields
  22. _logger = logging.getLogger(__name__)
  23. class BaseAutomation(models.Model):
  24. _inherit = 'base.automation'
  25. trigger = fields.Selection(
  26. selection_add=[('on_create_or_write_or_unlink', 'On Creation & Update & Deletion')])
  27. @api.onchange('trigger')
  28. def onchange_trigger(self):
  29. super(BaseAutomation, self).onchange_trigger()
  30. if self.trigger == "on_create_or_write_or_unlink":
  31. self.filter_pre_domain = False
  32. self.trg_date_id = False
  33. self.trg_date_range = False
  34. self.trg_date_range_type = False
  35. @api.model_cr
  36. def _register_hook(self):
  37. def make_create():
  38. @api.model
  39. def create(self, vals, **kw):
  40. actions = self.env['base.automation']._get_actions(self, ['on_create_or_write_or_unlink'])
  41. record = create.origin(self.with_env(actions.env), vals, **kw)
  42. for action in actions.with_context(old_values=None):
  43. action._process(action._filter_post(record))
  44. return record.with_env(self.env)
  45. return create
  46. def make_write():
  47. @api.multi
  48. def _write(self, vals, **kw):
  49. actions = self.env['base.automation']._get_actions(self, ['on_create_or_write_or_unlink'])
  50. records = self.with_env(actions.env)
  51. pre = {action: action._filter_pre(records) for action in actions}
  52. old_values = {
  53. old_vals.pop('id'): old_vals
  54. for old_vals in records.read(list(vals))
  55. }
  56. _write.origin(records, vals, **kw)
  57. for action in actions.with_context(old_values=old_values):
  58. action._process(action._filter_post(pre[action]))
  59. return True
  60. return _write
  61. def make_unlink():
  62. @api.multi
  63. def unlink(self, **kwargs):
  64. actions = self.env['base.automation']._get_actions(self, ['on_create_or_write_or_unlink'])
  65. records = self.with_env(actions.env)
  66. for action in actions:
  67. action._process(action._filter_post(records))
  68. return unlink.origin(self, **kwargs)
  69. return unlink
  70. patched_models = defaultdict(set)
  71. def patch(model, name, method):
  72. if model not in patched_models[name]:
  73. patched_models[name].add(model)
  74. model._patch_method(name, method)
  75. super(BaseAutomation, self)._register_hook()
  76. for action_rule in self.with_context({}).search([]):
  77. Model = self.env.get(action_rule.model_name)
  78. if Model is None:
  79. continue
  80. if action_rule.trigger == 'on_create_or_write_or_unlink':
  81. patch(Model, 'create', make_create())
  82. patch(Model, '_write', make_write())
  83. patch(Model, 'unlink', make_unlink())