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.

180 lines
6.0 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2015 Antiun Ingeniería S.L. - Antonio Espinosa
  3. # © 2015 Antiun Ingeniería S.L. - Jairo Llopis
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  5. from openerp import models, fields, api, exceptions
  6. from openerp.tools.translate import _
  7. class IrExportsLine(models.Model):
  8. _inherit = 'ir.exports.line'
  9. _order = 'sequence,id'
  10. name = fields.Char(
  11. required=True,
  12. readonly=True,
  13. store=True,
  14. compute="_compute_name",
  15. inverse="_inverse_name",
  16. help="Field's technical name.")
  17. field1_id = fields.Many2one(
  18. "ir.model.fields",
  19. "First field",
  20. domain="[('model_id', '=', model1_id)]")
  21. field2_id = fields.Many2one(
  22. "ir.model.fields",
  23. "Second field",
  24. domain="[('model_id', '=', model2_id)]")
  25. field3_id = fields.Many2one(
  26. "ir.model.fields",
  27. "Third field",
  28. domain="[('model_id', '=', model3_id)]")
  29. model1_id = fields.Many2one(
  30. string="First model",
  31. readonly=True,
  32. related="export_id.model_id")
  33. model2_id = fields.Many2one(
  34. "ir.model",
  35. "Second model",
  36. compute="_compute_model2_id")
  37. model3_id = fields.Many2one(
  38. "ir.model",
  39. "Third model",
  40. compute="_compute_model3_id")
  41. sequence = fields.Integer()
  42. label = fields.Char(
  43. compute="_compute_label")
  44. @api.multi
  45. @api.depends("field1_id", "field2_id", "field3_id")
  46. def _compute_name(self):
  47. """Get the name from the selected fields."""
  48. for s in self:
  49. s.name = "/".join((s.field_n(num).name
  50. for num in range(1, 4)
  51. if s.field_n(num)))
  52. @api.multi
  53. @api.depends("field1_id")
  54. def _compute_model2_id(self):
  55. """Get the related model for the second field."""
  56. ir_model = self.env["ir.model"]
  57. for s in self:
  58. s.model2_id = (
  59. s.field1_id.ttype and
  60. "2" in s.field1_id.ttype and
  61. ir_model.search([("model", "=", s.field1_id.relation)]))
  62. @api.multi
  63. @api.depends("field2_id")
  64. def _compute_model3_id(self):
  65. """Get the related model for the third field."""
  66. ir_model = self.env["ir.model"]
  67. for s in self:
  68. s.model3_id = (
  69. s.field2_id.ttype and
  70. "2" in s.field2_id.ttype and
  71. ir_model.search([("model", "=", s.field2_id.relation)]))
  72. @api.multi
  73. @api.depends('name')
  74. def _compute_label(self):
  75. """Column label in a user-friendly format and language."""
  76. translations = self.env["ir.translation"]
  77. for s in self:
  78. parts = list()
  79. for num in range(1, 4):
  80. field = s.field_n(num)
  81. if not field:
  82. break
  83. # Translate label if possible
  84. parts.append(
  85. translations.search([
  86. ("type", "=", "field"),
  87. ("lang", "=", self.env.context.get("lang")),
  88. ("name", "=", "%s,%s" % (s.model_n(num).model,
  89. field.name)),
  90. ]).value or
  91. field.display_name)
  92. s.label = ("%s (%s)" % ("/".join(parts), s.name)
  93. if parts and s.name else False)
  94. @api.multi
  95. def _inverse_name(self):
  96. """Get the fields from the name."""
  97. for s in self:
  98. # Field names can have up to only 3 indentation levels
  99. parts = s.name.split("/", 2)
  100. for num in range(1, 4):
  101. try:
  102. # Fail in excessive subfield level
  103. field_name = parts[num - 1]
  104. except IndexError:
  105. # Remove subfield on failure
  106. s[s.field_n(num, True)] = False
  107. else:
  108. model = s.model_n(num)
  109. s[s.field_n(num, True)] = self._get_field_id(
  110. model, field_name)
  111. @api.one
  112. @api.constrains("field1_id", "field2_id", "field3_id")
  113. def _check_name(self):
  114. if not self.label:
  115. raise exceptions.ValidationError(
  116. _("Field '%s' does not exist") % self.name)
  117. lines = self.search([('export_id', '=', self.export_id.id),
  118. ('name', '=', self.name)])
  119. if len(lines) > 1:
  120. raise exceptions.ValidationError(
  121. _("Field '%s' already exists") % self.name)
  122. @api.model
  123. def _install_base_export_manager(self):
  124. """Populate ``field*_id`` fields."""
  125. self.search([("export_id", "=", False)]).unlink()
  126. self.search([("field1_id", "=", False),
  127. ("name", "!=", False)])._inverse_name()
  128. @api.model
  129. def _get_field_id(self, model, name):
  130. """Get a field object from its model and name.
  131. :param int model:
  132. ``ir.model`` object that contains the field.
  133. :param str name:
  134. Technical name of the field, like ``child_ids``.
  135. """
  136. return self.env["ir.model.fields"].search(
  137. [("name", "=", name),
  138. ("model_id", "=", model.id)])
  139. @api.multi
  140. def field_n(self, n, only_name=False):
  141. """Helper to choose the field according to its indentation level.
  142. :param int n:
  143. Number of the indentation level to choose the field, from 1 to 3.
  144. :param bool only_name:
  145. Return only the field name, or return its value.
  146. """
  147. name = "field%d_id" % n
  148. return name if only_name else self[name]
  149. @api.multi
  150. def model_n(self, n, only_name=False):
  151. """Helper to choose the model according to its indentation level.
  152. :param int n:
  153. Number of the indentation level to choose the model, from 1 to 3.
  154. :param bool only_name:
  155. Return only the model name, or return its value.
  156. """
  157. name = "model%d_id" % n
  158. return name if only_name else self[name]