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.

110 lines
4.0 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2017 Therp BV <http://therp.nl>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from odoo import api, models, fields
  5. REASON_DUPLICATE = 1
  6. REASON_DEFAULT = 2
  7. class CleanupPurgeLineProperty(models.TransientModel):
  8. _inherit = 'cleanup.purge.line'
  9. _name = 'cleanup.purge.line.property'
  10. _description = 'Purge properties'
  11. wizard_id = fields.Many2one(
  12. 'cleanup.purge.wizard.property', 'Purge Wizard', readonly=True)
  13. property_id = fields.Many2one('ir.property')
  14. reason = fields.Selection([
  15. (REASON_DUPLICATE, 'Duplicated property'),
  16. (REASON_DEFAULT, 'Same value as default'),
  17. ])
  18. @api.multi
  19. def purge(self):
  20. """Delete properties"""
  21. self.write({'purged': True})
  22. return self.mapped('property_id').unlink()
  23. class CleanupPurgeWizardProperty(models.TransientModel):
  24. _inherit = 'cleanup.purge.wizard'
  25. _name = 'cleanup.purge.wizard.property'
  26. _description = 'Purge properties'
  27. @api.model
  28. def find(self):
  29. """
  30. Search property records which are duplicated or the same as the default
  31. """
  32. result = []
  33. default_properties = self.env['ir.property'].search([
  34. ('res_id', '=', False),
  35. ])
  36. handled_field_ids = []
  37. for prop in default_properties:
  38. if prop.fields_id.id in handled_field_ids:
  39. continue
  40. domain = [
  41. ('id', '!=', prop.id),
  42. ('fields_id', '=', prop.fields_id.id),
  43. # =? explicitly tests for None or False, not falsyness
  44. ('value_float', '=?', prop.value_float or False),
  45. ('value_integer', '=?', prop.value_integer or False),
  46. ('value_text', '=?', prop.value_text or False),
  47. ('value_binary', '=?', prop.value_binary or False),
  48. ('value_reference', '=?', prop.value_reference or False),
  49. ('value_datetime', '=?', prop.value_datetime or False),
  50. ]
  51. if prop.company_id:
  52. domain.append(('company_id', '=', prop.company_id.id))
  53. else:
  54. domain.extend([
  55. '|',
  56. ('company_id', '=', False),
  57. (
  58. 'company_id', 'in', self.env['res.company'].search([
  59. (
  60. 'id', 'not in', default_properties.filtered(
  61. lambda x: x.company_id and
  62. x.fields_id == prop.fields_id
  63. ).ids,
  64. )
  65. ]).ids
  66. ),
  67. ])
  68. for redundant_property in self.env['ir.property'].search(domain):
  69. result.append({
  70. 'name': '%s@%s: %s' % (
  71. prop.name, prop.res_id, prop.get_by_record()
  72. ),
  73. 'property_id': redundant_property.id,
  74. 'reason': REASON_DEFAULT,
  75. })
  76. handled_field_ids.append(prop.fields_id.id)
  77. self.env.cr.execute(
  78. '''
  79. with grouped_properties(ids, cnt) as (
  80. select array_agg(id), count(*)
  81. from ir_property group by res_id, company_id, fields_id
  82. )
  83. select ids from grouped_properties where cnt > 1
  84. '''
  85. )
  86. for ids, in self.env.cr.fetchall():
  87. # odoo uses the first property found by search
  88. for prop in self.env['ir.property'].search([
  89. ('id', 'in', ids)
  90. ])[1:]:
  91. result.append({
  92. 'name': '%s@%s: %s' % (
  93. prop.name, prop.res_id, prop.get_by_record()
  94. ),
  95. 'property_id': prop.id,
  96. 'reason': REASON_DUPLICATE,
  97. })
  98. return result
  99. purge_line_ids = fields.One2many(
  100. 'cleanup.purge.line.property', 'wizard_id', 'Properties to purge')