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.

245 lines
10 KiB

7 years ago
7 years ago
7 years ago
7 years ago
  1. # -*- coding: utf-8 -*-
  2. from openerp import models, fields, api, _
  3. from openerp.exceptions import ValidationError
  4. from datetime import timedelta
  5. def add_days_delta(date_from, days_delta):
  6. if not date_from:
  7. return date_from
  8. next_date = fields.Date.from_string(date_from) + timedelta(days=days_delta)
  9. return fields.Date.to_string(next_date)
  10. class ExemptReason(models.Model):
  11. _name = 'cooperative.exempt.reason'
  12. name = fields.Char(required=True)
  13. class HistoryStatus(models.Model):
  14. _name = 'cooperative.status.history'
  15. _order= 'create_date desc'
  16. status_id = fields.Many2one('cooperative.status')
  17. cooperator_id = fields.Many2one('res.partner')
  18. change = fields.Char()
  19. type = fields.Selection([('status', 'Status Change'), ('counter', 'Counter Change')])
  20. user_id = fields.Many2one('res.users', string="User")
  21. class CooperativeStatus(models.Model):
  22. _name = 'cooperative.status'
  23. _rec_name = 'cooperator_id'
  24. _order = 'cooperator_id'
  25. today = fields.Date(help="Field that allow to compute field and store them even if they are based on the current date")
  26. cooperator_id = fields.Many2one('res.partner')
  27. info_session = fields.Boolean('Information Session ?')
  28. info_session_date = fields.Datetime('Information Session Date')
  29. super = fields.Boolean("Super Cooperative")
  30. sr = fields.Integer("Compteur shift regulier", default=0)
  31. sc = fields.Integer("Compteur shift de compensation", default=0)
  32. time_extension = fields.Integer("Extension Days NB", default=0, help="Addtional days to the automatic extension, 5 mean that you have a total of 15 extension days of default one is set to 10")
  33. holiday_start_time = fields.Date("Holidays Start Day")
  34. holiday_end_time = fields.Date("Holidays End Day")
  35. alert_start_time = fields.Date("Alert Start Day")
  36. extension_start_time = fields.Date("Extension Start Day")
  37. #Champ compute
  38. working_mode = fields.Selection(
  39. [
  40. ('regular', 'Regular worker'),
  41. ('irregular', 'Irregular worker'),
  42. ('exempt', 'Exempted'),
  43. ],
  44. string="Working mode"
  45. )
  46. exempt_reason_id = fields.Many2one('cooperative.exempt.reason', 'Exempt Reason')
  47. status = fields.Selection([('ok', 'Up to Date'),
  48. ('holiday', 'Holidays'),
  49. ('alert', 'Alerte'),
  50. ('extension', 'Extension'),
  51. ('suspended', 'Suspended'),
  52. ('unsubscribed', 'Unsubscribed')],
  53. compute="_compute_status", string="Cooperative Status", store=True)
  54. can_shop = fields.Boolean(compute='_compute_status', store=True)
  55. history_ids = fields.One2many('cooperative.status.history', 'status_id', readonly=True)
  56. unsubscribed = fields.Boolean(default=False, help="Manually unsubscribed")
  57. @api.depends('today', 'sr', 'sc', 'holiday_end_time', 'holiday_start_time', 'time_extension', 'alert_start_time', 'extension_start_time', 'unsubscribed')
  58. def _compute_status(self):
  59. alert_delay = int(self.env['ir.config_parameter'].get_param('alert_delay', 28))
  60. grace_delay = int(self.env['ir.config_parameter'].get_param('default_grace_delay', 10))
  61. update = int(self.env['ir.config_parameter'].get_param('always_update', False))
  62. print update
  63. for rec in self:
  64. if update:
  65. rec.status = 'ok'
  66. rec.can_shop = True
  67. continue
  68. ok = rec.sr >= 0 and rec.sc >= 0
  69. grace_delay = grace_delay + rec.time_extension
  70. if rec.sr < -1 or rec.unsubscribed:
  71. rec.status = 'unsubscribed'
  72. rec.can_shop = False
  73. #Transition to alert sr < 0 or stay in alert sr < 0 or sc < 0 and thus alert time is defined
  74. elif not ok and rec.alert_start_time and rec.extension_start_time and rec.today <= add_days_delta(rec.extension_start_time, grace_delay):
  75. rec.status = 'extension'
  76. rec.can_shop = True
  77. elif not ok and rec.alert_start_time and rec.extension_start_time and rec.today > add_days_delta(rec.extension_start_time, grace_delay):
  78. rec.status = 'suspended'
  79. rec.can_shop = False
  80. elif not ok and rec.alert_start_time and rec.today > add_days_delta(rec.alert_start_time, alert_delay):
  81. rec.status = 'suspended'
  82. rec.can_shop = False
  83. elif (rec.sr < 0) or (not ok and rec.alert_start_time):
  84. rec.status = 'alert'
  85. rec.can_shop = True
  86. #Check for holidays; Can be in holidays even in alert or other mode ?
  87. elif rec.today >= rec.holiday_start_time and rec.today <= rec.holiday_end_time:
  88. rec.status = 'holiday'
  89. rec.can_shop = True
  90. elif ok or (not rec.alert_start_time and rec.sr >= 0):
  91. rec.status = 'ok'
  92. rec.can_shop = True
  93. @api.multi
  94. def write(self, vals):
  95. """
  96. Overwrite write to historize the change
  97. """
  98. for field in ['sr', 'sc', 'time_extension', 'extension_start_time', 'alert_start_time', 'unsubscribed']:
  99. if not field in vals:
  100. continue
  101. for rec in self:
  102. data = {
  103. 'status_id': rec.id,
  104. 'cooperator_id': rec.cooperator_id.id,
  105. 'type': 'counter',
  106. 'user_id': self.env.context.get('real_uid', self.env.uid),
  107. }
  108. if vals.get(field, rec[field]) != rec[field]:
  109. data['change'] = '%s: %s -> %s' % (field.upper(), rec[field], vals.get(field))
  110. self.env['cooperative.status.history'].sudo().create(data)
  111. return super(CooperativeStatus, self).write(vals)
  112. def _state_change(self, new_state, old_stage):
  113. self.ensure_one()
  114. if new_state == 'alert':
  115. self.write({'alert_start_time': self.today, 'extension_start_time': False, 'time_extension': 0})
  116. if new_state == 'ok': #reset alert start time if back to ok
  117. self.write({'alert_start_time': False, 'extension_start_time': False, 'time_extension': 0})
  118. if new_state == 'unsubscribed':
  119. self.cooperator_id.sudo().write({'subscribed_shift_ids' : [(5,0,0)]})
  120. self.env['beesdoo.shift.shift'].sudo().unsubscribe_from_today([self.cooperator_id.id], today=self.today)
  121. def _change_counter(self, data):
  122. self.sc += data.get('sc', 0)
  123. self.sr += data.get('sr', 0)
  124. @api.multi
  125. def _write(self, vals):
  126. """
  127. Overwrite write to historize the change of status
  128. and make action on status change
  129. """
  130. if 'status' in vals:
  131. self._cr.execute('select id, status, sr, sc from "%s" where id in %%s' % self._table, (self._ids,))
  132. result = self._cr.dictfetchall()
  133. old_status_per_id = {r['id'] : r for r in result}
  134. for rec in self:
  135. if old_status_per_id[rec.id]['status'] != vals['status']:
  136. data = {
  137. 'status_id': rec.id,
  138. 'cooperator_id': rec.cooperator_id.id,
  139. 'type': 'status',
  140. 'change': "STATUS: %s -> %s" % (old_status_per_id[rec.id]['status'], vals['status']),
  141. 'user_id': self.env.context.get('real_uid', self.env.uid),
  142. }
  143. self.env['cooperative.status.history'].sudo().create(data)
  144. rec._state_change(vals['status'], old_status_per_id[rec.id]['status'])
  145. return super(CooperativeStatus, self)._write(vals)
  146. _sql_constraints = [
  147. ('cooperator_uniq', 'unique (cooperator_id)', _('You can only set one cooperator status per cooperator')),
  148. ]
  149. @api.model
  150. def _set_today(self):
  151. """
  152. Method call by the cron to update store value base on the date
  153. """
  154. self.search([]).write({'today': fields.Date.today()})
  155. @api.multi
  156. def clear_history(self):
  157. self.ensure_one()
  158. self.history_ids.unlink()
  159. class ResPartner(models.Model):
  160. _inherit = 'res.partner'
  161. cooperative_status_ids = fields.One2many('cooperative.status', 'cooperator_id', readonly=True)
  162. super = fields.Boolean(related='cooperative_status_ids.super', string="Super Cooperative", readonly=True, store=True)
  163. info_session = fields.Boolean(related='cooperative_status_ids.info_session', string='Information Session ?', readonly=True, store=True)
  164. info_session_date = fields.Datetime(related='cooperative_status_ids.info_session_date', string='Information Session Date', readonly=True, store=True)
  165. working_mode = fields.Selection(related='cooperative_status_ids.working_mode', readonly=True, store=True)
  166. exempt_reason_id = fields.Many2one(related='cooperative_status_ids.exempt_reason_id', readonly=True, store=True)
  167. state = fields.Selection(related='cooperative_status_ids.status', readonly=True, store=True)
  168. extension_start_time = fields.Date(related='cooperative_status_ids.extension_start_time', string="Extension Start Day", readonly=True, store=True)
  169. subscribed_shift_ids = fields.Many2many('beesdoo.shift.template')
  170. @api.multi
  171. def coop_subscribe(self):
  172. return {
  173. 'name': _('Subscribe Cooperator'),
  174. 'type': 'ir.actions.act_window',
  175. 'view_type': 'form',
  176. 'view_mode': 'form',
  177. 'res_model': 'beesdoo.shift.subscribe',
  178. 'target': 'new',
  179. }
  180. @api.multi
  181. def coop_unsubscribe(self):
  182. res = self.coop_subscribe()
  183. res['context'] = {'default_unsubscribed': True}
  184. return res
  185. @api.multi
  186. def manual_extension(self):
  187. return {
  188. 'name': _('Manual Extension'),
  189. 'type': 'ir.actions.act_window',
  190. 'view_type': 'form',
  191. 'view_mode': 'form',
  192. 'res_model': 'beesdoo.shift.extension',
  193. 'target': 'new',
  194. }
  195. @api.multi
  196. def auto_extension(self):
  197. res = self.manual_extension()
  198. res['context'] = {'default_auto': True}
  199. res['name'] = _('Trigger Grace Delay')
  200. return res
  201. @api.multi
  202. def register_holiday(self):
  203. return {
  204. 'name': _('Register Holiday'),
  205. 'type': 'ir.actions.act_window',
  206. 'view_type': 'form',
  207. 'view_mode': 'form',
  208. 'res_model': 'beesdoo.shift.holiday',
  209. 'target': 'new',
  210. }
  211. #TODO access right + vue on res.partner
  212. #TODO can_shop : Status can_shop ou extempted ou part C