Commit ace150b0 by Etienne Freiss

Merge branch 'evolution_bdm' of…

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