Commit fc8a47ca by Etienne Freiss

Merge branch 'evolution_bdm' of…

Merge branch 'evolution_bdm' of https://gl.cooperatic.fr/cooperatic-foodcoops/third-party into ticket_1682
parents 67c555a8 1c77c4b9
Pipeline #1449 passed with stage
in 1 minute 48 seconds
...@@ -134,5 +134,5 @@ BLOCK_SERVICE_EXCHANGE_24H_BEFORE = True ...@@ -134,5 +134,5 @@ BLOCK_SERVICE_EXCHANGE_24H_BEFORE = True
ORDERS_HELPER_METABASE_URL = "url_meta_base" ORDERS_HELPER_METABASE_URL = "url_meta_base"
# New members space # New members space
USE_NEW_MEMBERS_SPACE = True USE_NEW_MEMBERS_SPACE = True
START_DATE_FOR_POINTS_HISTORY = "2018-01-01" START_DATE_FOR_SHIFTS_HISTORY = "2018-01-01"
...@@ -1117,24 +1117,26 @@ class CagetteServices(models.Model): ...@@ -1117,24 +1117,26 @@ class CagetteServices(models.Model):
def get_services_at_time(time, tz_offset, with_members=True): def get_services_at_time(time, tz_offset, with_members=True):
"""Retrieve present services with member linked.""" """Retrieve present services with member linked."""
# import operator default_acceptable_minutes_after_shift_begins = getattr(settings, 'ACCEPTABLE_ENTRANCE_MINUTES_AFTER_SHIFT_BEGINS', 15)
min_before_shift_starts_delay = 20 minutes_before_shift_starts_delay = getattr(settings, 'ACCEPTABLE_ENTRANCE_MINUTES_BEFORE_SHIFT', 15)
min_after_shift_starts_delay = 20 minutes_after_shift_starts_delay = default_acceptable_minutes_after_shift_begins
late_mode = getattr(settings, 'ENTRANCE_WITH_LATE_MODE', False) late_mode = getattr(settings, 'ENTRANCE_WITH_LATE_MODE', False)
max_duration = getattr(settings, 'MAX_DURATION', 180)
if late_mode is True: if late_mode is True:
min_before_shift_starts_delay = getattr(settings, 'ENTRANCE_VALIDATION_GRACE_DELAY', 60) minutes_after_shift_starts_delay = getattr(settings, 'ENTRANCE_VALIDATION_GRACE_DELAY', 60)
min_after_shift_starts_delay = 0
api = OdooAPI() api = OdooAPI()
now = dateutil.parser.parse(time) - datetime.timedelta(minutes=tz_offset) now = dateutil.parser.parse(time) - datetime.timedelta(minutes=tz_offset)
start1 = now - datetime.timedelta(minutes=min_before_shift_starts_delay) start1 = now + datetime.timedelta(minutes=minutes_before_shift_starts_delay)
start2 = now + datetime.timedelta(minutes=min_after_shift_starts_delay) start2 = now - datetime.timedelta(minutes=minutes_after_shift_starts_delay)
cond = [['date_begin_tz', '>=', start1.isoformat()], end = start1 + datetime.timedelta(minutes=max_duration)
['date_begin_tz', '<=', start2.isoformat()]] cond = [['date_end_tz', '<=', end.isoformat()]]
cond.append('|')
cond.append(['date_begin_tz', '>=', start1.isoformat()])
cond.append(['date_begin_tz', '>=', start2.isoformat()])
fields = ['name', 'week_number', 'registration_ids', fields = ['name', 'week_number', 'registration_ids',
'standard_registration_ids', 'standard_registration_ids',
'shift_template_id', 'shift_ticket_ids', 'shift_template_id', 'shift_ticket_ids',
'date_begin_tz', 'date_end_tz'] 'date_begin_tz', 'date_end_tz']
## return (start1.isoformat(), start2.isoformat())
services = api.search_read('shift.shift', cond, fields,order ="date_begin_tz ASC") services = api.search_read('shift.shift', cond, fields,order ="date_begin_tz ASC")
for s in services: for s in services:
if (len(s['registration_ids']) > 0): if (len(s['registration_ids']) > 0):
...@@ -1143,7 +1145,7 @@ class CagetteServices(models.Model): ...@@ -1143,7 +1145,7 @@ class CagetteServices(models.Model):
now.replace(tzinfo=None) now.replace(tzinfo=None)
- -
dateutil.parser.parse(s['date_begin_tz']).replace(tzinfo=None) dateutil.parser.parse(s['date_begin_tz']).replace(tzinfo=None)
).seconds / 60 > min_after_shift_starts_delay ).total_seconds() / 60 > default_acceptable_minutes_after_shift_begins
if with_members is True: if with_members is True:
cond = [['id', 'in', s['registration_ids']], ['state', '!=', 'cancel']] cond = [['id', 'in', s['registration_ids']], ['state', '!=', 'cancel']]
fields = ['partner_id', 'shift_type', 'state'] fields = ['partner_id', 'shift_type', 'state']
...@@ -1211,14 +1213,17 @@ class CagetteServices(models.Model): ...@@ -1211,14 +1213,17 @@ class CagetteServices(models.Model):
return api.update('shift.registration', [int(reg_id)], f) return api.update('shift.registration', [int(reg_id)], f)
@staticmethod @staticmethod
def record_absences(): def record_absences(date):
"""Called by cron script.""" """Called by cron script."""
import dateutil.parser import dateutil.parser
now = datetime.datetime.now() if len(date) > 0:
now = dateutil.parser.parse(date)
else:
now = datetime.datetime.now()
# now = dateutil.parser.parse('2020-09-15T15:00:00Z') # now = dateutil.parser.parse('2020-09-15T15:00:00Z')
date_24h_before = now - datetime.timedelta(hours=24) date_24h_before = now - datetime.timedelta(hours=24)
# let authorized people time to set presence for those who came in late # let authorized people time to set presence for those who came in late
end_date = now - datetime.timedelta(hours=3) end_date = now - datetime.timedelta(hours=2)
api = OdooAPI() api = OdooAPI()
absence_status = 'excused' absence_status = 'excused'
res_c = api.search_read('ir.config_parameter', res_c = api.search_read('ir.config_parameter',
......
...@@ -40,7 +40,7 @@ urlpatterns = [ ...@@ -40,7 +40,7 @@ urlpatterns = [
url(r'^save_photo/([0-9]+)$', views.save_photo, name='save_photo'), url(r'^save_photo/([0-9]+)$', views.save_photo, name='save_photo'),
url(r'^services_at_time/([0-9TZ\-\: \.]+)/([0-9\-]+)$', views.services_at_time), url(r'^services_at_time/([0-9TZ\-\: \.]+)/([0-9\-]+)$', views.services_at_time),
url(r'^service_presence/$', views.record_service_presence), url(r'^service_presence/$', views.record_service_presence),
url(r'^record_absences$', views.record_absences), url(r'^record_absences/?([0-9\-\ \:]*)$', views.record_absences),
url(r'^close_ftop_service$', views.close_ftop_service), url(r'^close_ftop_service$', views.close_ftop_service),
url(r'^get_credentials$', views.get_credentials), url(r'^get_credentials$', views.get_credentials),
url(r'^remove_data_from_couchdb$', views.remove_data_from_CouchDB), url(r'^remove_data_from_couchdb$', views.remove_data_from_CouchDB),
......
...@@ -281,7 +281,8 @@ def record_service_presence(request): ...@@ -281,7 +281,8 @@ def record_service_presence(request):
import re import re
o_date = re.search(r'/([^\/]+?)$', request.META.get('HTTP_REFERER')) o_date = re.search(r'/([^\/]+?)$', request.META.get('HTTP_REFERER'))
if o_date: if o_date:
overrided_date = o_date.group(1) overrided_date = re.sub(r'(%20)',' ', o_date.group(1))
# rid = 0 => C'est un rattrapage, sur le service # rid = 0 => C'est un rattrapage, sur le service
if sid > 0 and stid > 0: if sid > 0 and stid > 0:
# Add member to service and take presence into account # Add member to service and take presence into account
...@@ -289,7 +290,6 @@ def record_service_presence(request): ...@@ -289,7 +290,6 @@ def record_service_presence(request):
if res['rattrapage'] is True: if res['rattrapage'] is True:
res['update'] = 'ok' res['update'] = 'ok'
else: else:
if (CagetteServices.registration_done(rid, overrided_date) is True): if (CagetteServices.registration_done(rid, overrided_date) is True):
res['update'] = 'ok' res['update'] = 'ok'
else: else:
...@@ -325,8 +325,8 @@ def easy_validate_shift_presence(request): ...@@ -325,8 +325,8 @@ def easy_validate_shift_presence(request):
else: else:
return JsonResponse(res, safe=False) return JsonResponse(res, safe=False)
def record_absences(request): def record_absences(request, date):
return JsonResponse({'res': CagetteServices.record_absences()}) return JsonResponse({'res': CagetteServices.record_absences(date)})
def close_ftop_service(request): def close_ftop_service(request):
"""Close the closest past FTOP service""" """Close the closest past FTOP service"""
......
...@@ -11,38 +11,37 @@ class CagetteMembersSpace(models.Model): ...@@ -11,38 +11,37 @@ class CagetteMembersSpace(models.Model):
"""Init with odoo id.""" """Init with odoo id."""
self.o_api = OdooAPI() self.o_api = OdooAPI()
def get_points_history(self, partner_id, limit, offset, date_from, shift_type): def get_shifts_history(self, partner_id, limit, offset, date_from):
""" Get partner points history with related shift registration if needed """ """ Get partner shifts history """
cond = [ res = {}
['partner_id', '=', partner_id], today = str(datetime.date.today())
['type', '=', shift_type],
['create_date', '>', date_from], try:
['point_qty', '!=', 0] cond = [
] ['partner_id', '=', partner_id],
f = ['create_date', 'create_uid', 'shift_id', 'name', 'point_qty'] ['create_date', '>', date_from],
['date_begin', '<', today],
res = self.o_api.search_read('shift.counter.event', cond, f, limit=limit, offset=offset, ['state', '!=', 'draft'],
order='create_date DESC') ['state', '!=', 'open'],
['state', '!=', 'waiting'],
# Get related data from shift.registration ['state', '!=', 'replaced'],
shift_ids = [] ['state', '!=', 'replacing'],
for item in res: ]
item['is_late'] = False # So every item has the attribute f = ['create_date', 'shift_id', 'name', 'state', 'is_late', 'is_makeup']
if item['shift_id'] is not False: marshal_none_error = 'cannot marshal None unless allow_none is enabled'
shift_ids.append(item['shift_id'][0]) try:
res = self.o_api.search_read('shift.registration', cond, f, limit=limit, offset=offset,
cond = [['shift_id', 'in', shift_ids]] order='create_date DESC')
f = ['is_late', 'shift_id'] except Exception as e:
if not (marshal_none_error in str(e)):
res_shift_registration = self.o_api.search_read('shift.registration', cond, f) res['error'] = repr(e)
coop_logger.error(res['error'] + ' : %s', str(payment_id))
for registration_item in res_shift_registration: else:
for shift_counter_item in res: res = []
if (shift_counter_item['shift_id'] is not False
and shift_counter_item['shift_id'] == registration_item['shift_id']): except Exception as e:
shift_counter_item['is_late'] = registration_item['is_late'] print(str(e))
break
return res return res
\ No newline at end of file
...@@ -35,7 +35,14 @@ table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child:before { ...@@ -35,7 +35,14 @@ table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child:before {
background-color: white; background-color: white;
font-weight: bold; font-weight: bold;
border: none; border: none;
font-size: 2rem; font-size: 1.6rem;
height: 16px;
width: 16px;
border-radius: 2em;
}
@media screen {
} }
table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before, table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before,
table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before { table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before {
...@@ -43,7 +50,10 @@ table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before { ...@@ -43,7 +50,10 @@ table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before {
background-color: white; background-color: white;
font-weight: bold; font-weight: bold;
border: none; border: none;
font-size: 2rem;; font-size: 1.6rem;
height: 16px;
width: 16px;
border-radius: 2em;
} }
.loading-more-history { .loading-more-history {
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
display: none; display: none;
width: min-content; width: min-content;
max-width: 100%; max-width: 100%;
white-space: nowrap;
} }
@media screen and (max-width:768px) { @media screen and (max-width:768px) {
......
...@@ -9,13 +9,12 @@ function load_partner_history(offset = 0) { ...@@ -9,13 +9,12 @@ function load_partner_history(offset = 0) {
return new Promise((resolve) => { return new Promise((resolve) => {
$.ajax({ $.ajax({
type: 'GET', type: 'GET',
url: "/members_space/get_points_history", url: "/members_space/get_shifts_history",
data: { data: {
partner_id: partner_data.concerned_partner_id, partner_id: partner_data.concerned_partner_id,
verif_token: partner_data.verif_token, verif_token: partner_data.verif_token,
limit: history_items_limit, limit: history_items_limit,
offset: offset, offset: offset,
shift_type: (partner_data.in_ftop_team === "True") ? "ftop" : "standard"
}, },
dataType:"json", dataType:"json",
traditional: true, traditional: true,
...@@ -49,36 +48,18 @@ function prepare_server_data(data) { ...@@ -49,36 +48,18 @@ function prepare_server_data(data) {
res = []; res = [];
for (history_item of data) { for (history_item of data) {
// Date formating history_item.details = '';
let datetime_shift_start = new Date(history_item.create_date); if (history_item.state === 'excused' || history_item.state === 'absent') {
history_item.details = "Absent";
let f_date_shift_start = datetime_shift_start.toLocaleDateString("fr-fr", date_options); } else if (history_item.state === 'done' && history_item.is_late != false) {
history_item.details = "Présent (En Retard)";
f_date_shift_start = f_date_shift_start.charAt(0).toUpperCase() + f_date_shift_start.slice(1); } else if (history_item.state === 'done') {
history_item.details = "Présent";
history_item.movement_date = f_date_shift_start + " - " + datetime_shift_start.toLocaleTimeString("fr-fr", time_options); } else if (history_item.state === 'cancel') {
history_item.details = "Annulé";
// Text replacements
history_item.name = (history_item.name === "Clôturer le service") ? "Décompte 28j" : history_item.name;//Clôlturer le service
history_item.name = (history_item.name === "Rattrapage") ? "Absence" : history_item.name;
if (history_item.name === "Clôturer le service" || history_item.name === "Clôlturer le service") {
history_item.name = "Décompte 28j";
} else if (history_item.name === "Rattrapage") {
history_item.name = "Absence";
} else if (history_item.name === "Présent" && history_item.is_late != false) {
history_item.name = "Retard";
}
history_item.created_by = history_item.create_uid[1];
if (history_item.created_by === "Administrator") {
history_item.created_by = "Administrateur";
} else if (history_item.created_by === "api") {
history_item.created_by = "Système";
} }
history_item.shift_name = (history_item.shift_id === false) ? '' : history_item.shift_id[1]; history_item.shift_name = (history_item.shift_id === false) ? '' : history_item.shift_id[1];
// if Present && is_late -> Absent
} }
return data; return data;
...@@ -99,18 +80,14 @@ function init_history() { ...@@ -99,18 +80,14 @@ function init_history() {
data: partner_history, data: partner_history,
columns: [ columns: [
{ {
data: "movement_date",
title: `Date`,
responsivePriority: 1
},
{
data: "shift_name", data: "shift_name",
title: "Service" title: "<spans class='dt-body-center'>Service</span>",
width: "60%",
}, },
{ {
data: "name", data: "details",
title: "Détails", title: "Détails",
responsivePriority: 3 className: "tablet-l desktop"
} }
], ],
iDisplayLength: -1, iDisplayLength: -1,
...@@ -126,7 +103,7 @@ function init_history() { ...@@ -126,7 +103,7 @@ function init_history() {
$(row).addClass('row_partner_ok'); $(row).addClass('row_partner_ok');
} else if (cell.text() === "Retard") { } else if (cell.text() === "Retard") {
$(row).addClass('row_partner_late'); $(row).addClass('row_partner_late');
} else if (cell.text() === "Absence") { } else if (cell.text() === "Absent") {
$(row).addClass('row_partner_absent'); $(row).addClass('row_partner_absent');
} }
} }
......
...@@ -10,6 +10,6 @@ urlpatterns = [ ...@@ -10,6 +10,6 @@ urlpatterns = [
url(r'^my_shifts$', views.my_shifts), url(r'^my_shifts$', views.my_shifts),
url(r'^shifts_exchange$', views.shifts_exchange), url(r'^shifts_exchange$', views.shifts_exchange),
url(r'^no_content$', views.no_content), url(r'^no_content$', views.no_content),
url(r'^get_points_history$', views.get_points_history), url(r'^get_shifts_history$', views.get_shifts_history),
url('/*$', views.index), url('/*$', views.index),
] ]
...@@ -165,7 +165,7 @@ def no_content(request): ...@@ -165,7 +165,7 @@ def no_content(request):
} }
return HttpResponse(template.render(context, request)) return HttpResponse(template.render(context, request))
def get_points_history(request): def get_shifts_history(request):
res = {} res = {}
partner_id = int(request.GET.get('partner_id')) partner_id = int(request.GET.get('partner_id'))
...@@ -173,8 +173,7 @@ def get_points_history(request): ...@@ -173,8 +173,7 @@ def get_points_history(request):
limit = int(request.GET.get('limit')) limit = int(request.GET.get('limit'))
offset = int(request.GET.get('offset')) offset = int(request.GET.get('offset'))
shift_type = request.GET.get('shift_type') date_from = getattr(settings, 'START_DATE_FOR_SHIFTS_HISTORY', '2018-01-01')
date_from = getattr(settings, 'START_DATE_FOR_POINTS_HISTORY', '2018-01-01') res["data"] = m.get_shifts_history(partner_id, limit, offset, date_from)
res["data"] = m.get_points_history(partner_id, limit, offset, date_from, shift_type)
return JsonResponse(res) return JsonResponse(res)
\ No newline at end of file
...@@ -352,7 +352,7 @@ ...@@ -352,7 +352,7 @@
Should be set to False by default if parameter not set Should be set to False by default if parameter not set
- START_DATE_FOR_POINTS_HISTORY = "2018-01-01" - START_DATE_FOR_SHIFTS_HISTORY = "2018-01-01"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment