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.

244 lines
8.6 KiB

  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # Odoo, Open Source Management Solution
  5. #
  6. # Copyright (c) All rights reserved:
  7. # (c) 2012 Agile Business Group sagl (<http://www.agilebg.com>)
  8. # (c) 2012 Domsense srl (<http://www.domsense.com>)
  9. # (c) 2015 Anubía, soluciones en la nube,SL (http://www.anubia.es)
  10. # Alejandro Santana <alejandrosantana@anubia.es>
  11. #
  12. # This program is free software: you can redistribute it and/or modify
  13. # it under the terms of the GNU Affero General Public License as
  14. # published by the Free Software Foundation, either version 3 of the
  15. # License, or (at your option) any later version.
  16. #
  17. # This program is distributed in the hope that it will be useful,
  18. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. # GNU Affero General Public License for more details.
  21. #
  22. # You should have received a copy of the GNU Affero General Public License
  23. # along with this program. If not, see http://www.gnu.org/licenses
  24. #
  25. ##############################################################################
  26. from openerp import models, fields, api
  27. from openerp.tools.translate import _
  28. from mako.template import Template
  29. from datetime import datetime
  30. from openerp import tools
  31. from openerp.tools.safe_eval import safe_eval
  32. import logging
  33. def _models_get(self):
  34. model_obj = self.env['ir.model']
  35. model_ids = model_obj.search([])
  36. return [(model.model, model.name) for model in model_ids]
  37. class SuperCalendarConfigurator(models.Model):
  38. _logger = logging.getLogger(__name__)
  39. _name = 'super.calendar.configurator'
  40. name = fields.Char(
  41. string='Name',
  42. size=64,
  43. required=True,
  44. )
  45. line_ids = fields.One2many(
  46. comodel_name='super.calendar.configurator.line',
  47. inverse_name='configurator_id',
  48. string='Lines',
  49. )
  50. def _clear_super_calendar_records(self):
  51. """ Remove old super_calendar records """
  52. super_calendar_pool = self.env['super.calendar']
  53. super_calendar_ids = super_calendar_pool.search([])
  54. super_calendar_ids.unlink()
  55. @api.multi
  56. def generate_calendar_records(self):
  57. """ At every CRON execution, every 'super calendar' data is deleted
  58. and regenerated again. """
  59. # Remove old records
  60. self._clear_super_calendar_records()
  61. # Rebuild all calendar records
  62. configurator_ids = self.search([])
  63. for configurator in configurator_ids:
  64. for line in configurator.line_ids:
  65. self._generate_record_from_line(configurator, line)
  66. self._logger.info('Calendar generated')
  67. return True
  68. @api.multi
  69. def _generate_record_from_line(self, configurator, line):
  70. super_calendar_pool = self.env['super.calendar']
  71. values = self._get_record_values_from_line(configurator, line)
  72. for record in values:
  73. super_calendar_pool.create(values[record])
  74. @api.multi
  75. def _get_record_values_from_line(self, configurator, line):
  76. res = {}
  77. current_pool = self.env[line.name.model]
  78. domain = line.domain and safe_eval(line.domain) or []
  79. current_record_ids = current_pool.search(domain)
  80. for cur_rec in current_record_ids:
  81. f_user = line.user_field_id and line.user_field_id.name
  82. f_descr = (line.description_field_id and
  83. line.description_field_id.name)
  84. f_date_start = (line.date_start_field_id and
  85. line.date_start_field_id.name)
  86. f_date_stop = (line.date_stop_field_id and
  87. line.date_stop_field_id.name)
  88. f_duration = (line.duration_field_id and
  89. line.duration_field_id.name)
  90. if (f_user and
  91. cur_rec[f_user] and
  92. cur_rec[f_user]._model._name != 'res.users'):
  93. raise Exception(
  94. _('Error'),
  95. _("The 'User' field of record %s (%s) "
  96. "does not refer to res.users")
  97. % (cur_rec[f_descr], line.name.model))
  98. if (((f_descr and cur_rec[f_descr]) or
  99. line.description_code) and
  100. cur_rec[f_date_start]):
  101. duration = False
  102. if (not line.duration_field_id and
  103. line.date_stop_field_id and
  104. cur_rec[f_date_start] and
  105. cur_rec[f_date_stop]):
  106. date_start = datetime.strptime(
  107. cur_rec[f_date_start],
  108. tools.DEFAULT_SERVER_DATETIME_FORMAT
  109. )
  110. date_stop = datetime.strptime(
  111. cur_rec[f_date_stop],
  112. tools.DEFAULT_SERVER_DATETIME_FORMAT
  113. )
  114. date_diff = (date_stop - date_start)
  115. duration = date_diff.total_seconds() / 3600
  116. elif line.duration_field_id:
  117. duration = cur_rec[f_duration]
  118. if line.description_type != 'code':
  119. name = cur_rec[f_descr]
  120. else:
  121. parse_dict = {'o': cur_rec}
  122. mytemplate = Template(line.description_code)
  123. name = mytemplate.render(**parse_dict)
  124. super_calendar_values = {
  125. 'name': name,
  126. 'date_start': cur_rec[f_date_start],
  127. 'duration': duration,
  128. 'user_id': (
  129. f_user and
  130. cur_rec[f_user] and
  131. cur_rec[f_user].id or
  132. False
  133. ),
  134. 'configurator_id': configurator.id,
  135. 'res_id': line.name.model+','+str(cur_rec['id']),
  136. 'model_id': line.name.id,
  137. }
  138. res[cur_rec] = super_calendar_values
  139. return res
  140. class SuperCalendarConfiguratorLine(models.Model):
  141. _name = 'super.calendar.configurator.line'
  142. name = fields.Many2one(
  143. comodel_name='ir.model',
  144. string='Model',
  145. required=True,
  146. )
  147. domain = fields.Char(
  148. string='Domain',
  149. size=512,
  150. )
  151. configurator_id = fields.Many2one(
  152. comodel_name='super.calendar.configurator',
  153. string='Configurator',
  154. )
  155. description_type = fields.Selection(
  156. [('field', 'Field'),
  157. ('code', 'Code')],
  158. string="Description Type",
  159. default='field',
  160. )
  161. description_field_id = fields.Many2one(
  162. comodel_name='ir.model.fields',
  163. string='Description field',
  164. domain=("['&','|',('ttype', '=', 'char'),('ttype', '=', 'text'),"
  165. "('model_id', '=', name)]"),
  166. )
  167. description_code = fields.Text(
  168. string='Description field',
  169. help=("Use '${o}' to refer to the involved object. "
  170. "E.g.: '${o.project_id.name}'"),
  171. )
  172. date_start_field_id = fields.Many2one(
  173. comodel_name='ir.model.fields',
  174. string='Start date field',
  175. domain=("['&','|',('ttype', '=', 'datetime'),('ttype', '=', 'date'),"
  176. "('model_id', '=', name)]"),
  177. required=True,
  178. )
  179. date_stop_field_id = fields.Many2one(
  180. comodel_name='ir.model.fields',
  181. string='End date field',
  182. domain="['&',('ttype', '=', 'datetime'),('model_id', '=', name)]"
  183. )
  184. duration_field_id = fields.Many2one(
  185. comodel_name='ir.model.fields',
  186. string='Duration field',
  187. domain="['&',('ttype', '=', 'float'), ('model_id', '=', name)]",
  188. )
  189. user_field_id = fields.Many2one(
  190. comodel_name='ir.model.fields',
  191. string='User field',
  192. domain="['&', ('ttype', '=', 'many2one'), ('model_id', '=', name)]",
  193. )
  194. class SuperCalendar(models.Model):
  195. _name = 'super.calendar'
  196. name = fields.Char(
  197. string='Description',
  198. size=512,
  199. required=True,
  200. )
  201. date_start = fields.Datetime(
  202. string='Start date',
  203. required=True,
  204. )
  205. duration = fields.Float(
  206. string='Duration'
  207. )
  208. user_id = fields.Many2one(
  209. comodel_name='res.users',
  210. string='User',
  211. )
  212. configurator_id = fields.Many2one(
  213. comodel_name='super.calendar.configurator',
  214. string='Configurator',
  215. )
  216. res_id = fields.Reference(
  217. selection=_models_get,
  218. string='Resource',
  219. size=128,
  220. )
  221. model_id = fields.Many2one(
  222. comodel_name='ir.model',
  223. string='Model',
  224. )