diff --git a/beesdoo_shift/__openerp__.py b/beesdoo_shift/__openerp__.py
index 7ad419a..ba56969 100644
--- a/beesdoo_shift/__openerp__.py
+++ b/beesdoo_shift/__openerp__.py
@@ -20,6 +20,7 @@
'data': [
"data/stage.xml",
"data/system_parameter.xml",
+ "data/cron.xml",
"security/group.xml",
"security/ir.model.access.csv",
"views/task_template.xml",
diff --git a/beesdoo_shift/data/cron.xml b/beesdoo_shift/data/cron.xml
new file mode 100644
index 0000000..f534dc2
--- /dev/null
+++ b/beesdoo_shift/data/cron.xml
@@ -0,0 +1,12 @@
+
+
+ Update Cooperatoor status base on the date
+ 24
+ hours
+ -1
+
+ cooperative.status
+ _set_today
+ ()
+
+
\ No newline at end of file
diff --git a/beesdoo_shift/models/cooperative_status.py b/beesdoo_shift/models/cooperative_status.py
index efb07f0..4af346a 100644
--- a/beesdoo_shift/models/cooperative_status.py
+++ b/beesdoo_shift/models/cooperative_status.py
@@ -2,28 +2,48 @@
from openerp import models, fields, api, _
from openerp.exceptions import ValidationError
+from datetime import timedelta
+
+def add_days_delta(date_from, days_delta):
+ if not date_from:
+ return date_from
+ next_date = fields.Date.from_string(date_from) + timedelta(days=days_delta)
+ return fields.Date.to_string(next_date)
+
class ExemptReason(models.Model):
_name = 'cooperative.exempt.reason'
name = fields.Char(required=True)
+class HistoryStatus(models.Model):
+ _name = 'cooperative.status.history'
+
+ _order= 'create_date desc'
+
+ status_id = fields.Many2one('cooperative.status')
+ cooperator_id = fields.Many2one('res.partner')
+ change = fields.Char()
+ type = fields.Selection([('status', 'Status Change'), ('counter', 'Counter Change')])
+ user_id = fields.Many2one('res.users', string="User")
+
class CooperativeStatus(models.Model):
_name = 'cooperative.status'
_rec_name = 'cooperator_id'
+
+ today = fields.Date(help="Field that allow to compute field and store them even if they are based on the current date")
cooperator_id = fields.Many2one('res.partner')
info_session = fields.Boolean('Information Session ?')
info_session_date = fields.Datetime('Information Session Date')
super = fields.Boolean("Super Cooperative")
- sr = fields.Integer("Compteur shift regulier")
- sc = fields.Integer("Compteur shift de compensation")
+ sr = fields.Integer("Compteur shift regulier", default=0)
+ sc = fields.Integer("Compteur shift de compensation", default=0)
time_holiday = fields.Integer("Holidays Days NB", default=0)
- time_extension = fields.Integer("Extension Days NB", default=0) #Durée initial par défault sur ir_config_parameter
+ 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")
holiday_start_time = fields.Date("Holidays Start Day")
alert_start_time = fields.Date("Alert Start Day")
extension_start_time = fields.Date("Extension Start Day")
#Champ compute
- status = fields.Selection([('ok', 'Up to Date'), ('holiday', 'Holidays'), ('alert', 'Alerte'), ('unsubscribed', 'Unsubscribed')], compute="_compute_status", string="Cooperative Status")
working_mode = fields.Selection(
[
('regular', 'Regular worker'),
@@ -33,32 +53,122 @@ class CooperativeStatus(models.Model):
string="Working mode"
)
exempt_reason_id = fields.Many2one('cooperative.exempt.reason', 'Exempt Reason')
-# cooperator_type = fields.Selection(related="cooperator_id.cooperator_type", store=True)
-#
-# def _auto_working_mode(self, vals):
-# print "Auto Working mode"
-# if vals.get('cooperator_type') == 'share_b':
-# vals['working_mode'] = 'exempt'
-#
-# @api.model
-# @api.returns('self', lambda value:value.id)
-# def create(self, vals):
-# self._auto_working_mode(vals)
-# return super(CooperativeStatus, self).create(self, vals)
-#
-# @api.multi
-# def _write(self, vals):
-# self._auto_working_mode(vals)
-# return super(CooperativeStatus, self)._write(vals)
+ status = fields.Selection([('ok', 'Up to Date'),
+ ('holiday', 'Holidays'),
+ ('alert', 'Alerte'),
+ ('extension', 'Suspended (auto ext)'),
+ ('extension_current', 'In extension'),
+ ('suspended', 'Suspended'),
+ ('unsubscribed', 'Unsubscribed')],
+ compute="_compute_status", string="Cooperative Status", store=True)
+ can_shop = fields.Boolean(compute='_compute_status', store=True)
+ history_ids = fields.One2many('cooperative.status.history', 'status_id', readonly=True)
+
+
+ @api.depends('today', 'sr', 'sc', 'time_holiday', 'holiday_start_time', 'time_extension', 'alert_start_time', 'extension_start_time')
def _compute_status(self):
+ alert_delay = int(self.env['ir.config_parameter'].get_param('alert_delay', 28))
+ grace_delay = int(self.env['ir.config_parameter'].get_param('default_grace_delay', 10))
for rec in self:
- rec.status = 'ok'
+ ok = rec.sr >= 0 and rec.sc >= 0
+ grace_delay = grace_delay + rec.time_extension
+
+ if rec.sr < -1: #un subscribed
+ rec.status = 'unsubscribed'
+ rec.can_shop = False
+
+ #Transition to alert sr < 0 or stay in alert sr < 0 or sc < 0 and thus alert time is defined
+ 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):
+ rec.status = 'extension_current'
+ rec.can_shop = True
+ 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):
+ rec.status = 'suspended'
+ rec.can_shop = False
+ elif not ok and rec.alert_start_time and rec.today > add_days_delta(rec.alert_start_time, alert_delay):
+ rec.status = 'extension'
+ rec.can_shop = False
+ elif (rec.sr < 0) or (not ok and rec.alert_start_time):
+ rec.status = 'alert'
+ rec.can_shop = True
+
+ #Check for holidays; Can be in holidays even in alert or other mode ?
+ elif rec.today >= rec.holiday_start_time and rec.today < add_days_delta(rec.holiday_start_time, rec.time_holiday):
+ rec.status = 'holiday'
+ rec.can_shop = True
+ elif ok or (not rec.alert_start_time and rec.sr >= 0):
+ rec.status = 'ok'
+ rec.can_shop = True
+
+
+ @api.multi
+ def write(self, vals):
+ """
+ Overwrite write to historize the change
+ """
+ for field in ['sr', 'sc', 'time_extension', 'extension_start_time', 'alert_start_time']:
+ if not field in vals:
+ continue
+ for rec in self:
+ data = {
+ 'status_id': rec.id,
+ 'cooperator_id': rec.cooperator_id.id,
+ 'type': 'counter',
+ 'user_id': self.env.context.get('real_uid', self.env.uid),
+ }
+ if vals.get(field, rec[field]) != rec[field]:
+ data['change'] = '%s: %s -> %s' % (field.upper(), rec[field], vals.get(field))
+ self.env['cooperative.status.history'].sudo().create(data)
+ return super(CooperativeStatus, self).write(vals)
+
+ def _state_change(self, new_state, old_stage):
+ if new_state == 'alert':
+ self.write({'alert_start_time': self.today, 'extension_start_time': False, 'time_extension': 0})
+ if new_state == 'ok': #reset alert start time if back to ok
+ self.write({'alert_start_time': False, 'extension_start_time': False, 'time_extension': 0})
+ if new_state == 'unsubscribed':
+ self.cooperator_id.sudo().write({'subscribed_shift_ids' : [(5,0,0)]})
+ self.env['beesdoo.shift.shift'].sudo().unsubscribe_from_today([self.cooperator_id.id], today=self.today)
+
+ @api.multi
+ def _write(self, vals):
+ """
+ Overwrite write to historize the change of status
+ and make action on status change
+ """
+ if 'status' in vals:
+ self._cr.execute('select id, status, sr, sc from "%s" where id in %%s' % self._table, (self._ids,))
+ result = self._cr.dictfetchall()
+ old_status_per_id = {r['id'] : r for r in result}
+ for rec in self:
+ if old_status_per_id[rec.id]['status'] != vals['status']:
+ data = {
+ 'status_id': rec.id,
+ 'cooperator_id': rec.cooperator_id.id,
+ 'type': 'status',
+ 'change': "STATUS: %s -> %s" % (old_status_per_id[rec.id]['status'], vals['status']),
+ 'user_id': self.env.context.get('real_uid', self.env.uid),
+ }
+ self.env['cooperative.status.history'].sudo().create(data)
+ rec._state_change(vals['status'], old_status_per_id[rec.id]['status'])
+ return super(CooperativeStatus, self)._write(vals)
_sql_constraints = [
('cooperator_uniq', 'unique (cooperator_id)', _('You can only set one cooperator status per cooperator')),
]
+ @api.model
+ def _set_today(self):
+ """
+ Method call by the cron to update store value base on the date
+ """
+ self.search([]).write({'today': fields.Date.today()})
+
+ @api.multi
+ def clear_history(self):
+ self.ensure_one()
+ self.history_ids.unlink()
+
class ResPartner(models.Model):
_inherit = 'res.partner'
diff --git a/beesdoo_shift/models/task.py b/beesdoo_shift/models/task.py
index 5fc7992..4e3ebe4 100644
--- a/beesdoo_shift/models/task.py
+++ b/beesdoo_shift/models/task.py
@@ -49,4 +49,11 @@ class Task(models.Model):
'stage_id': _read_group_stage_id,
}
- #TODO button to replaced someone
\ No newline at end of file
+ #TODO button to replaced someone
+ @api.model
+ def unsubscribe_from_today(self, worker_ids, today=None):
+ today = today or fields.Date.today()
+ today = today + ' 00:00:00'
+ to_unsubscribe = self.search([('worker_id', 'in', worker_ids), ('start_time', '>=', today)])
+ to_unsubscribe.write({'worker_id': False})
+ #What about replacement ?
\ No newline at end of file
diff --git a/beesdoo_shift/views/cooperative_status.xml b/beesdoo_shift/views/cooperative_status.xml
index 246a40d..798ae83 100644
--- a/beesdoo_shift/views/cooperative_status.xml
+++ b/beesdoo_shift/views/cooperative_status.xml
@@ -39,20 +39,41 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -86,6 +107,19 @@
groups="beesdoo_shift.group_shift_management" sequence="20" />
+
+
+
+ Worker
+ res.partner
+ kanban,tree,form
+ [('cooperator_type', '=', 'share_a')]
+
+
+
+
diff --git a/beesdoo_shift/views/planning.xml b/beesdoo_shift/views/planning.xml
index 8b42baa..3a644d0 100644
--- a/beesdoo_shift/views/planning.xml
+++ b/beesdoo_shift/views/planning.xml
@@ -79,4 +79,5 @@
+
diff --git a/beesdoo_shift/wizard/subscribe.py b/beesdoo_shift/wizard/subscribe.py
index 5be9c00..c7d91f7 100644
--- a/beesdoo_shift/wizard/subscribe.py
+++ b/beesdoo_shift/wizard/subscribe.py
@@ -15,6 +15,9 @@ class Subscribe(models.TransientModel):
def _get_super(self):
return self.env['res.partner'].browse(self._context.get('active_id')).super
+ def _get_mode(self):
+ return self.env['res.partner'].browse(self._context.get('active_id')).working_mode
+
cooperator_id = fields.Many2one('res.partner', default=lambda self: self.env['res.partner'].browse(self._context.get('active_id')), required=True)
info_session = fields.Boolean(string="Followed an information session", default=True)
info_session_date = fields.Date(string="Date of information session", default=_get_date)
@@ -24,10 +27,11 @@ class Subscribe(models.TransientModel):
('regular', 'Regular worker'),
('irregular', 'Irregular worker'),
('exempt', 'Exempted'),
- ],
+ ], default=_get_mode
)
exempt_reason_id = fields.Many2one('cooperative.exempt.reason', 'Exempt Reason')
shift_id = fields.Many2one('beesdoo.shift.template')
+ reset_counter = fields.Boolean(default=False)
@api.multi
def subscribe(self):
@@ -36,10 +40,16 @@ class Subscribe(models.TransientModel):
if self.cooperator_id == self.env.user.partner_id and not self.env.user.has_group('beesdoo_shift.group_cooperative_admin'):
raise UserError(_("You cannot subscribe yourself."))
self.ensure_one()
+ self = self.with_context(real_uid=self._uid)
if self.shift_id and self.shift_id.remaining_worker <= 0:
raise UserError(_('There is no remaining space for this shift'))
if self.shift_id:
- self.sudo().shift_id.worker_ids |= self.cooperator_id
+ #Remove existing shift then subscribe to the new shift
+ self.cooperator_id.sudo().write({'subscribed_shift_ids' : [(6,0, [self.shift_id.id])]})
+ if self.working_mode != 'regular':
+ #Remove existing shift then subscribe to the new shift
+ self.cooperator_id.sudo().write({'subscribed_shift_ids' : [(5,)]})
+
data = {
'info_session' : self.info_session,
'info_session_date': self.info_session_date,
@@ -47,8 +57,12 @@ class Subscribe(models.TransientModel):
'exempt_reason_id' : self.exempt_reason_id.id,
'super' : self.super,
'cooperator_id': self.cooperator_id.id,
- 'sr' : 0, #set back to 0 if you subscribe a second time
+ 'extension_start_time': False,
+ 'alert_start_time': False,
+ 'time_extension': 0,
}
+ if self.reset_counter:
+ data['sr'] = 0
status_id = self.env['cooperative.status'].search([('cooperator_id', '=', self.cooperator_id.id)])
if status_id:
diff --git a/beesdoo_shift/wizard/subscribe.xml b/beesdoo_shift/wizard/subscribe.xml
index 2bf0316..83daa31 100644
--- a/beesdoo_shift/wizard/subscribe.xml
+++ b/beesdoo_shift/wizard/subscribe.xml
@@ -12,6 +12,7 @@
+