Browse Source

[REF] b_shift : attendance sheet code cleaning

pull/143/head
Elouan Le Bars 5 years ago
parent
commit
4a72deca1d
  1. 227
      beesdoo_shift/models/attendance_sheet.py
  2. 8
      beesdoo_shift/wizard/validate_attendance_sheet.py

227
beesdoo_shift/models/attendance_sheet.py

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import date, datetime, timedelta
from lxml import etree from lxml import etree
from openerp import models, exceptions, fields, api, _
from openerp import _, api, exceptions, fields, models
from openerp.exceptions import UserError, ValidationError from openerp.exceptions import UserError, ValidationError
from datetime import date, datetime, timedelta
from lxml import etree
class AttendanceSheetShift(models.AbstractModel): class AttendanceSheetShift(models.AbstractModel):
_name = "beesdoo.shift.sheet.shift" _name = "beesdoo.shift.sheet.shift"
@ -23,8 +22,7 @@ class AttendanceSheetShift(models.AbstractModel):
task_types = self.env["beesdoo.shift.type"] task_types = self.env["beesdoo.shift.type"]
return task_types.browse(id) return task_types.browse(id)
# Related actual shift, not required because doesn't exist for added shift before validation
# To update after validation
# Related actual shift
task_id = fields.Many2one("beesdoo.shift.shift", string="Task") task_id = fields.Many2one("beesdoo.shift.shift", string="Task")
attendance_sheet_id = fields.Many2one( attendance_sheet_id = fields.Many2one(
"beesdoo.shift.sheet", "beesdoo.shift.sheet",
@ -42,7 +40,6 @@ class AttendanceSheetShift(models.AbstractModel):
], ],
string="Shift Stage", string="Shift Stage",
) )
worker_id = fields.Many2one( worker_id = fields.Many2one(
"res.partner", "res.partner",
string="Worker", string="Worker",
@ -119,7 +116,7 @@ class AttendanceSheetShiftAdded(models.Model):
_description = "Added Shift" _description = "Added Shift"
_inherit = ["beesdoo.shift.sheet.shift"] _inherit = ["beesdoo.shift.sheet.shift"]
# Change the previously determined two booleans for a more comprehensive field
# The two exclusive booleans are gathered in a selection field
regular_task_type = fields.Selection( regular_task_type = fields.Selection(
[("normal", "Normal"), ("compensation", "Compensation")], [("normal", "Normal"), ("compensation", "Compensation")],
string="Task Mode (if regular)", string="Task Mode (if regular)",
@ -127,7 +124,6 @@ class AttendanceSheetShiftAdded(models.Model):
) )
stage = fields.Selection(default="present") stage = fields.Selection(default="present")
# WARNING: check the code, readonly fields modified by onchange are not inserted on write
@api.onchange("working_mode") @api.onchange("working_mode")
def on_change_working_mode(self): def on_change_working_mode(self):
self.stage = "present" self.stage = "present"
@ -144,7 +140,7 @@ class AttendanceSheet(models.Model):
"ir.needaction_mixin", "ir.needaction_mixin",
"barcodes.barcode_events_mixin", "barcodes.barcode_events_mixin",
] ]
_description = "Attendance sheets with all the shifts in one time range."
_description = "Attendance sheet"
_order = "start_time" _order = "start_time"
name = fields.Char(string="Name", compute="_compute_name") name = fields.Char(string="Name", compute="_compute_name")
@ -187,6 +183,7 @@ class AttendanceSheet(models.Model):
"attendance_sheet_id", "attendance_sheet_id",
string="Added Shifts", string="Added Shifts",
) )
max_worker_no = fields.Integer( max_worker_no = fields.Integer(
string="Maximum number of workers", string="Maximum number of workers",
default=0, default=0,
@ -235,42 +232,17 @@ class AttendanceSheet(models.Model):
) )
] ]
@api.constrains(
"expected_shift_ids",
"added_shift_ids",
"annotation",
"feedback",
"worker_nb_feedback",
)
def _lock_after_validation(self):
if self.state == "validated":
raise UserError(
_("The sheet has already been validated and can't be edited.")
@api.depends("start_time", "end_time")
def _compute_name(self):
for rec in self:
start_time_dt = fields.Datetime.from_string(rec.start_time)
start_time_dt = fields.Datetime.context_timestamp(
rec, start_time_dt
) )
@api.multi
def button_mark_as_read(self):
if self.is_read:
raise UserError(_("The sheet has already been marked as read."))
self.is_read = True
@api.constrains("expected_shift_ids", "added_shift_ids")
def _constrain_unique_worker(self):
# Warning : map return generator in python3 (for Odoo 12)
added_ids = map(lambda s: s.worker_id.id, self.added_shift_ids)
expected_ids = map(lambda s: s.worker_id.id, self.expected_shift_ids)
replacement_ids = map(
lambda s: s.replacement_worker_id.id, self.expected_shift_ids
)
replacement_ids = filter(bool, replacement_ids)
ids = added_ids + expected_ids + replacement_ids
if (len(ids) - len(set(ids))) > 0:
raise UserError(
_(
"You can't add the same worker more than once to an attendance sheet."
if rec.time_slot:
rec.name = (
fields.Date.to_string(start_time_dt) + " " + rec.time_slot
) )
)
@api.depends("start_time", "end_time") @api.depends("start_time", "end_time")
def _compute_time_slot(self): def _compute_time_slot(self):
@ -287,18 +259,6 @@ class AttendanceSheet(models.Model):
+ end_time_dt.strftime("%H:%M") + end_time_dt.strftime("%H:%M")
) )
@api.depends("start_time", "end_time")
def _compute_name(self):
for rec in self:
start_time_dt = fields.Datetime.from_string(rec.start_time)
start_time_dt = fields.Datetime.context_timestamp(
rec, start_time_dt
)
if rec.time_slot:
rec.name = (
fields.Date.to_string(start_time_dt) + " " + rec.time_slot
)
@api.depends("start_time") @api.depends("start_time")
def _compute_day(self): def _compute_day(self):
for rec in self: for rec in self:
@ -323,11 +283,92 @@ class AttendanceSheet(models.Model):
) )
rec.default_super_coop_id = shift.super_coop_id rec.default_super_coop_id = shift.super_coop_id
# Is this method necessary ?
@api.depends("annotation") @api.depends("annotation")
def _compute_is_annotated(self): def _compute_is_annotated(self):
for rec in self: for rec in self:
rec.is_annotated = (rec.annotation.strip() != False)
rec.is_annotated = bool(rec.annotation.strip())
@api.constrains("expected_shift_ids", "added_shift_ids")
def _constrain_unique_worker(self):
# Warning : map return generator in python3 (for Odoo 12)
added_ids = map(lambda s: s.worker_id.id, self.added_shift_ids)
expected_ids = map(lambda s: s.worker_id.id, self.expected_shift_ids)
replacement_ids = map(
lambda s: s.replacement_worker_id.id, self.expected_shift_ids
)
replacement_ids = filter(bool, replacement_ids)
ids = added_ids + expected_ids + replacement_ids
if (len(ids) - len(set(ids))) > 0:
raise UserError(
_(
"You can't add the same worker more than once to an attendance sheet."
)
)
@api.constrains(
"expected_shift_ids",
"added_shift_ids",
"annotation",
"feedback",
"worker_nb_feedback",
)
def _lock_after_validation(self):
if self.state == "validated":
raise UserError(
_("The sheet has already been validated and can't be edited.")
)
def on_barcode_scanned(self, barcode):
if self.state == "validated":
raise UserError(
_("You cannot modify a validated attendance sheet.")
)
worker = self.env["res.partner"].search([("barcode", "=", barcode)])
if not len(worker):
raise UserError(_("Worker not found (invalid barcode or status)."))
if len(worker) > 1:
raise UserError(
_("Multiple workers are corresponding this barcode.")
)
if worker.state in ("unsubscribed", "resigning"):
raise UserError(_("Worker is %s.") % worker.state)
if worker.working_mode not in ("regular", "irregular"):
raise UserError(
_("Worker is %s and should be regular or irregular.")
% worker.working_mode
)
for id in self.expected_shift_ids.ids:
shift = self.env["beesdoo.shift.sheet.expected"].browse(id)
if (
shift.worker_id == worker
or shift.replacement_worker_id == worker
):
shift.stage = "present"
return
if worker.working_mode == "regular":
regular_task_type = "compensation"
else:
regular_task_type = False
added_ids = map(lambda s: s.worker_id.id, self.added_shift_ids)
if worker.id in added_ids:
raise UserError(_("Worker is already present."))
self.added_shift_ids |= self.added_shift_ids.new(
{
"task_type_id": self.added_shift_ids.default_task_type_id(),
"stage": "present",
"attendance_sheet_id": self._origin.id,
"worker_id": worker.id,
"regular_task_type": regular_task_type,
}
)
@api.model @api.model
def create(self, vals): def create(self, vals):
@ -367,8 +408,14 @@ class AttendanceSheet(models.Model):
new_sheet.max_worker_no = sum(r.worker_nb for r in task_templates) new_sheet.max_worker_no = sum(r.worker_nb for r in task_templates)
return new_sheet return new_sheet
# Workaround to display notifications only for unread and not validated
# sheets, via a check on domain.
@api.multi
def button_mark_as_read(self):
if self.is_read:
raise UserError(_("The sheet has already been marked as read."))
self.is_read = True
# Workaround to display notifications only
# for unread and not validated sheets, via a check on domain.
@api.model @api.model
def _needaction_count(self, domain=None): def _needaction_count(self, domain=None):
if domain == [ if domain == [
@ -426,14 +473,10 @@ class AttendanceSheet(models.Model):
# Expected shifts status update # Expected shifts status update
for expected_shift in self.expected_shift_ids: for expected_shift in self.expected_shift_ids:
actual_shift = expected_shift.task_id actual_shift = expected_shift.task_id
# We get stage record corresponding to mapped stage id
actual_stage = self.env.ref( actual_stage = self.env.ref(
"beesdoo_shift.%s" % expected_shift.get_actual_stage() "beesdoo_shift.%s" % expected_shift.get_actual_stage()
) )
# If the actual stage has been deleted, the sheet is still validated.
# Raising an exception would stop this but would prevent validation.
# How can we show a message without stopping validation ?
if actual_stage: if actual_stage:
actual_shift.stage_id = actual_stage actual_shift.stage_id = actual_stage
actual_shift.replaced_id = expected_shift.replacement_worker_id actual_shift.replaced_id = expected_shift.replacement_worker_id
@ -445,7 +488,6 @@ class AttendanceSheet(models.Model):
) )
is_regular_worker = added_shift.worker_id.working_mode == "regular" is_regular_worker = added_shift.worker_id.working_mode == "regular"
is_regular_shift = added_shift.regular_task_type == "normal" is_regular_shift = added_shift.regular_task_type == "normal"
# Add an annotation if a regular worker is doing its regular shift
if is_regular_shift and is_regular_worker: if is_regular_shift and is_regular_worker:
warning_message = ( warning_message = (
_( _(
@ -501,10 +543,9 @@ class AttendanceSheet(models.Model):
self.state = "validated" self.state = "validated"
return return
# @api.multi is needed to call the wizard, but doesn't match @api.one
# from the validate(user) method
@api.multi @api.multi
def validate_via_wizard(self): def validate_via_wizard(self):
self.ensure_one()
if self.env.user.has_group("beesdoo_shift.group_cooperative_admin"): if self.env.user.has_group("beesdoo_shift.group_cooperative_admin"):
self.validate(self.env.user.partner_id) self.validate(self.env.user.partner_id)
return return
@ -522,7 +563,6 @@ class AttendanceSheet(models.Model):
Generate sheets 20 minutes before current time. Generate sheets 20 minutes before current time.
Corresponding CRON intervall time must be the same. Corresponding CRON intervall time must be the same.
Check if any task exists in the time intervall. Check if any task exists in the time intervall.
If no sheet is already created, it is created.
""" """
time_ranges = set() time_ranges = set()
@ -549,54 +589,3 @@ class AttendanceSheet(models.Model):
sheet = sheets.create( sheet = sheets.create(
{"start_time": start_time, "end_time": end_time} {"start_time": start_time, "end_time": end_time}
) )
def on_barcode_scanned(self, barcode):
if self.state == "validated":
raise UserError(
_("You cannot modify a validated attendance sheet.")
)
worker = self.env["res.partner"].search([("barcode", "=", barcode)])
if not len(worker):
raise UserError(_("Worker not found (invalid barcode or status)."))
if len(worker) > 1:
raise UserError(
_("Multiple workers are corresponding this barcode.")
)
if worker.state in ("unsubscribed", "resigning"):
raise UserError(_("Worker is %s.") % worker.state)
if worker.working_mode not in ("regular", "irregular"):
raise UserError(
_("Worker is %s and should be regular or irregular.")
% worker.working_mode
)
for id in self.expected_shift_ids.ids:
shift = self.env["beesdoo.shift.sheet.expected"].browse(id)
if (
shift.worker_id == worker
or shift.replacement_worker_id == worker
):
shift.stage = "present"
return
if worker.working_mode == "regular":
regular_task_type = "compensation"
else:
regular_task_type = False
added_ids = map(lambda s: s.worker_id.id, self.added_shift_ids)
if worker.id in added_ids:
raise UserError(_("Worker is already present."))
self.added_shift_ids |= self.added_shift_ids.new(
{
"task_type_id": self.added_shift_ids.default_task_type_id(),
"stage": "present",
"attendance_sheet_id": self._origin.id,
"worker_id": worker.id,
"regular_task_type": regular_task_type,
}
)

8
beesdoo_shift/wizard/validate_attendance_sheet.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from openerp import models, fields, api, exceptions, _
from openerp import _, api, exceptions, fields, models
from openerp.exceptions import UserError, ValidationError from openerp.exceptions import UserError, ValidationError
@ -25,6 +25,9 @@ class ValidateAttendanceSheet(models.TransientModel):
required=True, required=True,
) )
def on_barcode_scanned(self, barcode):
self.barcode = barcode
@api.multi @api.multi
def validate_sheet(self): def validate_sheet(self):
sheet_id = self._context.get("active_id") sheet_id = self._context.get("active_id")
@ -46,6 +49,3 @@ class ValidateAttendanceSheet(models.TransientModel):
sheet.feedback += self.feedback sheet.feedback += self.feedback
sheet.worker_nb_feedback = self.worker_nb_feedback sheet.worker_nb_feedback = self.worker_nb_feedback
sheet.validate(user or self.env.user.partner_id) sheet.validate(user or self.env.user.partner_id)
def on_barcode_scanned(self, barcode):
self.barcode = barcode
Loading…
Cancel
Save