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.

196 lines
7.8 KiB

10 years ago
10 years ago
10 years ago
  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. # Copyright (C) 2010-2013 OpenERP s.a. (<http://openerp.com>).
  6. # Copyright (C) 2014 initOS GmbH & Co. KG (<http://www.initos.com>).
  7. # Copyright (C) 2015-Today GRAP
  8. # Author Markus Schneider <markus.schneider at initos.com>
  9. # @author Sylvain LE GAL (https://twitter.com/legalsylvain)
  10. #
  11. # This program is free software: you can redistribute it and/or modify
  12. # it under the terms of the GNU Affero General Public License as
  13. # published by the Free Software Foundation, either version 3 of the
  14. # License, or (at your option) any later version.
  15. #
  16. # This program is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU Affero General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU Affero General Public License
  22. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. #
  24. ##############################################################################
  25. from openerp.osv import orm, fields
  26. from openerp.tools.translate import _
  27. class tile(orm.Model):
  28. _name = 'tile.tile'
  29. _order = 'sequence, name'
  30. def _get_tile_info(self, cr, uid, ids, fields, args, context=None):
  31. ima_obj = self.pool['ir.model.access']
  32. res = {}
  33. records = self.browse(cr, uid, ids, context=context)
  34. for r in records:
  35. res[r.id] = {
  36. 'active': False,
  37. 'count': 0,
  38. 'computed_value': 0,
  39. 'helper': '',
  40. }
  41. if ima_obj.check(
  42. cr, uid, r.model_id.model, 'read', False, context):
  43. # Compute count item
  44. model = self.pool.get(r.model_id.model)
  45. count = model.search_count(
  46. cr, uid, eval(r.domain), context=context)
  47. res[r.id].update({
  48. 'active': True,
  49. 'count': count,
  50. })
  51. # Compute datas for field_id depending of field_function
  52. if r.field_function and r.field_id and count != 0:
  53. ids = model.search(
  54. cr, uid, eval(r.domain), context=context)
  55. vals = [x[r.field_id.name] for x in model.read(
  56. cr, uid, ids, [r.field_id.name], context=context)]
  57. desc = r.field_id.field_description
  58. if r.field_function == 'min':
  59. value = min(vals)
  60. helper = _("'Minimum value of %s'" % desc)
  61. elif r.field_function == 'max':
  62. value = max(vals)
  63. helper = _("'Maximum value of %s'" % desc)
  64. elif r.field_function == 'sum':
  65. value = sum(vals)
  66. helper = _("'Total value of %s'" % desc)
  67. elif r.field_function == 'avg':
  68. value = sum(vals) / len(vals)
  69. helper = _("'Average value of %s'" % desc)
  70. res[r.id].update({
  71. 'computed_value': value,
  72. 'helper': helper,
  73. })
  74. return res
  75. def _search_active(self, cr, uid, obj, name, arg, context=None):
  76. ima_obj = self.pool['ir.model.access']
  77. ids = []
  78. cr.execute("""
  79. SELECT tt.id, im.model
  80. FROM tile_tile tt
  81. INNER JOIN ir_model im
  82. ON tt.model_id = im.id""")
  83. for result in cr.fetchall():
  84. if (ima_obj.check(cr, uid, result[1], 'read', False) ==
  85. arg[0][2]):
  86. ids.append(result[0])
  87. return [('id', 'in', ids)]
  88. _columns = {
  89. 'name': fields.char('Tile Name'),
  90. 'model_id': fields.many2one('ir.model', 'Model', required=True),
  91. 'user_id': fields.many2one('res.users', 'User'),
  92. 'domain': fields.text('Domain'),
  93. 'action_id': fields.many2one('ir.actions.act_window', 'Action'),
  94. 'count': fields.function(
  95. _get_tile_info, type='int', string='Count',
  96. multi='tile_info', readonly=True),
  97. 'computed_value': fields.function(
  98. _get_tile_info, type='float', string='Computed Value',
  99. multi='tile_info', readonly=True),
  100. 'helper': fields.function(
  101. _get_tile_info, type='char', string='Helper',
  102. multi='tile_info', readonly=True),
  103. 'field_function': fields.selection([
  104. ('min', 'Minimum'),
  105. ('max', 'Maximum'),
  106. ('sum', 'Sum'),
  107. ('avg', 'Average')], 'Function'),
  108. 'field_id': fields.many2one(
  109. 'ir.model.fields', 'Field',
  110. domain="[('model_id', '=', model_id),"
  111. " ('ttype', 'in', ['float', 'int'])]"),
  112. 'active': fields.function(
  113. _get_tile_info, type='boolean', string='Active',
  114. multi='tile_info', readonly=True, fnct_search=_search_active),
  115. 'color': fields.char('Background color'),
  116. 'font_color': fields.char('Font Color'),
  117. 'sequence': fields.integer(
  118. 'Sequence', required=True),
  119. }
  120. # Constraint Section
  121. def _check_model_id_field_id(self, cr, uid, ids, context=None):
  122. for t in self.browse(cr, uid, ids, context=context):
  123. if t.field_id and t.field_id.model_id.id != t.model_id.id:
  124. return False
  125. return True
  126. def _check_field_id_field_function(self, cr, uid, ids, context=None):
  127. for t in self.browse(cr, uid, ids, context=context):
  128. if t.field_id and not t.field_function or\
  129. t.field_function and not t.field_id:
  130. return False
  131. return True
  132. _constraints = [
  133. (
  134. _check_model_id_field_id,
  135. "Error ! Please select a field of the select model.",
  136. ['model_id', 'field_id']),
  137. (
  138. _check_field_id_field_function,
  139. "Error ! Please set both fields: 'Field' and 'Function'.",
  140. ['field_id', 'field_function']),
  141. ]
  142. _defaults = {
  143. 'domain': '[]',
  144. 'color': '#0E6C7E',
  145. 'font_color': '#FFFFFF',
  146. 'sequence': 0,
  147. }
  148. def open_link(self, cr, uid, ids, context=None):
  149. tile_id = ids[0]
  150. tile_object = self.browse(cr, uid, tile_id, context=context)
  151. if tile_object.action_id:
  152. act_obj = self.pool.get('ir.actions.act_window')
  153. result = act_obj.read(cr, uid, [tile_object.action_id.id],
  154. context=context)[0]
  155. # FIXME: restore original Domain + Filter would be better
  156. result['domain'] = tile_object.domain
  157. return result
  158. # we have no action_id stored,
  159. # so try to load a default tree view
  160. return {
  161. 'name': tile_object.name,
  162. 'view_type': 'form',
  163. 'view_mode': 'tree',
  164. 'view_id': [False],
  165. 'res_model': tile_object.model_id.model,
  166. 'type': 'ir.actions.act_window',
  167. 'context': context,
  168. 'nodestroy': True,
  169. 'target': 'current',
  170. 'domain': tile_object.domain,
  171. }
  172. def add(self, cr, uid, vals, context=None):
  173. # TODO: check if string
  174. if 'model_id' in vals:
  175. # need to replace model_name with its id
  176. model_ids = self.pool.get('ir.model').search(cr, uid,
  177. [('model', '=',
  178. vals['model_id'])])
  179. vals['model_id'] = model_ids[0]
  180. return self.create(cr, uid, vals, context)