Browse Source

[CHG] b_shift : shift status

To give better understanding of compensations given by each status.

'stage_id' is replaced by a selection field state to ease
domain restrictions.
pull/124/head
Elouan Le Bars 5 years ago
parent
commit
db2dd6b988
  1. 3
      beesdoo_shift/__openerp__.py
  2. 44
      beesdoo_shift/data/stage.xml
  3. 66
      beesdoo_shift/migrations/9.0.1.3.0/post-migrate.py
  4. 16
      beesdoo_shift/migrations/9.0.1.3.0/pre-migrate.py
  5. 2
      beesdoo_shift/models/planning.py
  6. 98
      beesdoo_shift/models/task.py
  7. 2
      beesdoo_shift/security/ir.model.access.csv
  8. 11
      beesdoo_shift/views/task.xml
  9. 12
      beesdoo_website_shift/controllers/main.py
  10. 30
      beesdoo_website_shift/views/my_shift_website_templates.xml

3
beesdoo_shift/__openerp__.py

@ -13,12 +13,11 @@
'website': "https://github.com/beescoop/Obeesdoo",
'category': 'Cooperative management',
'version': '9.0.1.2.3',
'version': '9.0.1.3.0',
'depends': ['beesdoo_base'],
'data': [
"data/stage.xml",
"data/system_parameter.xml",
"data/cron.xml",
"data/mail_template.xml",

44
beesdoo_shift/data/stage.xml

@ -1,44 +0,0 @@
<odoo>
<record model="beesdoo.shift.stage" id="draft">
<field name="name">Unconfirmed</field>
<field name="sequence">1</field>
<field name="color">0</field>
<field name="code">draft</field>
</record>
<record model="beesdoo.shift.stage" id="open">
<field name="name">Confirmed</field>
<field name="sequence">2</field>
<field name="color">5</field>
<field name="code">open</field>
</record>
<record model="beesdoo.shift.stage" id="done">
<field name="name">Attended</field>
<field name="sequence">3</field>
<field name="color">1</field>
<field name="code">done</field>
</record>
<record model="beesdoo.shift.stage" id="absent">
<field name="name">Absent</field>
<field name="sequence">5</field>
<field name="color">2</field>
<field name="code">absent</field>
</record>
<record model="beesdoo.shift.stage" id="excused">
<field name="name">Excused</field>
<field name="sequence">6</field>
<field name="color">4</field>
<field name="code">excused</field>
</record>
<record model="beesdoo.shift.stage" id="excused_necessity">
<field name="name">Excused - Absolute Necessity</field>
<field name="sequence">7</field>
<field name="color">4</field>
<field name="code">excused_necessity</field>
</record>
<record model="beesdoo.shift.stage" id="cancel">
<field name="name">Cancelled</field>
<field name="sequence">8</field>
<field name="color">8</field>
<field name="code">cancel</field>
</record>
</odoo>

66
beesdoo_shift/migrations/9.0.1.3.0/post-migrate.py

@ -0,0 +1,66 @@
# coding: utf-8
def migrate(cr, version):
"""
The Char field 'code' from shift stage is now a Selection Field
named 'state'.
"""
# Set new field state
cr.execute(
"""
UPDATE beesdoo_shift_shift
SET state = old_code
"""
)
# Map new stage from corresponding old stage
cr.execute(
"""
UPDATE beesdoo_shift_shift
SET state = 'absent_2'
FROM res_partner
WHERE beesdoo_shift_shift.worker_id = res_partner.id
AND (
beesdoo_shift_shift.old_code = 'absent'
OR (
beesdoo_shift_shift.old_code = 'excused'
AND res_partner.working_mode = 'irregular'
)
)
"""
)
cr.execute(
"""
UPDATE beesdoo_shift_shift
SET state = 'absent_1'
FROM res_partner
WHERE beesdoo_shift_shift.worker_id = res_partner.id
AND beesdoo_shift_shift.old_code = 'excused'
AND res_partner.working_mode = 'regular'
"""
)
cr.execute(
"""
UPDATE beesdoo_shift_shift
SET state = 'absent_0'
FROM res_partner
WHERE beesdoo_shift_shift.worker_id = res_partner.id
AND beesdoo_shift_shift.old_code = 'excused_necessity'
"""
)
cr.execute(
"""
UPDATE beesdoo_shift_shift
SET state = 'absent_0'
WHERE beesdoo_shift_shift.state = 'excused'
"""
)
cr.execute(
"""
DELETE FROM beesdoo_shift_shift
WHERE beesdoo_shift_shift.state = 'absent'
"""
)
# Drop temporary columns
cr.execute("ALTER TABLE beesdoo_shift_shift DROP COLUMN old_code")

16
beesdoo_shift/migrations/9.0.1.3.0/pre-migrate.py

@ -0,0 +1,16 @@
# coding: utf-8
def migrate(cr, version):
# Record information from old shift stage
cr.execute("ALTER TABLE beesdoo_shift_shift ADD old_code varchar")
cr.execute(
"""
UPDATE beesdoo_shift_shift
SET old_code = (
SELECT code
FROM beesdoo_shift_stage
WHERE id = stage_id
)
"""
)

2
beesdoo_shift/models/planning.py

@ -174,7 +174,7 @@ class TaskTemplate(models.Model):
'is_regular': True if worker_id else False,
'start_time' : rec.start_date,
'end_time' : rec.end_date,
'stage_id': self.env.ref('beesdoo_shift.open').id,
'state': 'open',
})
return tasks

98
beesdoo_shift/models/task.py

@ -6,19 +6,6 @@ from openerp import _, api, fields, models
from openerp.exceptions import UserError, ValidationError
class TaskStage(models.Model):
_name = 'beesdoo.shift.stage'
_order = 'sequence asc'
name = fields.Char()
sequence = fields.Integer()
color = fields.Integer()
code = fields.Char(readonly=True)
@api.multi
def unlink(self):
raise UserError(_("You Cannot delete Task Stage"))
class Task(models.Model):
_name = 'beesdoo.shift.shift'
@ -39,9 +26,22 @@ class Task(models.Model):
])
start_time = fields.Datetime(track_visibility='always', index=True, required=True)
end_time = fields.Datetime(track_visibility='always', required=True)
stage_id = fields.Many2one('beesdoo.shift.stage', required=True, track_visibility='onchange', default=lambda self: self.env.ref('beesdoo_shift.open'))
state = fields.Selection(selection=[
("draft","Unconfirmed"),
("open","Confirmed"),
("done","Attended"),
("absent_2","Absent - 2 compensations"),
("absent_1","Absent - 1 compensation"),
("absent_0","Absent - 0 compensation"),
("cancel","Cancelled")
],
default="open",
required=True,
store=True,
track_visibility='onchange',
)
color = fields.Integer(compute="_compute_color")
super_coop_id = fields.Many2one('res.users', string="Super Cooperative", domain=[('partner_id.super', '=', True)], track_visibility='onchange')
color = fields.Integer(related="stage_id.color", readonly=True)
# TODO: Maybe is_regular and is_compensation must be merged in a
# selection field as they are mutually exclusive.
is_regular = fields.Boolean(default=False, string="Regular shift")
@ -55,6 +55,20 @@ class Task(models.Model):
revert_info = fields.Text(copy=False)
working_mode = fields.Selection(related='worker_id.working_mode')
@api.depends("state")
def _compute_color(self):
color_mapping = {
"draft": 0,
"open": 1,
"done": 5,
"absent_2": 2,
"absent_1": 7,
"absent_0": 3,
"cancel": 9,
}
for rec in self:
rec.color = color_mapping[rec.state]
def _compensation_validation(self, task):
"""
Raise a validation error if the fields is_regular and
@ -103,16 +117,6 @@ class Task(models.Model):
worker = self.env['res.partner'].browse(vals['worker_id'])
self.message_subscribe(partner_ids=worker.ids)
@api.model
def _read_group_stage_id(self, ids, domain, read_group_order=None, access_rights_uid=None):
res = self.env['beesdoo.shift.stage'].search([]).name_get()
fold = dict.fromkeys([r[0] for r in res], False)
return res, fold
_group_by_full = {
'stage_id': _read_group_stage_id,
}
#TODO button to replaced someone
@api.model
def unsubscribe_from_today(self, worker_ids, today=None, end_date=None):
@ -144,11 +148,11 @@ class Task(models.Model):
@api.multi
def write(self, vals):
"""
Overwrite write to track stage change
Overwrite write to track state change
If worker is changer:
Revert for the current worker
Change the worker info
Compute stage change for the new worker
Compute state change for the new worker
"""
if 'worker_id' in vals:
for rec in self:
@ -163,11 +167,11 @@ class Task(models.Model):
'is_compensation': vals.get('is_compensation',
rec.is_compensation),
})
rec._update_stage(rec.stage_id.id)
if 'stage_id' in vals:
rec._update_state(rec.state)
if 'state' in vals:
for rec in self:
if vals['stage_id'] != rec.stage_id.id:
rec._update_stage(vals['stage_id'])
if vals['state'] != rec.state:
rec._update_state(vals['state'])
return super(Task, self).write(vals)
def _set_revert_info(self, data, status):
@ -187,19 +191,15 @@ class Task(models.Model):
self.env['cooperative.status'].browse(data['status_id']).sudo()._change_counter(data['data'])
self.revert_info = False
def _update_stage(self, new_stage):
def _update_state(self, new_state):
self.ensure_one()
self._revert()
update = int(self.env['ir.config_parameter'].get_param('always_update', False))
new_stage = self.env['beesdoo.shift.stage'].browse(new_stage)
data = {}
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 no worker is defined for the shift") % new_stage.name)
if not (self.worker_id or self.replaced_id) and new_state in ("done", "absent_0", "absent_1", "absent_2"):
raise UserError(_("You cannot change to the status %s if no worker is defined for the shift") % new_state)
if update or not (self.worker_id or self.replaced_id):
return
@ -210,31 +210,31 @@ class Task(models.Model):
else:
status = self.replaced_id.cooperative_status_ids[0]
if new_stage == DONE and not self.is_regular:
if new_state == "done" and not self.is_regular:
# Regular counter is always updated first
if status.sr < 0:
data['sr'] = 1
elif status.sc < 0:
data['sc'] = 1
# Bonus shift case
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:
if new_state == "absent_2":
data['sr'] = -1
data['sc'] = -1
if new_stage == EXCUSED:
if new_state == "absent_1":
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:
if new_state == "done" or new_state == "absent_0":
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:
if new_state == "absent_2" or new_state == "absent_1":
if new_state == "absent_2":
data['sr'] = -1
data['irregular_absence_date'] = self.start_time[:10]
data['irregular_absence_counter'] = -1
@ -263,7 +263,7 @@ class Task(models.Model):
("start_time", ">", start_time.strftime("%Y-%m-%d 00:00:01")),
("start_time", "<", end_time.strftime("%Y-%m-%d 23:59:59")),
("worker_id", "!=", False),
("stage_id", "=", self.env.ref("beesdoo_shift.open").id),
("state", "=", "open"),
]
)

2
beesdoo_shift/security/ir.model.access.csv

@ -1,5 +1,4 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_coopplanning_task_stage,Attendance Read Stage,model_beesdoo_shift_stage,group_shift_attendance,1,0,0,0
access_coopplanning_task_type,Attendance Read Type,model_beesdoo_shift_type,group_shift_attendance,1,0,0,0
access_coopplanning_daynumber,Attendance Read Daynumber,model_beesdoo_shift_daynumber,group_shift_attendance,1,0,0,0
access_coopplanning_planning,Attendance Read Planning,model_beesdoo_shift_planning,group_shift_attendance,1,0,0,0
@ -8,7 +7,6 @@ access_coopplanning_task,Attendance Edit Shift,model_beesdoo_shift_shift,group_s
access_coopplanning_task_full,Shift Management all Shift,model_beesdoo_shift_shift,group_shift_management,1,1,1,1
access_coop_status,Coop Status Read for all,model_cooperative_status,,1,0,0,0
access_coop_status_all,Coop Status Admin,model_cooperative_status,group_cooperative_admin,1,1,1,1
all_config_coopplanning_task_stage,Attendance Read Stage,model_beesdoo_shift_stage,group_planning_management,1,1,1,1
all_config_coopplanning_task_type,Attendance Read Type,model_beesdoo_shift_type,group_planning_management,1,1,1,1
all_config_coopplanning_daynumber,Attendance Read Daynumber,model_beesdoo_shift_daynumber,group_planning_management,1,1,1,1
all_config_coopplanning_planning,Attendance Read Planning,model_beesdoo_shift_planning,group_planning_management,1,1,1,1

11
beesdoo_shift/views/task.xml

@ -12,7 +12,7 @@
<field name="worker_id" />
<field name="replaced_id" />
<field name="end_time" />
<field name="stage_id" />
<field name="state" />
</tree>
</field>
</record>
@ -57,7 +57,7 @@
<filter string="Type" name="gb_type"
context="{'group_by' : 'task_type_id'}" />
<filter string="Status" name="gb_status"
context="{'group_by' : 'stage_id'}" />
context="{'group_by' : 'state'}" />
<filter string="Day" name="gb_day"
context="{'group_by' : 'start_time:day'}" />
</group>
@ -84,8 +84,7 @@
<field name="arch" type="xml">
<form>
<header>
<field name="stage_id" widget="statusbar"
clickable="1" />
<field name="state" widget="statusbar" clickable="1" />
</header>
<sheet>
<div class="oe_title">
@ -135,7 +134,7 @@
<field name="color" />
<field name="task_type_id" />
<field name="name" />
<field name="stage_id" />
<field name="state" />
<field name="worker_id" />
<field name="super_coop_id" />
<field name="is_regular" />
@ -170,7 +169,7 @@
</div>
<div>
Status:
<field name="stage_id" />
<field name="state" />
</div>
<div t-if="record.task_type_id.raw_value">
Type:

12
beesdoo_website_shift/controllers/main.py

@ -143,14 +143,12 @@ class WebsiteShiftController(http.Controller):
# Get config
irregular_enable_sign_up = literal_eval(request.env['ir.config_parameter'].get_param(
'beesdoo_website_shift.irregular_enable_sign_up'))
# Get open status
open_status = request.env.ref('beesdoo_shift.open')
request.session['success'] = False
if (irregular_enable_sign_up
and self.user_can_subscribe()
and shift
and shift.stage_id == open_status
and shift.state == "open"
and not shift.worker_id):
shift.worker_id = cur_user.partner_id
request.session['success'] = True
@ -280,11 +278,10 @@ class WebsiteShiftController(http.Controller):
# Get all the shifts in the future with no worker
now = datetime.now()
open_status = request.env.ref('beesdoo_shift.open')
shifts = request.env['beesdoo.shift.shift'].sudo().search(
[('start_time', '>', now.strftime("%Y-%m-%d %H:%M:%S")),
('worker_id', '=', False),
('stage_id', '=', open_status.id)],
('state', '=', 'open')],
order="start_time, task_template_id, task_type_id",
)
@ -394,9 +391,6 @@ class WebsiteShiftController(http.Controller):
regular_next_shift_limit = int(request.env['ir.config_parameter'].get_param(
'beesdoo_website_shift.regular_next_shift_limit'))
# Get default status for fictive shifts
draft_status = request.env.ref('beesdoo_shift.draft')
for i in range(nb_subscribed_shifts, regular_next_shift_limit):
# Create the fictive shift
shift = main_shift.new()
@ -405,7 +399,7 @@ class WebsiteShiftController(http.Controller):
shift.planning_id = main_shift.planning_id
shift.task_type_id = main_shift.task_type_id
shift.worker_id = main_shift.worker_id
shift.stage_id = draft_status
shift.state = "draft"
shift.super_coop_id = main_shift.super_coop_id
shift.color = main_shift.color
shift.is_regular = main_shift.is_regular

30
beesdoo_website_shift/views/my_shift_website_templates.xml

@ -101,34 +101,34 @@
id="shift_status_label"
name="Shift Status Label">
<span t-if="shift.stage_id.code == 'draft'"
<span t-if="shift.state == 'draft'"
t-attf-class="label label-default {{label_css}}">
<t t-esc="shift.stage_id.name"/>
<t t-esc="shift.state"/>
</span>
<span t-if="shift.stage_id.code == 'done'"
<span t-if="shift.state == 'done'"
t-attf-class="label label-success {{label_css}}">
<t t-esc="shift.stage_id.name"/>
<t t-esc="shift.state"/>
</span>
<span t-if="shift.stage_id.code == 'absent'"
<span t-if="shift.state == 'absent_2'"
t-attf-class="label label-warning {{label_css}}">
<t t-esc="shift.stage_id.name"/>
<t t-esc="shift.state"/>
</span>
<span t-if="shift.stage_id.code == 'excused'"
<span t-if="shift.state == 'absent_1'"
t-attf-class="label label-info {{label_css}}">
<t t-esc="shift.stage_id.name"/>
<t t-esc="shift.state"/>
</span>
<span t-if="shift.stage_id.code == 'excused_necessity'"
<span t-if="shift.state == 'absent_0'"
t-attf-class="label label-info {{label_css}}">
<t t-esc="shift.stage_id.name"/>
<t t-esc="shift.state"/>
</span>
<span t-if="shift.stage_id.code == 'cancel'"
<span t-if="shift.state == 'cancel'"
t-attf-class="label label-danger {{label_css}}">
<t t-esc="shift.stage_id.name"/>
<t t-esc="shift.state"/>
</span>
</template>
@ -207,7 +207,7 @@
</thead>
<tbody>
<t t-foreach="subscribed_shifts" t-as="shift">
<tr t-att-class="'danger text-danger' if shift.stage_id.code == 'cancel' else ''">
<tr t-att-class="'danger text-danger' if shift.state == 'cancel' else ''">
<td>
<t t-esc="time.strftime('%A', time.strptime(shift.start_time, '%Y-%m-%d %H:%M:%S'))"/>
</td>
@ -222,7 +222,7 @@
<t t-esc="shift.task_type_id.name"/>
</td>
<td>
<t t-esc="shift.stage_id.name"/>
<t t-esc="shift.state"/>
</td>
<td class="text-center">
<button type="button" class="btn btn-default btn-sm"
@ -347,7 +347,7 @@
<t t-esc="shift.task_type_id.name"/>
</td>
<td>
<t t-esc="shift.stage_id.name"/>
<t t-esc="shift.state"/>
</td>
</tr>
</t>

Loading…
Cancel
Save