diff --git a/beesdoo_shift/data/cron.xml b/beesdoo_shift/data/cron.xml
index 040f9f7..a67f050 100644
--- a/beesdoo_shift/data/cron.xml
+++ b/beesdoo_shift/data/cron.xml
@@ -23,5 +23,17 @@
()
+
+
+ Compute Shift Counter
+ 4
+ hours
+ -1
+
+ cooperative.status
+ _cron_compute_counter_irregular
+ ()
+
+
\ No newline at end of file
diff --git a/beesdoo_shift/models/cooperative_status.py b/beesdoo_shift/models/cooperative_status.py
index 886e306..48b171a 100644
--- a/beesdoo_shift/models/cooperative_status.py
+++ b/beesdoo_shift/models/cooperative_status.py
@@ -2,7 +2,11 @@
from openerp import models, fields, api, _
from openerp.exceptions import ValidationError
-from datetime import timedelta
+from datetime import timedelta, datetime
+import logging
+from openerp.osv.fields import related
+
+_logger = logging.getLogger(__name__)
def add_days_delta(date_from, days_delta):
if not date_from:
@@ -65,49 +69,97 @@ class CooperativeStatus(models.Model):
history_ids = fields.One2many('cooperative.status.history', 'status_id', readonly=True)
unsubscribed = fields.Boolean(default=False, help="Manually unsubscribed")
+ #Specific to irregular
+ irregular_start_date = fields.Date() #TODO migration script
+ irregular_absence_date = fields.Date()
+ irregular_absence_counter = fields.Integer() #TODO unsubscribe when reach -2
- @api.depends('today', 'sr', 'sc', 'holiday_end_time', 'holiday_start_time', 'time_extension', 'alert_start_time', 'extension_start_time', 'unsubscribed')
+ @api.depends('today', 'sr', 'sc', 'holiday_end_time',
+ 'holiday_start_time', 'time_extension',
+ 'alert_start_time', 'extension_start_time',
+ 'unsubscribed', 'irregular_absence_date',
+ 'irregular_absence_counter')
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))
update = int(self.env['ir.config_parameter'].get_param('always_update', False))
print update
for rec in self:
- if update:
+ if update or not self.today:
rec.status = 'ok'
rec.can_shop = True
continue
- ok = rec.sr >= 0 and rec.sc >= 0
- grace_delay = grace_delay + rec.time_extension
-
- if rec.sr < -1 or rec.unsubscribed:
- 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'
- 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 = 'suspended'
- 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 <= rec.holiday_end_time:
- rec.status = 'holiday'
- rec.can_shop = True
- elif ok or (not rec.alert_start_time and rec.sr >= 0):
+ if rec.working_mode == 'regular':
+ rec._set_regular_status(grace_delay, alert_delay)
+ elif rec.working_mode == 'irregular':
+ rec._set_irregular_status(grace_delay, alert_delay)
+ elif rec.working_mode == 'exempt':
rec.status = 'ok'
rec.can_shop = True
+ def _set_regular_status(self, grace_delay, alert_delay):
+ self.ensure_one()
+ ok = self.sr >= 0 and self.sc >= 0
+ grace_delay = grace_delay + self.time_extension
+
+ if self.sr < -1 or self.unsubscribed:
+ self.status = 'unsubscribed'
+ self.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 self.alert_start_time and self.extension_start_time and self.today <= add_days_delta(self.extension_start_time, grace_delay):
+ self.status = 'extension'
+ self.can_shop = True
+ elif not ok and self.alert_start_time and self.extension_start_time and self.today > add_days_delta(self.extension_start_time, grace_delay):
+ self.status = 'suspended'
+ self.can_shop = False
+ elif not ok and self.alert_start_time and self.today > add_days_delta(self.alert_start_time, alert_delay):
+ self.status = 'suspended'
+ self.can_shop = False
+ elif (self.sr < 0) or (not ok and self.alert_start_time):
+ self.status = 'alert'
+ self.can_shop = True
+
+ #Check for holidays; Can be in holidays even in alert or other mode ?
+ elif self.today >= self.holiday_start_time and self.today <= self.holiday_end_time:
+ self.status = 'holiday'
+ self.can_shop = True
+ elif ok or (not self.alert_start_time and self.sr >= 0):
+ self.status = 'ok'
+ self.can_shop = True
+
+ def _set_irregular_status(self, grace_delay, alert_delay):
+ self.ensure_one()
+ ok = self.sr >= 0
+ grace_delay = grace_delay + self.time_extension
+ print add_days_delta(self.extension_start_time, grace_delay)
+ if (not ok and self.irregular_absence_date and self.today > add_days_delta(self.irregular_absence_date, alert_delay * 2)) \
+ or self.unsubscribed or self.irregular_absence_counter <= -2:
+ self.status = 'unsubscribed'
+ self.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 self.alert_start_time and self.extension_start_time and self.today <= add_days_delta(self.extension_start_time, grace_delay):
+ self.status = 'extension'
+ self.can_shop = True
+ elif not ok and self.alert_start_time and self.extension_start_time and self.today > add_days_delta(self.extension_start_time, grace_delay):
+ self.status = 'suspended'
+ self.can_shop = False
+ elif not ok and self.alert_start_time and self.today > add_days_delta(self.alert_start_time, alert_delay):
+ self.status = 'suspended'
+ self.can_shop = False
+ elif (self.sr < 0) or (not ok and self.alert_start_time):
+ self.status = 'alert'
+ self.can_shop = True
+
+ #Check for holidays; Can be in holidays even in alert or other mode ?
+ elif self.today >= self.holiday_start_time and self.today <= self.holiday_end_time:
+ self.status = 'holiday'
+ self.can_shop = True
+ elif ok or (not self.alert_start_time and self.sr >= 0):
+ self.status = 'ok'
+ self.can_shop = True
@api.multi
def write(self, vals):
@@ -137,11 +189,14 @@ class CooperativeStatus(models.Model):
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)]})
+ #TODO: Add one day othertwise unsubscribed from the shift you were absent
self.env['beesdoo.shift.shift'].sudo().unsubscribe_from_today([self.cooperator_id.id], today=self.today)
def _change_counter(self, data):
self.sc += data.get('sc', 0)
self.sr += data.get('sr', 0)
+ self.irregular_absence_counter += data.get('irregular_absence_counter', 0)
+ self.irregular_absence_date = data.get('irregular_absence_date', False)
@api.multi
def _write(self, vals):
@@ -181,7 +236,45 @@ class CooperativeStatus(models.Model):
def clear_history(self):
self.ensure_one()
self.history_ids.unlink()
-
+
+ @api.model
+ def _cron_compute_counter_irregular(self, today=False):
+ today = today or fields.Date.today()
+ journal = self.env['beesdoo.shift.journal'].search([('date', '=', today)])
+ if not journal:
+ journal = self.env['beesdoo.shift.journal'].create({'date': today})
+
+ irregular = self.search([('status', '!=', 'unsubscribed'), ('working_mode', '=', 'irregular'), ('irregular_start_date', '!=', False)])
+ today_date = fields.Date.from_string(today)
+ for status in irregular:
+ delta = (today_date - fields.Date.from_string(status.irregular_start_date)).days
+ if delta and delta % 28 == 0 and status not in journal.line_ids: #TODO use system parameter for 28
+ if status.sr > 0:
+ status.sr -= 1
+ else:
+ status.sr -= 2
+ journal.line_ids |= status
+
+
+class ShiftCronJournal(models.Model):
+ _name = 'beesdoo.shift.journal'
+ _order = 'date desc'
+ _rec_name = 'date'
+
+ date = fields.Date()
+ line_ids = fields.Many2many('cooperative.status')
+
+ _sql_constraints = [
+ ('one_entry_per_day', 'unique (date)', _('You can only create one journal per day')),
+ ]
+
+ @api.multi
+ def run(self):
+ self.ensure_one()
+ if not self.user_has_groups('beesdoo_shift.group_cooperative_admin'):
+ raise ValidationError(_("You don't have the access to perform this action"))
+ self.sudo().env['cooperative.status']._cron_compute_counter_irregular(today=self.date)
+
class ResPartner(models.Model):
_inherit = 'res.partner'
diff --git a/beesdoo_shift/models/task.py b/beesdoo_shift/models/task.py
index 9deb853..6058c2b 100644
--- a/beesdoo_shift/models/task.py
+++ b/beesdoo_shift/models/task.py
@@ -87,11 +87,14 @@ class Task(models.Model):
return super(Task, self).write(vals)
def _set_revert_info(self, data, status):
- data = {
+ data_new = {
'status_id': status.id,
- 'data' : {k: data[k] * -1 for k in data.keys()}
+ 'data' : {k: data.get(k, 0) * -1 for k in ['sr', 'sc', 'irregular_absence_counter']}
}
- self.write({'revert_info': json.dumps(data)})
+ if data.get('irregular_absence_date'):
+ data_new['data']['irregular_absence_date'] = False
+
+ self.write({'revert_info': json.dumps(data_new)})
def _revert(self):
if not self.revert_info:
@@ -107,35 +110,54 @@ class Task(models.Model):
self.ensure_one()
self._revert()
update = int(self.env['ir.config_parameter'].get_param('always_update', False))
- if not (self.worker_id or self.replaced_id) or update:
- return
+
new_stage = self.env['beesdoo.shift.stage'].browse(new_stage)
-
- if not self.replaced_id: #No replacement case
- status = self.worker_id.cooperative_status_ids[0]
- else:
- status = self.replaced_id.cooperative_status_ids[0]
-
data = {}
- if new_stage == self.env.ref('beesdoo_shift.done') and self.is_regular:
- pass
- if new_stage == self.env.ref('beesdoo_shift.done') and not self.is_regular:
- if status.sr < 0:
- data['sr'] = 1
- elif status.sc < 0:
- data['sc'] = 1
+ DONE = self.env.ref('beesdoo_shift.done')
+ ABSENT = self.env.ref('beesdoo_shift.absent')
+ EXCUSED = self.env.ref('beesdoo_shift.excused')
+ NECESSITY = self.env.ref('beesdoo_shift.excused_necessity')
+
+ if not (self.worker_id or self.replaced_id) and new_stage in (DONE, ABSENT, EXCUSED, NECESSITY):
+ raise UserError(_("You cannot change to the status %s if the is no worker defined on the shift") % new_stage.name)
+
+ if update or not (self.worker_id or self.replaced_id):
+ return
+
+ if self.worker_id.working_mode == 'regular':
+ if not self.replaced_id: #No replacement case
+ status = self.worker_id.cooperative_status_ids[0]
else:
+ status = self.replaced_id.cooperative_status_ids[0]
+
+ if new_stage == DONE and not self.is_regular:
+ if status.sr < 0:
+ data['sr'] = 1
+ elif status.sc < 0:
+ data['sc'] = 1
+ else:
+ data['sr'] = 1
+
+ if new_stage == ABSENT and not self.replaced_id:
+ data['sr'] = - 1
+ if status.sr <= 0:
+ data['sc'] = -1
+ if new_stage == ABSENT and self.replaced_id:
+ data['sr'] = -1
+
+ if new_stage == EXCUSED:
+ data['sr'] = -1
+
+ elif self.worker_id.working_mode == 'irregular':
+ status = self.worker_id.cooperative_status_ids[0]
+ if new_stage == DONE or new_stage == NECESSITY:
data['sr'] = 1
-
- if new_stage == self.env.ref('beesdoo_shift.absent') and not self.replaced_id:
- data['sr'] = - 1
- if status.sr <= 0:
- data['sc'] = -1
- if new_stage == self.env.ref('beesdoo_shift.absent') and self.replaced_id:
- data['sr'] = -1
-
- if new_stage == self.env.ref('beesdoo_shift.excused'):
- data['sr'] = -1
+ data['irregular_absence_date'] = False
+ data['irregular_absence_counter'] = 1 if status.irregular_absence_counter < 0 else 0
+ if new_stage == ABSENT or new_stage == EXCUSED:
+ data['sr'] = -2
+ data['irregular_absence_date'] = self.start_time[:10]
+ data['irregular_absence_counter'] = -1
status.sudo()._change_counter(data)
self._set_revert_info(data, status)
diff --git a/beesdoo_shift/security/ir.model.access.csv b/beesdoo_shift/security/ir.model.access.csv
index 3ff2efe..0d8ddb7 100644
--- a/beesdoo_shift/security/ir.model.access.csv
+++ b/beesdoo_shift/security/ir.model.access.csv
@@ -17,3 +17,5 @@ all_config_coopplanning_task,Attendance Edit Shift,model_beesdoo_shift_shift,gro
exempt_reason_read_all,Exempt Reason Read all ,beesdoo_shift.model_cooperative_exempt_reason,,1,0,0,0
exempt_reason,Exempt Reason Admin,beesdoo_shift.model_cooperative_exempt_reason,beesdoo_shift.group_cooperative_admin,1,1,1,1
history_read_all,History Read All,beesdoo_shift.model_cooperative_status_history,,1,0,0,0
+access_beesdoo_shift_journal,access_beesdoo_shift_journal,model_beesdoo_shift_journal,beesdoo_shift.group_cooperative_admin,1,0,1,1
+access_beesdoo_shift_journal_line,access_beesdoo_shift_journal_line,model_beesdoo_shift_journal_line,beesdoo_shift.group_cooperative_admin,1,0,0,0
diff --git a/beesdoo_shift/views/cooperative_status.xml b/beesdoo_shift/views/cooperative_status.xml
index f5c3f02..6e8a1aa 100644
--- a/beesdoo_shift/views/cooperative_status.xml
+++ b/beesdoo_shift/views/cooperative_status.xml
@@ -63,15 +63,19 @@
+
+
+
+
-
+
@@ -119,6 +123,29 @@
+
+
+ Journal Form View
+ beesdoo.shift.journal
+
+
+
+
Cooperator Status
@@ -143,6 +170,15 @@
sequence="1" />
+
+
+ Counter Journal
+ beesdoo.shift.journal
+ tree,form
+
+
+
diff --git a/beesdoo_shift/views/task.xml b/beesdoo_shift/views/task.xml
index 2a5b45a..7335464 100644
--- a/beesdoo_shift/views/task.xml
+++ b/beesdoo_shift/views/task.xml
@@ -98,6 +98,7 @@
+
diff --git a/beesdoo_shift/wizard/subscribe.py b/beesdoo_shift/wizard/subscribe.py
index c910599..2040a57 100644
--- a/beesdoo_shift/wizard/subscribe.py
+++ b/beesdoo_shift/wizard/subscribe.py
@@ -33,7 +33,8 @@ class Subscribe(models.TransientModel):
return self.env['res.partner'].browse(self._context.get('active_id')).working_mode
def _get_reset_counter_default(self):
- return self.env['res.partner'].browse(self._context.get('active_id')).state == 'unsubscribed'
+ partner = self.env['res.partner'].browse(self._context.get('active_id'))
+ return partner.state == 'unsubscribed' and partner.working_mode == 'regular'
info_session = fields.Boolean(string="Followed an information session", default=True)
info_session_date = fields.Date(string="Date of information session", default=_get_date)
@@ -50,6 +51,7 @@ class Subscribe(models.TransientModel):
reset_counter = fields.Boolean(default=_get_reset_counter_default)
reset_compensation_counter = fields.Boolean(default=False)
unsubscribed = fields.Boolean(default=False, string="Are you sure to unsubscribe this cooperator")
+ irregular_start_date = fields.Date(string="Start Date", default=fields.Date.today)
@@ -80,6 +82,7 @@ class Subscribe(models.TransientModel):
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,
@@ -88,7 +91,10 @@ class Subscribe(models.TransientModel):
'exempt_reason_id' : self.exempt_reason_id.id,
'super' : self.super,
'cooperator_id': self.cooperator_id.id,
- 'unsubscribed': False
+ 'unsubscribed': False,
+ 'irregular_start_date': self.irregular_start_date,
+ 'irregular_absence_date': False,
+ 'irregular_absence_counter': 0,
}
if self.reset_counter:
data['sr'] = 0
@@ -103,3 +109,5 @@ class Subscribe(models.TransientModel):
status_id.sudo().write(data)
else:
self.env['cooperative.status'].sudo().create(data)
+
+
diff --git a/beesdoo_shift/wizard/subscribe.xml b/beesdoo_shift/wizard/subscribe.xml
index 14f4633..5c6dcca 100644
--- a/beesdoo_shift/wizard/subscribe.xml
+++ b/beesdoo_shift/wizard/subscribe.xml
@@ -15,6 +15,7 @@
+