Commit 9e7f5b76 by Damien Moulard

add sync between workstations for grouped orders & localstorage cleaning

parent 8bbbfbb4
Pipeline #801 failed with stage
in 11 seconds
var order = { var order = {
'id' : null 'id' : null
}, },
table_orders = null,
callback_update = false, callback_update = false,
callback_report = false, callback_report = false,
selection_type = null, selection_type = null,
...@@ -25,7 +26,7 @@ function goto(id) { ...@@ -25,7 +26,7 @@ function goto(id) {
* i : index of group in 'saved_groups' array * i : index of group in 'saved_groups' array
*/ */
function group_goto(i) { function group_goto(i) {
// Check if all group's orders are saved in local storage // Make sure all group's orders are saved in local storage
for (j in saved_groups[i]) { for (j in saved_groups[i]) {
set_local_storage(saved_groups[i][j]); set_local_storage(saved_groups[i][j]);
} }
...@@ -48,6 +49,144 @@ function set_local_storage(order_data) { ...@@ -48,6 +49,144 @@ function set_local_storage(order_data) {
} }
} }
/*
* Remove from local storage orders that have a wrong status
* (-> order has been updated elsewhere)
*/
function clean_local_storage() {
var stored_order = null
// Loop through local storage
for (key of Object.keys(localStorage)) {
if (key.startsWith('order_')) {
stored_order = JSON.parse(localStorage.getItem(key));
// Loop through orders in table to find match
var i = 0;
var found = false;
while (i < table_orders.rows().data().length && !found) {
var uptodate_order = table_orders.rows(i).data()[0]
// If status in local storage is wrong
if (stored_order.id == uptodate_order.id
&& stored_order.reception_status != uptodate_order.reception_status) {
// Remove from local storage
localStorage.removeItem("order_" + uptodate_order.id);
// Evolution: remove order's group too
// Evolution: warn user (order modified elsewhere, local data has been deleted)
found = true;
}
i++;
}
if (!found) {
// Remove too if order isn't in server data
localStorage.removeItem("order_" + stored_order.id);
}
}
}
}
function create_groups_from_server_data() {
// Get array of stored grouped orders
var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
// Create if not exists
if (grouped_orders == null) {
grouped_orders = [];
} else {
// Remove from server data groups already in local storage
for (stored_group of grouped_orders) {
for (sg_order_item of stored_group) {
for (i in server_stored_groups) {
if (server_stored_groups[i].includes(sg_order_item)) {
server_stored_groups.splice(i, 1);
break;
}
}
}
}
}
// Add server groups to stored groups
grouped_orders = grouped_orders.concat(server_stored_groups)
localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
}
/*
* If there are groups in local storage, extract them from the table, set the groups actions.
*/
function extract_grouped_orders() {
var saved_grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
var groups_to_delete = [] // indexes
// if there are grouped orders
if (saved_grouped_orders != null) {
// for each group
for (group_index in saved_grouped_orders) {
var g = [];
// for each order in group
for (group_element_id of saved_grouped_orders[group_index]) {
// Look for order in datatable
for (var i = 0; i < table_orders.rows().data().length; i++) {
if (group_element_id == table_orders.rows(i).data()[0].id) {
var order = table_orders.rows(i).data()[0];
g.push(order);
// remove raw from table
table_orders.rows(i).remove()
.draw();
}
}
}
// No order found, delete group and skip the rest
if (g.length == 0) {
groups_to_delete.push(group_index)
continue;
}
// Display group
document.getElementById("container_groups").hidden = false;
var group_row = "<ul> <li> Commandes de ";
for (i in g) {
if (i == g.length-1) { // last element of list
group_row += "<b>" + g[i].partner + "</b> du " + g[i].date_order + " : ";
} else {
group_row += "<b>" + g[i].partner + "</b> du " + g[i].date_order + ", ";
}
}
if (g[0].reception_status == 'False') {
group_row += "<button class='btn--primary' onClick='group_goto("
+ saved_groups.length
+ ")'>Compter les produits</button>";
} else {
group_row += "<button class='btn--success' onClick='group_goto("
+ saved_groups.length
+ ")'>Mettre à jour les prix</button>";
}
group_row += "</li>";
$('#groups_items').append(group_row);
saved_groups.push(g);
}
}
if (groups_to_delete.length > 0) {
for (index of groups_to_delete) {
saved_grouped_orders.splice(index, 1)
}
localStorage.setItem('grouped_orders', JSON.stringify(saved_grouped_orders));
}
}
/* ACTIONS */ /* ACTIONS */
...@@ -63,7 +202,6 @@ function validatePrices() { ...@@ -63,7 +202,6 @@ function validatePrices() {
update_data.orders[order['id']] = { 'po' : [] }; update_data.orders[order['id']] = { 'po' : [] };
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({ $.ajax({
type: "PUT", type: "PUT",
url: "/reception/update_orders", url: "/reception/update_orders",
...@@ -119,43 +257,67 @@ function group_action() { ...@@ -119,43 +257,67 @@ function group_action() {
var pswd = prompt('Merci de demander à un.e salarié.e le mot de passe pour fusionner ces commandes.'); var pswd = prompt('Merci de demander à un.e salarié.e le mot de passe pour fusionner ces commandes.');
if (pswd == merge_orders_pswd) { // Minimum security level if (pswd == merge_orders_pswd) { // Minimum security level
var table_orders = $('#orders').DataTable();
// Use local storage to pass order data to next page // Use local storage to pass order data to next page
if (Modernizr.localstorage) { if (Modernizr.localstorage) {
var selected_data = table_orders.rows('.selected').data(); var selected_data = table_orders.rows('.selected').data();
var group_ids = []; var group_ids = [];
var min_id = 999999;
// Select orders id
for (var i = 0; i < selected_data.length; i++) { for (var i = 0; i < selected_data.length; i++) {
// Add order to group
group_ids.push(selected_data[i].id); group_ids.push(selected_data[i].id);
}
// Notify server that group is created
$.ajax({
type: "POST",
url: "/reception/save_order_group",
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
data: JSON.stringify(group_ids),
success: function(data) {
var min_id = 9999999;
for (var i = 0; i < selected_data.length; i++) {
// get smallest id
if (selected_data[i].id < min_id) {
min_id = selected_data[i].id;
}
// get smallest id // Add each order to local storage
if (selected_data[i].id < min_id) { set_local_storage(selected_data[i]);
min_id = selected_data[i].id; }
}
set_local_storage(selected_data[i]); // Get array of grouped orders
} var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
// Get array of grouped orders // Create if not exists
var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders')); if (grouped_orders == null) {
grouped_orders = [];
}
// Create if not exists // Add group
if (grouped_orders == null) { grouped_orders.push(group_ids);
grouped_orders = [];
}
// Add group (removed verif if group already exists, it shouldn't) // store grouped orders array
grouped_orders.push(group_ids); localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
// Go to products page of order with smallest id
// goto(min_id);
},
error: function(data) {
if (data != null && data.status == 409) {
alert("Un groupe a déjà été formé sur un autre poste "
+ "avec au moins l'une des commandes sélectionnées. Merci de rafraichir la page.")
}
}
});
// store grouped orders array
localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders)); } else {
alert("Le local storage n'est pas disponible. Merci de contacter un.e salarié.e !")
} }
// Go to products page of order with smallest id
goto(min_id);
} else if (pswd == null) { } else if (pswd == null) {
return; return;
} else { } else {
...@@ -165,12 +327,16 @@ function group_action() { ...@@ -165,12 +327,16 @@ function group_action() {
$(document).ready(function() { $(document).ready(function() {
openModal()
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
// Set date format for DataTable so date ordering can work // Set date format for DataTable so date ordering can work
$.fn.dataTable.moment('D/M/Y'); $.fn.dataTable.moment('D/M/Y');
var saved_grouped_orders = JSON.parse(localStorage.getItem('grouped_orders')); var saved_grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
var table_orders = $('#orders').DataTable({ table_orders = $('#orders').DataTable({
ajax: "get_list_orders", ajax: "get_list_orders",
columns:[ columns:[
{ {
...@@ -232,56 +398,10 @@ $(document).ready(function() { ...@@ -232,56 +398,10 @@ $(document).ready(function() {
iDisplayLength: 25, iDisplayLength: 25,
language: {url : '/static/js/datatables/french.json'}, language: {url : '/static/js/datatables/french.json'},
initComplete: function(settings, json) { // After data is loaded initComplete: function(settings, json) { // After data is loaded
// if there are grouped orders clean_local_storage()
if (saved_grouped_orders != null) { create_groups_from_server_data()
$('#groups_items').append("<ul>"); extract_grouped_orders()
closeModal()
// for each group
for (group of saved_grouped_orders) {
var g = [];
// for each order in group
for (group_element_id of group) {
// Look for order in datatable
for (var i = 0; i < table_orders.rows().data().length; i++) {
if (group_element_id == table_orders.rows(i).data()[0].id) {
var order = table_orders.rows(i).data()[0];
g.push(order);
// remove raw from table
table_orders.rows(i).remove()
.draw();
}
}
}
// Display group
document.getElementById("container_groups").hidden = false;
var group_row = "<ul> <li> Commandes de ";
for (i in g) {
if (i == g.length-1) { // last element of list
group_row += "<b>" + g[i].partner + "</b> du " + g[i].date_order + " : ";
} else {
group_row += "<b>" + g[i].partner + "</b> du " + g[i].date_order + ", ";
}
}
if (g[0].reception_status == 'False') {
group_row += "<button class='btn--primary' onClick='group_goto(" + saved_groups.length + ")'>Compter les produits</button>";
} else {
group_row += "<button class='btn--success' onClick='group_goto(" + saved_groups.length + ")'>Mettre à jour les prix</button>";
}
group_row += "</li>";
$('#groups_items').append(group_row);
saved_groups.push(g);
}
}
$('#groups_items').append("</ul>");
} }
}); });
......
...@@ -16,5 +16,6 @@ urlpatterns = [ ...@@ -16,5 +16,6 @@ urlpatterns = [
url(r'^reception_qtiesValidated', views.reception_qtiesValidated), url(r'^reception_qtiesValidated', views.reception_qtiesValidated),
url(r'^reception_pricesValidated', views.reception_pricesValidated), url(r'^reception_pricesValidated', views.reception_pricesValidated),
# url(r'^update_order_status/([0-9]+)$', views.tmp_update_order_status), # url(r'^update_order_status/([0-9]+)$', views.tmp_update_order_status),
url(r'^po_process_picking$', views.po_process_picking) url(r'^po_process_picking$', views.po_process_picking),
url(r'^save_order_group$', views.save_order_group)
] ]
...@@ -21,9 +21,18 @@ def as_text(value): ...@@ -21,9 +21,18 @@ def as_text(value):
def home(request): def home(request):
"""Page de selection de la commande suivant un fournisseurs""" """Page de selection de la commande suivant un fournisseurs"""
# Get grouped orders stored on the server
try:
with open('temp/grouped_order.json', 'r') as json_file:
saved_groups = json.load(json_file)
except Exception:
saved_groups = []
context = { context = {
'title': 'Reception', 'title': 'Reception',
'merge_orders_pswd': settings.RECEPTION_MERGE_ORDERS_PSWD 'merge_orders_pswd': settings.RECEPTION_MERGE_ORDERS_PSWD,
'server_stored_groups' : saved_groups
} }
template = loader.get_template('reception/index.html') template = loader.get_template('reception/index.html')
...@@ -117,6 +126,40 @@ def data_validation(request): ...@@ -117,6 +126,40 @@ def data_validation(request):
coop_logger.error("Orders data validation : %s", str(e)) coop_logger.error("Orders data validation : %s", str(e))
return JsonResponse({'error': str(e)}, status=500) return JsonResponse({'error': str(e)}, status=500)
def save_order_group(request):
"""
When an order group is created, save it to force group these orders later.
Raise an error if one of the orders is already in a group.
"""
order_ids = json.loads(request.body.decode())
try:
try:
# Check if any of the orders attempted to be grouped is already in a group
with open('temp/grouped_order.json', 'r') as json_file:
saved_groups = json.load(json_file)
for order_id in order_ids:
for group in saved_groups:
if order_id in group:
# Found in a group, stop
msg = 'One of the orders is already in a group'
return JsonResponse({'message': msg}, status=409)
except Exception:
saved_groups = []
# All good, save group
with open('temp/grouped_order.json', 'w+') as json_file:
saved_groups.append(order_ids)
json.dump(saved_groups, json_file)
msg = 'Group saved'
return JsonResponse({'message': msg})
except Exception as e:
print(str(e))
return JsonResponse({'message': str(e)}, status=500)
def update_orders(request): def update_orders(request):
"""Update orders lines: quantity and unit prices""" """Update orders lines: quantity and unit prices"""
...@@ -130,7 +173,10 @@ def update_orders(request): ...@@ -130,7 +173,10 @@ def update_orders(request):
print_labels = True print_labels = True
if hasattr(settings, 'RECEPTION_SHELF_LABEL_PRINT'): if hasattr(settings, 'RECEPTION_SHELF_LABEL_PRINT'):
print_labels = settings.RECEPTION_SHELF_LABEL_PRINT print_labels = settings.RECEPTION_SHELF_LABEL_PRINT
order_ids = []
for order_id, order in data['orders'].items(): for order_id, order in data['orders'].items():
order_ids.append(int(order_id))
answer_data[order_id] = {} answer_data[order_id] = {}
errors = [] errors = []
...@@ -181,11 +227,29 @@ def update_orders(request): ...@@ -181,11 +227,29 @@ def update_orders(request):
answer_data[order_id]['order_data'] = order answer_data[order_id]['order_data'] = order
answer_data[order_id]['errors'] = errors answer_data[order_id]['errors'] = errors
if len(errors) == 0: if len(errors) == 0:
m.update_order_status(order_id, data['update_type']) m.update_order_status(order_id, data['update_type'])
if data['update_type'] == 'br_valid': if data['update_type'] == 'br_valid':
answer_data[order_id]['finalyze_result'] = m.register_purchase_order_to_finalyze() answer_data[order_id]['finalyze_result'] = m.register_purchase_order_to_finalyze()
# Remove order's group
try:
with open('temp/grouped_order.json', 'r') as json_file:
saved_groups = json.load(json_file)
for oi in order_ids:
for i, group in enumerate(saved_groups):
if oi in group:
saved_groups.pop(i)
break
with open('temp/grouped_order.json', 'w') as json_file:
json.dump(saved_groups, json_file)
except Exception as e:
# no saved groups
print(str(e))
rep = JsonResponse(answer_data, safe=False) rep = JsonResponse(answer_data, safe=False)
return rep return rep
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
<script src="{% static "js/all_common.js" %}?v="></script> <script src="{% static "js/all_common.js" %}?v="></script>
<script type="text/javascript"> <script type="text/javascript">
var merge_orders_pswd = '{{merge_orders_pswd}}'; var merge_orders_pswd = '{{merge_orders_pswd}}';
var server_stored_groups = {{server_stored_groups}};
</script> </script>
<script src="{% static "js/common.js" %}?v="></script> <script src="{% static "js/common.js" %}?v="></script>
{% endblock %} {% endblock %}
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