eo_conges: add support for half days off (#72676)
gitea/barbacompta/pipeline/head This commit looks good
Details
gitea/barbacompta/pipeline/head This commit looks good
Details
This commit is contained in:
parent
7f25841bce
commit
00bc42b98a
|
@ -149,16 +149,25 @@ class WorkersMonthlyReport(MonthMixin, YearMixin, TemplateView):
|
|||
worker_possible_names = [slugify(x) for x in worker_possible_names]
|
||||
|
||||
errors = []
|
||||
day_off = None
|
||||
days_off = None
|
||||
days_off = [x for x in day_off_events if self.is_event_for_worker(x, worker_possible_names)]
|
||||
if len(days_off) > 1:
|
||||
half_days_off = [
|
||||
x
|
||||
for x in days_off
|
||||
if hasattr(x.dtstart.value, 'time')
|
||||
and (
|
||||
x.dtstart.value.time() > datetime.time(12, 00)
|
||||
or x.dtend.value.time() <= datetime.time(15, 00)
|
||||
)
|
||||
]
|
||||
if len(days_off) > 2 or len(days_off) == 2 and len(half_days_off) != 2:
|
||||
errors.append(
|
||||
'%s a plusieurs jours off : %s.' % (name, ', '.join(x.summary.value for x in days_off))
|
||||
'%s a trop de jours off : %s.' % (name, ', '.join(x.summary.value for x in days_off))
|
||||
)
|
||||
elif not days_off:
|
||||
errors.append("%s n'a pas de jour off." % name)
|
||||
else:
|
||||
day_off = days_off[0].getrruleset()[0].weekday()
|
||||
days_off = [x.getrruleset()[0].weekday() for x in days_off]
|
||||
|
||||
def get_date_end(event):
|
||||
if hasattr(event, 'rrule'):
|
||||
|
@ -171,7 +180,7 @@ class WorkersMonthlyReport(MonthMixin, YearMixin, TemplateView):
|
|||
for x in holidays_events
|
||||
if self.is_event_for_worker(x, worker_possible_names)
|
||||
]
|
||||
holidays = self.normalize_holidays(holidays, day_off)
|
||||
holidays = self.normalize_holidays(holidays, days_off)
|
||||
|
||||
ignore = worker.get('ignore', False)
|
||||
if not ignore:
|
||||
|
@ -199,7 +208,7 @@ class WorkersMonthlyReport(MonthMixin, YearMixin, TemplateView):
|
|||
|
||||
return worker_match
|
||||
|
||||
def normalize_holidays(self, worker_holidays, day_off=None):
|
||||
def normalize_holidays(self, worker_holidays, days_off=None):
|
||||
def make_holiday(start, end):
|
||||
if type(start) != type(end):
|
||||
start = start.date() if hasattr(start, 'date') else start
|
||||
|
@ -225,18 +234,23 @@ class WorkersMonthlyReport(MonthMixin, YearMixin, TemplateView):
|
|||
def split_holidays_on_day_off(holiday):
|
||||
start, end = holiday.start, holiday.end
|
||||
if start == end:
|
||||
if start.weekday() != day_off:
|
||||
if start.weekday() not in days_off:
|
||||
yield holiday
|
||||
elif len(days_off) == 2:
|
||||
holiday.half = True
|
||||
yield holiday
|
||||
return
|
||||
|
||||
if start.weekday() == day_off:
|
||||
if len(days_off) == 1 and start.weekday() == days_off[0]:
|
||||
start += datetime.timedelta(days=1)
|
||||
|
||||
interval_start = start
|
||||
for i in range((end - start).days + 1):
|
||||
interval_end = start + datetime.timedelta(days=i)
|
||||
if interval_end.weekday() == day_off:
|
||||
if interval_end.weekday() in days_off:
|
||||
yield Holiday(interval_start, interval_end - datetime.timedelta(days=1))
|
||||
if len(days_off) == 2:
|
||||
yield Holiday(interval_end, interval_end, half=True)
|
||||
interval_start = interval_end + datetime.timedelta(days=1)
|
||||
|
||||
if interval_start <= interval_end:
|
||||
|
@ -252,7 +266,7 @@ class WorkersMonthlyReport(MonthMixin, YearMixin, TemplateView):
|
|||
|
||||
worker_holidays = [make_holiday(*dates) for dates in worker_holidays]
|
||||
|
||||
if day_off is not None:
|
||||
if days_off is not None:
|
||||
worker_holidays = [
|
||||
sub_holiday
|
||||
for holiday in worker_holidays
|
||||
|
|
|
@ -159,7 +159,27 @@ def test_conges_day_off_error(mocked_get_events, app, settings):
|
|||
mocked_get_events.return_value = [ev1, ev2]
|
||||
|
||||
resp = app.get('/conges/2023/01/')
|
||||
assert 'Jean Dupont a plusieurs jours off : Jean off, Jean off 2.' in resp.text
|
||||
assert 'Jean Dupont a trop de jours off : Jean off, Jean off 2.' in resp.text
|
||||
|
||||
ev1.dtstart.value = datetime.datetime(2023, 1, 6, 8, 0)
|
||||
ev1.dtend.value = datetime.datetime(2023, 1, 6, 13, 0)
|
||||
ev2.dtstart.value = datetime.datetime(2023, 1, 9, 14, 0)
|
||||
ev2.dtend.value = datetime.datetime(2023, 1, 9, 19, 0)
|
||||
|
||||
resp = app.get('/conges/2023/01/')
|
||||
assert 'Jean Dupont a trop de jours off' not in resp.text
|
||||
|
||||
ev3 = get_event(
|
||||
'Jean off 3',
|
||||
datetime.datetime(2023, 1, 9, 14, 0),
|
||||
datetime.datetime(2023, 1, 10, 19, 0),
|
||||
category='Journées off',
|
||||
)
|
||||
ev3.add('rrule').value = 'FREQ=WEEKLY;BYDAY=TH'
|
||||
mocked_get_events.return_value.append(ev3)
|
||||
|
||||
resp = app.get('/conges/2023/01/')
|
||||
assert 'Jean Dupont a trop de jours off : Jean off, Jean off 2, Jean off 3.' in resp.text
|
||||
|
||||
|
||||
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
|
||||
|
@ -308,6 +328,51 @@ def test_conges_split_on_day_off(mocked_get_events, app, settings):
|
|||
)
|
||||
|
||||
|
||||
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
|
||||
def test_conges_split_on_multiple_days_off(mocked_get_events, app, settings):
|
||||
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
|
||||
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
|
||||
]
|
||||
|
||||
holidays = get_event('Jean', datetime.date(2023, 1, 2), datetime.date(2023, 1, 7))
|
||||
events = mocked_get_events.return_value = [holidays]
|
||||
|
||||
login(app)
|
||||
resp = app.get('/conges/2023/01/')
|
||||
assert resp.pyquery('.worker span.holidays').text() == 'Congés : du 02 au 06/01.'
|
||||
|
||||
ev1 = get_event(
|
||||
'Jean off lundi matin',
|
||||
datetime.datetime(2023, 1, 6, 8, 0),
|
||||
datetime.datetime(2023, 1, 6, 13, 0),
|
||||
category='Journées off',
|
||||
)
|
||||
ev1.add('rrule').value = 'FREQ=WEEKLY;BYDAY=MO'
|
||||
ev2 = get_event(
|
||||
'Jean off mercredi aprem',
|
||||
datetime.datetime(2023, 1, 9, 14, 0),
|
||||
datetime.datetime(2023, 1, 9, 19, 0),
|
||||
category='Journées off',
|
||||
)
|
||||
ev2.add('rrule').value = 'FREQ=WEEKLY;BYDAY=WE'
|
||||
mocked_get_events.return_value += [ev1, ev2]
|
||||
|
||||
resp = app.get('/conges/2023/01/')
|
||||
assert (
|
||||
resp.pyquery('.worker span.holidays').text()
|
||||
== 'Congés : 0,5j le 02/01, le 03/01, 0,5j le 04/01, les 05 et 06/01.'
|
||||
)
|
||||
|
||||
# long holidays get split multiple times
|
||||
holidays.dtend.value = datetime.date(2023, 1, 14)
|
||||
|
||||
resp = app.get('/conges/2023/01/')
|
||||
assert resp.pyquery('.worker span.holidays').text() == (
|
||||
'Congés : 0,5j le 02/01, le 03/01, 0,5j le 04/01, les 05 et 06/01, 0,5j le 09/01, '
|
||||
'le 10/01, 0,5j le 11/01, les 12 et 13/01.'
|
||||
)
|
||||
|
||||
|
||||
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
|
||||
def test_conges_split_on_day_off_single_day(mocked_get_events, app, settings):
|
||||
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
|
||||
|
@ -335,3 +400,36 @@ def test_conges_split_on_day_off_single_day(mocked_get_events, app, settings):
|
|||
|
||||
resp = app.get('/conges/2023/01/')
|
||||
assert resp.pyquery('.worker span.holidays').text() == 'Congés : 0.'
|
||||
|
||||
|
||||
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
|
||||
def test_conges_split_on_multiple_days_off_single_day(mocked_get_events, app, settings):
|
||||
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
|
||||
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
|
||||
]
|
||||
|
||||
ev1 = get_event(
|
||||
'Jean off lundi matin',
|
||||
datetime.datetime(2023, 1, 6, 8, 0),
|
||||
datetime.datetime(2023, 1, 6, 13, 0),
|
||||
category='Journées off',
|
||||
)
|
||||
ev1.add('rrule').value = 'FREQ=WEEKLY;BYDAY=MO'
|
||||
ev2 = get_event(
|
||||
'Jean off mercredi aprem',
|
||||
datetime.datetime(2023, 1, 9, 14, 0),
|
||||
datetime.datetime(2023, 1, 9, 19, 0),
|
||||
category='Journées off',
|
||||
)
|
||||
ev2.add('rrule').value = 'FREQ=WEEKLY;BYDAY=WE'
|
||||
|
||||
mocked_get_events.return_value = [
|
||||
ev1,
|
||||
ev2,
|
||||
# holidays on monday
|
||||
get_event('Jean', datetime.date(2023, 1, 2), datetime.date(2023, 1, 3)),
|
||||
]
|
||||
|
||||
login(app)
|
||||
resp = app.get('/conges/2023/01/')
|
||||
assert resp.pyquery('.worker span.holidays').text() == 'Congés : 0,5j le 02/01.'
|
||||
|
|
Loading…
Reference in New Issue