Skip to content

Commit d6f9df1

Browse files
MatteoLdxremytms
authored andcommitted
[CHG] beesdoo_shift: compute next shifts
1 parent 5984d79 commit d6f9df1

File tree

6 files changed

+143
-9
lines changed

6 files changed

+143
-9
lines changed

beesdoo_shift/__manifest__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"author": "Thibault Francois, Elouan Le Bars, Coop IT Easy SCRLfs",
1010
"website": "https://github.com/beescoop/Obeesdoo",
1111
"category": "Cooperative management",
12-
"version": "12.0.1.1.4",
12+
"version": "12.0.2.0.0",
1313
"depends": ["mail"],
1414
"data": [
1515
"data/system_parameter.xml",

beesdoo_shift/data/system_parameter.xml

+12
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,16 @@
3131
<field name="key">regular_counter_to_unsubscribe</field>
3232
<field name="value">-4</field>
3333
</record>
34+
<record id="min_percentage_presence" model="ir.config_parameter">
35+
<field name="key">beesdoo_shift.min_percentage_presence</field>
36+
<field name="value">20</field>
37+
</record>
38+
<record id="regular_next_shift_limit" model="ir.config_parameter">
39+
<field name="key">beesdoo_shift.regular_next_shift_limit</field>
40+
<field name="value">7</field>
41+
</record>
42+
<record id="min_hours_to_unsubscribe" model="ir.config_parameter">
43+
<field name="key">min_hours_to_unsubscribe</field>
44+
<field name="value">2</field>
45+
</record>
3446
</odoo>

beesdoo_shift/models/planning.py

+85-5
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,60 @@ def _generate_next_planning(self):
106106
_logger.error("Could not generate next planning: no task template defined.")
107107
return
108108

109-
planning.task_template_ids._generate_task_day()
109+
planning.task_template_ids.generate_task_day()
110110

111111
next_date = planning._get_next_planning_date(date)
112112
config.set_param("last_planning_seq", planning.sequence)
113113
config.set_param("next_planning_date", next_date)
114114

115+
@api.model
116+
def get_future_shifts(self, end_date):
117+
"""
118+
Calculates shifts between now and end_date without
119+
storing them in the database
120+
Uses a list of shifts instead of a recordset because
121+
of issues occuring when copying records
122+
:param end_date: Datetime
123+
:return: beesdoo.shift.shift list
124+
"""
125+
start_date = datetime.now()
126+
127+
shift_list = list(
128+
self.env["beesdoo.shift.shift"]
129+
.sudo()
130+
.search(
131+
[("start_time", ">", start_date.strftime("%Y-%m-%d %H:%M:%S"))],
132+
order="start_time, task_template_id, task_type_id",
133+
)
134+
)
135+
136+
last_sequence = int(
137+
self.env["ir.config_parameter"].sudo().get_param("last_planning_seq")
138+
)
139+
140+
next_planning = self._get_next_planning(last_sequence)
141+
142+
next_planning_date = fields.Datetime.from_string(
143+
self.env["ir.config_parameter"].sudo().get_param("next_planning_date", 0)
144+
)
145+
146+
next_planning = next_planning.with_context(visualize_date=next_planning_date)
147+
148+
while next_planning_date < end_date:
149+
for shift in next_planning.task_template_ids.get_task_day():
150+
if shift.start_time > start_date:
151+
shift_list.append(shift)
152+
next_planning_date = next_planning._get_next_planning_date(
153+
next_planning_date
154+
)
155+
last_sequence = next_planning.sequence
156+
next_planning = self._get_next_planning(last_sequence)
157+
next_planning = next_planning.with_context(
158+
visualize_date=next_planning_date
159+
)
160+
161+
return shift_list
162+
115163

116164
class TaskTemplate(models.Model):
117165
_name = "beesdoo.shift.template"
@@ -144,7 +192,7 @@ class TaskTemplate(models.Model):
144192
domain=[("is_worker", "=", True)],
145193
)
146194
remaining_worker = fields.Integer(
147-
compute="_compute_remaining", store=True, string="Remaining Spot"
195+
compute="_compute_remaining", store=True, string="Remaining Place"
148196
)
149197
active = fields.Boolean(default=True)
150198
# For Kanban View Only
@@ -212,8 +260,12 @@ def _set_duration(self):
212260
if self.start_time:
213261
self.end_time = self.start_time + self.duration
214262

215-
def _generate_task_day(self):
216-
tasks = self.env["beesdoo.shift.shift"]
263+
def _prepare_task_day(self):
264+
"""
265+
Generates a list of dict objects containing the informations
266+
for the shifts to generate based on the template data
267+
"""
268+
tasks = []
217269
for rec in self:
218270
for i in range(0, rec.worker_nb):
219271
worker_id = rec.worker_ids[i] if len(rec.worker_ids) > i else False
@@ -234,7 +286,7 @@ def _generate_task_day(self):
234286
and status.temporary_exempt_end_date >= rec.end_date.date()
235287
):
236288
worker_id = False
237-
tasks |= tasks.create(
289+
tasks.append(
238290
{
239291
"name": "[%s] %s %s (%s - %s) [%s]"
240292
% (
@@ -258,6 +310,34 @@ def _generate_task_day(self):
258310

259311
return tasks
260312

313+
@api.multi
314+
def get_task_day(self):
315+
"""
316+
Creates the shifts according to the template without saving
317+
them into the database.
318+
To adapt the behaviour, function _prepare_task_day()
319+
should be overwritten.
320+
"""
321+
tasks = self.env["beesdoo.shift.shift"]
322+
task_list = self._prepare_task_day()
323+
for task in task_list:
324+
tasks |= tasks.new(task)
325+
return tasks
326+
327+
@api.multi
328+
def generate_task_day(self):
329+
"""
330+
Creates the shifts according to the template and saves
331+
them into the database.
332+
To adapt the behaviour, function _prepare_task_day()
333+
should be overwritten.
334+
"""
335+
tasks = self.env["beesdoo.shift.shift"]
336+
task_list = self._prepare_task_day()
337+
for task in task_list:
338+
tasks |= tasks.create(task)
339+
return tasks
340+
261341
@api.onchange("worker_ids")
262342
def check_for_multiple_shifts(self):
263343
original_ids = {worker.id for worker in self._origin.worker_ids}

beesdoo_shift/models/res_partner.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from datetime import datetime
1+
from datetime import datetime, timedelta
22

33
from odoo import _, api, fields, models
44

@@ -195,4 +195,26 @@ def _update_shifts_on_subscribed_task_tmpl(
195195
now=datetime.now(),
196196
)
197197

198-
# TODO access right + vue on res.partner
198+
def get_next_shifts(self):
199+
"""
200+
Get the shifts of the user between now and an end_date,
201+
with end_date = 4 weeks * regular_next_shift_limit
202+
:return: beesdoo.shift.shift list
203+
"""
204+
regular_next_shift_limit = int(
205+
self.env["ir.config_parameter"]
206+
.sudo()
207+
.get_param("beesdoo_shift.regular_next_shift_limit")
208+
)
209+
nb_days = 28 * regular_next_shift_limit
210+
start_date = datetime.now()
211+
end_date = start_date + timedelta(days=nb_days)
212+
213+
shifts = self.env["beesdoo.shift.planning"].get_future_shifts(end_date)
214+
215+
next_shifts = []
216+
for rec in shifts:
217+
if rec.worker_id.id == self.id:
218+
next_shifts.append(rec)
219+
220+
return next_shifts

beesdoo_shift/models/task.py

+20
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def _get_final_state(self):
8282
)
8383
revert_info = fields.Text(copy=False)
8484
working_mode = fields.Selection(related="worker_id.working_mode")
85+
can_unsubscribe = fields.Boolean(compute="_compute_can_unsubscribe")
8586

8687
def _expand_states(self, states, domain, order):
8788
return [key for key, val in self._fields["state"].selection(self)]
@@ -91,6 +92,25 @@ def _compute_color(self):
9192
for rec in self:
9293
rec.color = self._get_color_mapping(rec.state)
9394

95+
def _compute_can_unsubscribe(self):
96+
now = datetime.now()
97+
ICP = self.env["ir.config_parameter"].sudo()
98+
min_hours = int(ICP.get_param("min_hours_to_unsubscribe", 2))
99+
for rec in self:
100+
if (
101+
rec.start_time > now
102+
and rec.state == "open"
103+
and (
104+
(rec.worker_id and rec.worker_id.working_mode == "irregular")
105+
or rec.is_compensation
106+
)
107+
):
108+
delta = rec.start_time - now
109+
delta = delta.seconds / 3600.0 + delta.days * 24
110+
rec.can_unsubscribe = delta >= min_hours
111+
else:
112+
rec.can_unsubscribe = False
113+
94114
@api.constrains("state")
95115
def _lock_future_task(self):
96116
if datetime.now() < self.start_time:

beesdoo_shift/wizard/instanciate_planning.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def _get_planning(self):
1717
def generate_task(self):
1818
self.ensure_one()
1919
self = self.with_context(visualize_date=self.date_start, tracking_disable=True)
20-
shifts = self.planning_id.task_template_ids._generate_task_day()
20+
shifts = self.planning_id.task_template_ids.generate_task_day()
2121
return {
2222
"name": _("Generated Shift"),
2323
"type": "ir.actions.act_window",

0 commit comments

Comments
 (0)