Commit 43a0e6c6 by Damien Moulard

display member history

parent ca9333d4
...@@ -11,7 +11,7 @@ class CagetteMembersSpace(models.Model): ...@@ -11,7 +11,7 @@ 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, date_from): def get_points_history(self, partner_id, limit, offset, date_from):
""" Get partner points history with related shift registration if needed """ """ Get partner points history with related shift registration if needed """
cond = [ cond = [
['partner_id', '=', partner_id], ['partner_id', '=', partner_id],
...@@ -20,8 +20,28 @@ class CagetteMembersSpace(models.Model): ...@@ -20,8 +20,28 @@ class CagetteMembersSpace(models.Model):
] ]
f = ['create_date', 'create_uid', 'shift_id', 'name', 'point_qty'] f = ['create_date', 'create_uid', 'shift_id', 'name', 'point_qty']
# TODO get related data in service registration res = self.o_api.search_read('shift.counter.event', cond, f, limit=limit, offset=offset,
return self.o_api.search_read('shift.counter.event', cond, f, limit=limit, offset=0,
order='create_date DESC') 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
return res
\ No newline at end of file
...@@ -2,30 +2,74 @@ ...@@ -2,30 +2,74 @@
font-size: 1.8rem; font-size: 1.8rem;
} }
#incoming_services { #incoming_shifts {
height: 100%; height: 100%;
flex-direction: column; flex-direction: column;
display: none;
} }
.history_table { .loading-history, .loading-incoming-shifts {
width: 100%; margin: 2rem 0;
} }
.history_table_header { #history {
display: flex; display: flex;
border-bottom: 1px solid #333; flex-direction: column;
display: none;
} }
.history_table_line {
display: flex; table.dataTable tbody td {
text-overflow: ellipsis;
} }
.table_header_el {
flex: 1 0 20%; table.dataTable thead .sorting,
padding: 1rem 0.5rem; table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc {
background : none;
}
table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child:before,
table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child:before {
color: #0275d8;
background-color: white;
font-weight: bold;
border: none;
font-size: 2rem;
}
table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before,
table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before {
color: #d8534f;
background-color: white;
font-weight: bold; font-weight: bold;
border: none;
font-size: 2rem;;
}
.loading-more-history {
display: none;
}
.more_history {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
font-size: 2rem;
}
.more_history_button {
height: 50px;
width: 50px;
border-radius: 50%;
}
table.dataTable.display tbody tr.row_partner_ok {
background-color: #8feb8b;
}
table.dataTable.display tbody tr.row_partner_late {
background-color: #ffdf7d;
} }
.table_line_el { table.dataTable.display tbody tr.row_partner_absent {
flex: 1 0 20%; background-color: #ff847b;
padding: 1rem 0.5rem;
border-bottom: 1px solid #e7e9ed;
} }
\ No newline at end of file
var history_table = null;
const history_items_limit = 10;
/** /**
* Load the partner points history * Load the partner points history
*/ */
function load_partner_history() { function load_partner_history(offset = 0) {
return new Promise((resolve) => { return new Promise((resolve) => {
$.ajax({ $.ajax({
type: 'GET', type: 'GET',
...@@ -9,62 +13,155 @@ ...@@ -9,62 +13,155 @@
data: { data: {
partner_id: partner_data.partner_id, partner_id: partner_data.partner_id,
verif_token: partner_data.verif_token, verif_token: partner_data.verif_token,
limit: 10 limit: history_items_limit,
offset: offset
}, },
dataType:"json", dataType:"json",
traditional: true, traditional: true,
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
success: function(data) { success: function(data) {
partner_history = data.data; formatted_data = prepare_server_data(data.data);
resolve(); resolve(formatted_data);
}, },
error: function(data) { error: function(data) {
err = {msg: "erreur serveur lors de la récupération des services", ctx: 'load_partner_shifts'}; err = {msg: "erreur serveur lors de la récupération de l'historique", ctx: 'load_partner_history'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') { if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error; err.msg += ' : ' + data.responseJSON.error;
} }
report_JS_error(err, 'members_space.index'); report_JS_error(err, 'members_space.my_shifts');
closeModal(); closeModal();
// TODO Notify // TODO Notify
alert('Erreur lors de la récupération de vos services.'); alert('Erreur lors de la récupération de votre historique.');
} }
}); });
}); });
} }
function init_history() { /**
if (incoming_shifts.length === 0) { * Format history data to insert in the table
$("#history").empty().text("Aucun historique... pour l'instant !") *
} else { * @param {Array} data
for (history_item of partner_history) { * @returns formated data array
// Prepare history lines */
let history_line_template = $("#history_line_template"); function prepare_server_data(data) {
res = [];
// Date for (history_item of data) {
let datetime_item_start = new Date(history_item.create_date); // Date formating
let f_date_item_start = datetime_item_start.toLocaleDateString("fr-fr", date_options); let datetime_shift_start = new Date(history_item.create_date);
f_date_item_start = f_date_item_start.charAt(0).toUpperCase() + f_date_item_start.slice(1);
history_line_template.find(".table_line_date").text(f_date_item_start); 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_line_template.find(".table_line_desc").text(history_item.name); history_item.movement_date = f_date_shift_start + " - " + datetime_shift_start.toLocaleTimeString("fr-fr");
history_line_template.find(".table_line_pts").text(history_item.point_qty);
// 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_table_content").append(history_line_template.html()); 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];
// if Present && is_late -> Absent
} }
return data;
} }
/**
* Init the History section: display the history table
*/
function init_history() {
$(".loading-history").hide();
$("#history").show();
if (partner_history.length === 0) {
$("#history").empty().text("Aucun historique... pour l'instant !")
} else {
let viewportWidth = $(window).width();
history_table = $('#history_table').DataTable({
data: partner_history,
columns: [
{
data: "movement_date",
title: `Date`,
responsivePriority: 1,
},
{
data: "created_by",
title: "Créé par",
responsivePriority: 20000,
className: "desktop tablet-l"
},
{
data: "shift_name",
title: "Service",
},
{
data: "name",
title: "Détails",
responsivePriority: 3,
},
{
data: "point_qty",
title: (viewportWidth <= 768) ? "Mvmt de points" : "Mouvement de points",
responsivePriority: 2,
width: "10%",
className: (viewportWidth <= 768) ? "dt-body-center" : '',
},
],
iDisplayLength: -1,
ordering: false,
language: {url : '/static/js/datatables/french.json'},
dom: "t",
responsive: true,
createdRow: function(row) {
for (var i = 0; i < row.cells.length; i++) {
const cell = $(row.cells[i]);
if (cell.text() === "Présent") {
$(row).addClass('row_partner_ok');
} else if (cell.text() === "Retard") {
$(row).addClass('row_partner_late');
} else if (cell.text() === "Absence") {
$(row).addClass('row_partner_absent');
}
}
}
});
}
}
/**
* Init the Incoming shifts section: display them
*/
function init_incoming_shifts() { function init_incoming_shifts() {
$(".loading-incoming-shifts").hide();
$("#incoming_shifts").show();
if (incoming_shifts.length === 0) { if (incoming_shifts.length === 0) {
$("#incoming_services").text("Aucun service à venir...") $("#incoming_shifts").text("Aucun service à venir...")
} else { } else {
$("#incoming_services").empty(); $("#incoming_shifts").empty();
for (shift of incoming_shifts) { for (shift of incoming_shifts) {
let shift_line_template = prepare_shift_line_template(shift.date_begin); let shift_line_template = prepare_shift_line_template(shift.date_begin);
$("#incoming_services").append(shift_line_template.html()); $("#incoming_shifts").append(shift_line_template.html());
} }
} }
} }
...@@ -81,15 +178,33 @@ function init_my_shifts() { ...@@ -81,15 +178,33 @@ function init_my_shifts() {
init_history(); init_history();
} else { } else {
load_partner_history() load_partner_history()
.then(init_history); .then((data) => {
partner_history = data;
// Sort by date desc
partner_history.sort((a, b) => a.create_date - b.create_date);
init_history();
});
} }
/** $(".more_history_button").on("click", function() {
* if no incoming_services || no history { // Hide button & display loading
* if no incoming : load incoming $('.more_history_button').hide();
* if no history : load hitstory $('.loading-more-history').show();
* } else {
* do the stuff load_partner_history(partner_history.length)
* } .then((data) => {
*/ partner_history = partner_history.concat(data);
if (history_table) {
history_table.rows.add( data ).draw( false );
}
$('.loading-more-history').hide();
// Show "load more" if there is more to load
if (data.length === history_items_limit) {
$('.more_history_button').show();
}
});
});
} }
\ No newline at end of file
...@@ -145,8 +145,9 @@ def get_points_history(request): ...@@ -145,8 +145,9 @@ def get_points_history(request):
m = CagetteMembersSpace() m = CagetteMembersSpace()
limit = int(request.GET.get('limit')) limit = int(request.GET.get('limit'))
offset = int(request.GET.get('offset'))
date_from = getattr(settings, 'START_DATE_FOR_POINTS_HISTORY', '2018-01-01') date_from = getattr(settings, 'START_DATE_FOR_POINTS_HISTORY', '2018-01-01')
res["data"] = m.get_points_history(partner_id, limit, date_from) res["data"] = m.get_points_history(partner_id, limit, offset, date_from)
else: else:
return JsonResponse(res, status=403) return JsonResponse(res, status=403)
......
table.dataTable.dtr-inline.collapsed>tbody>tr>td.child,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty{cursor:default !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty:before{display:none !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control,table.dataTable.dtr-inline.collapsed>tbody>tr>th.dtr-control{position:relative;padding-left:30px;cursor:pointer}table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th.dtr-control:before{top:50%;left:5px;height:1em;width:1em;margin-top:-9px;display:block;position:absolute;color:white;border:.15em solid white;border-radius:1em;box-shadow:0 0 .2em #444;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:"Courier New",Courier,monospace;line-height:1em;content:"+";background-color:#31b131}table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td.dtr-control:before,table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th.dtr-control:before{content:"-";background-color:#d33333}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td.dtr-control,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th.dtr-control{padding-left:27px}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td.dtr-control:before,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th.dtr-control:before{left:4px;height:14px;width:14px;border-radius:14px;line-height:14px;text-indent:3px}table.dataTable.dtr-column>tbody>tr>td.dtr-control,table.dataTable.dtr-column>tbody>tr>th.dtr-control,table.dataTable.dtr-column>tbody>tr>td.control,table.dataTable.dtr-column>tbody>tr>th.control{position:relative;cursor:pointer}table.dataTable.dtr-column>tbody>tr>td.dtr-control:before,table.dataTable.dtr-column>tbody>tr>th.dtr-control:before,table.dataTable.dtr-column>tbody>tr>td.control:before,table.dataTable.dtr-column>tbody>tr>th.control:before{top:50%;left:50%;height:.8em;width:.8em;margin-top:-0.5em;margin-left:-0.5em;display:block;position:absolute;color:white;border:.15em solid white;border-radius:1em;box-shadow:0 0 .2em #444;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:"Courier New",Courier,monospace;line-height:1em;content:"+";background-color:#31b131}table.dataTable.dtr-column>tbody>tr.parent td.dtr-control:before,table.dataTable.dtr-column>tbody>tr.parent th.dtr-control:before,table.dataTable.dtr-column>tbody>tr.parent td.control:before,table.dataTable.dtr-column>tbody>tr.parent th.control:before{content:"-";background-color:#d33333}table.dataTable>tbody>tr.child{padding:.5em 1em}table.dataTable>tbody>tr.child:hover{background:transparent !important}table.dataTable>tbody>tr.child ul.dtr-details{display:inline-block;list-style-type:none;margin:0;padding:0}table.dataTable>tbody>tr.child ul.dtr-details>li{border-bottom:1px solid #efefef;padding:.5em 0}table.dataTable>tbody>tr.child ul.dtr-details>li:first-child{padding-top:0}table.dataTable>tbody>tr.child ul.dtr-details>li:last-child{border-bottom:none}table.dataTable>tbody>tr.child span.dtr-title{display:inline-block;min-width:75px;font-weight:bold}div.dtr-modal{position:fixed;box-sizing:border-box;top:0;left:0;height:100%;width:100%;z-index:100;padding:10em 1em}div.dtr-modal div.dtr-modal-display{position:absolute;top:0;left:0;bottom:0;right:0;width:50%;height:50%;overflow:auto;margin:auto;z-index:102;overflow:auto;background-color:#f5f5f7;border:1px solid black;border-radius:.5em;box-shadow:0 12px 30px rgba(0, 0, 0, 0.6)}div.dtr-modal div.dtr-modal-content{position:relative;padding:1em}div.dtr-modal div.dtr-modal-close{position:absolute;top:6px;right:6px;width:22px;height:22px;border:1px solid #eaeaea;background-color:#f9f9f9;text-align:center;border-radius:3px;cursor:pointer;z-index:12}div.dtr-modal div.dtr-modal-close:hover{background-color:#eaeaea}div.dtr-modal div.dtr-modal-background{position:fixed;top:0;left:0;right:0;bottom:0;z-index:101;background:rgba(0, 0, 0, 0.6)}@media screen and (max-width: 767px){div.dtr-modal div.dtr-modal-display{width:95%}}
...@@ -2,11 +2,16 @@ ...@@ -2,11 +2,16 @@
{% load static %} {% load static %}
{% block additionnal_css %} {% block additionnal_css %}
<link rel="stylesheet" href="{% static 'css/datatables/jquery.dataTables.css' %}">
<link rel="stylesheet" href="{% static 'css/datatables/responsive.dataTables.min.css' %}">
<link rel="stylesheet" href="{% static "css/members-space.css" %}?v="> <link rel="stylesheet" href="{% static "css/members-space.css" %}?v=">
<link rel="stylesheet" href="{% static "css/members-space-my-shifts.css" %}?v="> <link rel="stylesheet" href="{% static "css/members-space-my-shifts.css" %}?v=">
{% endblock %} {% endblock %}
{% block additionnal_scripts %}{% endblock %} {% block additionnal_scripts %}
<script type="text/javascript" src="{% static 'js/datatables/jquery.dataTables.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/datatables/dataTables.responsive.min.js' %}"></script>
{% endblock %}
{% block content %} {% block content %}
...@@ -23,16 +28,6 @@ ...@@ -23,16 +28,6 @@
<span class="shift_line_date"></span> - <span class="shift_line_time"></span> <span class="shift_line_date"></span> - <span class="shift_line_time"></span>
</div> </div>
</div> </div>
<div id="history_line_template">
<div class="history_table_line">
<div class="table_line_el table_line_date"></div>
<div class="table_line_el table_line_created_by"></div>
<div class="table_line_el table_line_service"></div>
<div class="table_line_el table_line_desc"></div>
<div class="table_line_el table_line_pts"></div>
</div>
</div>
</div> </div>
</div> </div>
......
...@@ -4,37 +4,37 @@ ...@@ -4,37 +4,37 @@
<h1>Mes Services</h1> <h1>Mes Services</h1>
</div> </div>
<div class="tiles_container"> <div class="tiles_container">
<div class="tile full_width_tile" id="incoming_services_area"> <div class="tile full_width_tile" id="incoming_shifts_area">
<div class="tile_title"> <div class="tile_title">
À venir À venir
</div> </div>
<div class="tile_content" id="incoming_services"></div> <div class="loading-incoming-shifts">
<i class="fas fa-spinner fa-spin fa-lg"></i>
</div>
<div class="tile_content" id="incoming_shifts"></div>
</div> </div>
<div class="tile full_width_tile" id="history_area"> <div class="tile full_width_tile" id="history_area">
<div class="tile_title"> <div class="tile_title">
Historique des mouvements de points Historique des mouvements de points
</div> </div>
<div class="loading-history">
<i class="fas fa-spinner fa-spin fa-lg"></i>
</div>
<div class="tile_content" id="history"> <div class="tile_content" id="history">
<div class="history_table"> <div class="history_table_area">
<div class="history_table_header"> <table id="history_table" class="display" cellspacing="0" width="100%"></table>
<div class="table_header_el table_header_date"> </div>
Date <div class="more_history">
</div> <div class="loading-more-history">
<div class="table_header_el table_header_created_by"> <i class="fas fa-spinner fa-spin fa-lg"></i>
Créé par
</div>
<div class="table_header_el table_header_service">
Service ??
</div>
<div class="table_header_el table_header_desc">
Description
</div>
<div class="table_header_el table_header_pts">
Mouvement de points
</div>
</div>
<div class="history_table_content">
</div> </div>
<button
type="button"
class="btn btn--primary more_history_button"
title="Charger plus d'éléments..."
>
<i class="fas fa-plus more_history_icon"></i>
</button>
</div> </div>
</div> </div>
</div> </div>
......
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