Commit 9f56118c by Damien Moulard

[WIP] replace localstorage by couchdb in reception

parent 520b3262
...@@ -19,7 +19,8 @@ COUCHDB = { ...@@ -19,7 +19,8 @@ COUCHDB = {
'member': 'coops', 'member': 'coops',
'inventory': 'inventory', 'inventory': 'inventory',
'envelops': 'envelop', 'envelops': 'envelop',
'shop': 'shopping_carts' 'shop': 'shopping_carts',
'reception': 'reception_test'
} }
} }
......
...@@ -11,6 +11,10 @@ input[type="number"] { ...@@ -11,6 +11,10 @@ input[type="number"] {
} }
/* INDEX */ /* INDEX */
.group_line {
margin-bottom: 5px;
}
#orders tbody tr { #orders tbody tr {
cursor: pointer; cursor: pointer;
} }
......
var order = { var orders = [],
order = {
'id' : null 'id' : null
}, },
table_orders = null, table_orders = null,
callback_update = false, callback_update = false,
callback_report = false, callback_report = false,
selection_type = null, selection_type = null,
saved_groups = []; order_groups = {
_id: null,
groups: []
},
dbc = null,
sync = null;
/* UTILS */ /* UTILS */
// Wait for both ajax callbacks for reloading to avoid a js error /**
// -> reloading when ajax call not answered causes a popup to appear, can be confusing * Wait for both ajax callbacks for reloading to avoid a js error
* -> reloading when ajax call not answered causes a popup to appear, which can be confusing
*/
function reload() { function reload() {
if (callback_update && callback_report) if (callback_update && callback_report)
document.location.reload(); document.location.reload();
...@@ -20,178 +29,74 @@ function goto(id) { ...@@ -20,178 +29,74 @@ function goto(id) {
document.location.href = "produits/" + id; document.location.href = "produits/" + id;
} }
/* /**
* Go to Products page for an existing group * Go to Products page for an existing group
* params : * @param {int} group_index index of group in groups array
* i : index of group in 'saved_groups' array
*/
function group_goto(i) {
// Make sure all group's orders are saved in local storage
for (j in saved_groups[i]) {
set_local_storage(saved_groups[i][j]);
}
// go to one of group's order Products page
goto(saved_groups[i][0].id);
}
/*
* Set local storage for given order
*/
function set_local_storage(order_data) {
if (Modernizr.localstorage) {
var stored_order = JSON.parse(localStorage.getItem('order_' + order_data.id));
// Set local storage if key doesn't exist
if (stored_order == null) {
localStorage.setItem("order_" + order_data.id, JSON.stringify(order_data));
}
}
}
/*
* Remove from local storage orders that have a wrong status
* (-> order has been updated elsewhere)
*/ */
function clean_local_storage() { function group_goto(group_index) {
var stored_order = null; console.log(order_groups.groups);
// Make sure a couchdb document exists for all group's orders
// Loop through local storage for (let i in order_groups.groups[group_index]) {
for (key of Object.keys(localStorage)) { let order_data = null;
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: warn user (order modified elsewhere, local data has been deleted) // Find order data
found = true; for (let order of orders) {
if (order.id == order_groups.groups[group_index][i]) {
order_data = order
} }
i++;
} }
if (!found) { create_order_doc(order_data);
// 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 // go to first order
grouped_orders = grouped_orders.concat(server_stored_groups); goto(order_groups.groups[group_index][0]);
localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
} }
/* /**
* If there are groups in local storage, extract them from the table, set the groups actions. * Create a couchdb document for an order if it doesn't exist
* @param {Object} order_data
* @param {Boolean} goto if true, go to order page
*/ */
function extract_grouped_orders() { function create_order_doc(order_data, go_to_order = false) {
var saved_grouped_orders = JSON.parse(localStorage.getItem('grouped_orders')); const order_doc_id = 'order_' + order_data.id;
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 dbc.get(order_doc_id).then(() => {
table_orders.rows(i).remove() if (go_to_order === true) {
.draw(); goto(order_data.id)
}
}
} }
})
.catch(function (err) {
// Create if doesn't exist
if (err.status === 404) {
let order_doc = { ... order_data };
order_doc._id = order_doc_id;
// No order found, delete group and skip the rest dbc.put(order_doc, (err) => {
if (g.length == 0) { if (!err) {
groups_to_delete.push(group_index); if (go_to_order === true) {
continue; goto(order_data.id)
} }
// 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 { } else {
group_row += "<button class='btn--success' onClick='group_goto(" error = {
+ saved_groups.length msg: 'Erreur dans la creation de la commande dans couchdb',
+ ")'>Mettre à jour les prix</button>"; ctx: 'validatePrices',
} details: err
};
group_row += "</li>"; report_JS_error(error, 'reception');
$('#groups_items').append(group_row); console.log(error);
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 */
// Validate all prices of an order /**
function validatePrices() { * Validate all prices of an order
*/
function validatePrices() {
// Loading on // Loading on
openModal(); openModal();
...@@ -210,9 +115,19 @@ function validatePrices() { ...@@ -210,9 +115,19 @@ function validatePrices() {
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
data: JSON.stringify(update_data), data: JSON.stringify(update_data),
success: function() { success: function() {
localStorage.removeItem("order_" + order["id"]); // Remove order
dbc.get(`order_${order['id']}`).then((doc) => {
return dbc.remove(doc);
})
.then(() => {
callback_update = true; callback_update = true;
reload(); reload();
})
.catch((err) => {
// No doc found
console.log(err);
reload();
});
}, },
error: function() { error: function() {
closeModal(); closeModal();
...@@ -251,91 +166,111 @@ function validatePrices() { ...@@ -251,91 +166,111 @@ function validatePrices() {
}); });
} }
/**
// Action fired when orders are grouped (new group) * Action fired when orders are grouped (new group)
* @returns
*/
function group_action() { function group_action() {
var pswd = prompt('Merci de demander à un.e salarié.e le mot de passe pour fusionner ces commandes.'); let 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 // Minimum security level
// Use local storage to pass order data to next page if (pswd == merge_orders_pswd) {
if (Modernizr.localstorage) { let selected_data = table_orders.rows('.selected').data();
var selected_data = table_orders.rows('.selected').data(); let group_ids = [];
var group_ids = [];
// Select orders id for (let i = 0; i < selected_data.length; i++) {
for (var i = 0; i < selected_data.length; i++) { // Select group orders id
group_ids.push(selected_data[i].id); group_ids.push(selected_data[i].id);
// Create doc for each group order if doesn't exist
create_order_doc(selected_data[i]);
} }
// Notify server that group is created group_ids.sort();
$.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() {
var min_id = 9999999;
for (var i = 0; i < selected_data.length; i++) { // Save group
// get smallest id order_groups.groups.push(group_ids);
if (selected_data[i].id < min_id) { dbc.put(order_groups, (err) => {
min_id = selected_data[i].id; if (!err) {
goto(group_ids[0]);
} else {
alert("Une erreur est survenue lors de la création du groupe. Veuillez ré-essayer plus tard svp.")
console.log(err);
} }
});
// Add each order to local storage } else if (pswd == null) {
set_local_storage(selected_data[i]); return;
} else {
alert('Mauvais mot de passe !');
} }
}
// Get array of grouped orders /* DISPLAY */
var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
// Create if not exists
if (grouped_orders == null) {
grouped_orders = [];
}
// Add group /**
grouped_orders.push(group_ids); * Display the order groups.
* Remove the grouped orders from the order table to prevent grouping in multiple groups.
*/
function display_grouped_orders() {
if (table_orders !== null) {
let groups_display_content = "<ul>";
for (let group_index in order_groups.groups) {
let group_orders = [];
// Extract every order in the groups from the orders table
for (group_order_id of order_groups.groups[group_index]) {
// Look for order in datatable"
for (let i = 0; i < table_orders.rows().data().length; i++) {
if (group_order_id == table_orders.rows(i).data()[0].id) {
var order = table_orders.rows(i).data()[0];
// store grouped orders array group_orders.push(order);
localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
// Go to products page of order with smallest id // remove table row
goto(min_id); table_orders.rows(i).remove()
}, .draw();
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.");
} }
} }
});
// Display group
document.getElementById("container_groups").hidden = false;
let group_row = `<li class="group_line"> Commandes de `;
for (let i in group_orders) {
if (i == group_orders.length-1) { // last element of list
group_row += "<b>" + group_orders[i].partner + "</b> du " + group_orders[i].date_order + " : ";
} else { } else {
alert("Le local storage n'est pas disponible. Merci de contacter un.e salarié.e !"); group_row += "<b>" + group_orders[i].partner + "</b> du " + group_orders[i].date_order + ", ";
}
} }
} else if (pswd == null) { if (group_orders[0].reception_status == 'False') {
return; group_row += "<button class='btn--primary' onClick='group_goto("
+ group_index
+ ")'>Compter les produits</button>";
} else { } else {
alert('Mauvais mot de passe !'); group_row += "<button class='btn--success' onClick='group_goto("
+ group_index
+ ")'>Mettre à jour les prix</button>";
} }
}
$(document).ready(function() {
openModal();
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } }); group_row += "</li>";
groups_display_content += group_row;
// Set date format for DataTable so date ordering can work }
$.fn.dataTable.moment('D/M/Y'); $('#container_groups').show();
$('#groups_items').append(groups_display_content);
}
}
/**
* Display the main orders table
*/
function display_orders_table() {
table_orders = $('#orders').DataTable({ table_orders = $('#orders').DataTable({
ajax: "get_list_orders", data: orders,
columns:[ columns:[
{ {
data:"id", data:"id",
...@@ -417,13 +352,7 @@ $(document).ready(function() { ...@@ -417,13 +352,7 @@ $(document).ready(function() {
] ]
], ],
iDisplayLength: 25, iDisplayLength: 25,
language: {url : '/static/js/datatables/french.json'}, language: {url : '/static/js/datatables/french.json'}
initComplete: function() { // After data is loaded
clean_local_storage();
create_groups_from_server_data();
extract_grouped_orders();
closeModal();
}
}); });
// Set rows event on click // Set rows event on click
...@@ -482,12 +411,10 @@ $(document).ready(function() { ...@@ -482,12 +411,10 @@ $(document).ready(function() {
document.getElementById("group_action").hidden = true; document.getElementById("group_action").hidden = true;
} }
} else if (this.cellIndex == 4) { // Click on last cell button -> go to products page } else if (this.cellIndex == 4) { // Click on last cell button -> go to products page
// Extra security if order with a different status gets lost in here // Click action only for specific reception status
if (row_data.reception_status == "qty_valid" || row_data.reception_status == "False") { if (row_data.reception_status == "qty_valid" || row_data.reception_status == "False") {
// Use local storage to pass order data to next page // Use couchdb to pass order data to next page
set_local_storage(row_data); create_order_doc(row_data, true);
goto(row_data.id);
} }
} else if (this.cellIndex == 3 && row_data.reception_status == "qty_valid") { } else if (this.cellIndex == 3 && row_data.reception_status == "qty_valid") {
// If 'update prices' step, click on before-last cell -> validate all prices // If 'update prices' step, click on before-last cell -> validate all prices
...@@ -502,6 +429,68 @@ $(document).ready(function() { ...@@ -502,6 +429,68 @@ $(document).ready(function() {
.search(jQuery.fn.DataTable.ext.type.search.string(this.value)) .search(jQuery.fn.DataTable.ext.type.search.string(this.value))
.draw(); .draw();
}); });
}
$(document).ready(function() {
openModal();
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
// Init couchdb
dbc = new PouchDB(couchdb_dbname),
sync = PouchDB.sync(couchdb_dbname, couchdb_server, {
live: true,
retry: true,
auto_compaction: false
});
// TODO sync on change : get data, update data & dom
// TODO on button click to access order: verif fingerprint & timestamp
// Get or create order groups doc
dbc.get("grouped_orders").then((doc) => {
order_groups = doc;
})
.catch(function (err) {
console.log(err);
if (err.status === 404) {
// Create if doesn't exist
dbc.put(order_groups, (err, result) => {
if (!err) {
order_groups._rev = result.rev;
} else {
console.log("document pour les groupes déjà créé");
console.log(err);
}
});
}
});
// Set date format for DataTable so date ordering can work
$.fn.dataTable.moment('D/M/Y');
// Get orders
$.ajax({
type: 'GET',
url: "/reception/get_list_orders",
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
orders = data.data;
display_orders_table();
display_grouped_orders();
closeModal();
},
error: function(data) {
err = {msg: "erreur serveur lors de la récupération des commandes", ctx: 'get_list_orders'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur lors de la récupération des commandes, rechargez la page plus tard.');
}
});
}); });
...@@ -13,9 +13,9 @@ Sémantiquement, ici : ...@@ -13,9 +13,9 @@ Sémantiquement, ici :
* Associative array of current order(s) * Associative array of current order(s)
* If more than 1 element: group of orders * If more than 1 element: group of orders
* If 1 element: single order * If 1 element: single order
* -> check for Object.keys(orders).length to know if we're in a group case
*/ */
var orders = {}, var orders = {},
is_group = false,
group_ids = []; group_ids = [];
var reception_status = null, var reception_status = null,
...@@ -32,6 +32,8 @@ var reception_status = null, ...@@ -32,6 +32,8 @@ var reception_status = null,
updateType = "", // step 1: qty_valid; step2: br_valid updateType = "", // step 1: qty_valid; step2: br_valid
barcodes = null; // Barcodes stored locally barcodes = null; // Barcodes stored locally
var dbc = null,
sync = null;
/* UTILS */ /* UTILS */
...@@ -112,12 +114,29 @@ function select_product_from_bc(barcode) { ...@@ -112,12 +114,29 @@ function select_product_from_bc(barcode) {
return 0; return 0;
} }
/**
* Update couchdb order
* @param {int} order_id
*/
function update_distant_order(order_id) {
// TODO insert fingerprint & timestamp
console.log(order_id);
dbc.put(orders[order_id], (err, result) => {
if (!err && result !== undefined) {
orders[order_id]._rev = result.rev;
} else {
alert("Erreur lors de la sauvegarde de la commande... Si l'erreur persiste contactez un administrateur svp.");
console.log(err);
}
});
}
/* INIT */ /* INIT */
// Get order(s) data from server // Get order(s) data from server
function fetch_data() { function fetch_data() {
try { try {
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '../get_orders_lines', url: '../get_orders_lines',
...@@ -198,7 +217,7 @@ function initLists() { ...@@ -198,7 +217,7 @@ function initLists() {
document.getElementById("valid_all_uprices").disabled = false; document.getElementById("valid_all_uprices").disabled = false;
} }
// Set lists with local storage content // Set processed and to_process lists based on saved data
for (var i = 0; i < updatedProducts.length; i++) { for (var i = 0; i < updatedProducts.length; i++) {
let product = updatedProducts[i]; let product = updatedProducts[i];
...@@ -384,17 +403,18 @@ function initLists() { ...@@ -384,17 +403,18 @@ function initLists() {
$('#table_to_process tbody').on('click', 'a#toProcess_line_valid', function () { $('#table_to_process tbody').on('click', 'a#toProcess_line_valid', function () {
if (is_time_to('reception_direct_valid_order_line', 500)) { if (is_time_to('reception_direct_valid_order_line', 500)) {
try { try {
var row = table_to_process.row($(this).parents('tr')); let row = table_to_process.row($(this).parents('tr'));
var data = row.data(); let data = row.data();
add_to_processed(data); add_to_processed(data);
remove_from_toProcess(row, data); remove_from_toProcess(row, data);
// Update local storage of product's order // Update product's order
if (!orders[data.id_po]['valid_products']) if (!orders[data.id_po]['valid_products']) {
orders[data.id_po]['valid_products'] = []; orders[data.id_po]['valid_products'] = [];
}
orders[data.id_po]['valid_products'].push(data['id']); orders[data.id_po]['valid_products'].push(data['id']);
localStorage.setItem("order_" + data.id_po, JSON.stringify(orders[data.id_po])); update_distant_order(data.id_po)
// Reset search // Reset search
document.getElementById('search_input').value = ''; document.getElementById('search_input').value = '';
...@@ -719,8 +739,8 @@ function set_supplier_shortage(row, product, from_processed = false) { ...@@ -719,8 +739,8 @@ function set_supplier_shortage(row, product, from_processed = false) {
} }
add_to_processed(product); add_to_processed(product);
// Update local storage of product's order // Update product's order
localStorage.setItem("order_" + product.id_po, JSON.stringify(orders[product.id_po])); update_distant_order(product.id_po);
// Reset search // Reset search
document.getElementById('search_input').value = ''; document.getElementById('search_input').value = '';
...@@ -856,10 +876,10 @@ function editProductInfo (productToEdit, value = null) { ...@@ -856,10 +876,10 @@ function editProductInfo (productToEdit, value = null) {
if (firstUpdate) { if (firstUpdate) {
updatedProducts.push(productToEdit); updatedProducts.push(productToEdit);
/* Update local storage of product order */
// Create 'updated_products' list in order if not exists // Create 'updated_products' list in order if not exists
if (!orders[productToEdit.id_po]['updated_products']) if (!orders[productToEdit.id_po]['updated_products']) {
orders[productToEdit.id_po]['updated_products'] = []; orders[productToEdit.id_po]['updated_products'] = [];
}
// Add product to order's updated products if first update // Add product to order's updated products if first update
orders[productToEdit.id_po]['updated_products'].push(productToEdit); orders[productToEdit.id_po]['updated_products'].push(productToEdit);
...@@ -881,8 +901,8 @@ function editProductInfo (productToEdit, value = null) { ...@@ -881,8 +901,8 @@ function editProductInfo (productToEdit, value = null) {
} }
} }
// Update local storage of product order // Update product order
localStorage.setItem("order_" + productToEdit.id_po, JSON.stringify(orders[productToEdit.id_po])); update_distant_order(productToEdit.id_po);
add_to_processed(productToEdit); add_to_processed(productToEdit);
} catch (e) { } catch (e) {
...@@ -918,8 +938,6 @@ function setAllQties() { ...@@ -918,8 +938,6 @@ function setAllQties() {
.draw(); .draw();
} }
/* ACTIONS */ /* ACTIONS */
// Get labels to print for current orders from server // Get labels to print for current orders from server
...@@ -1010,7 +1028,6 @@ function pre_send(type) { ...@@ -1010,7 +1028,6 @@ function pre_send(type) {
function data_validation() { function data_validation() {
openModal(); openModal();
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: "../data_validation", url: "../data_validation",
...@@ -1065,7 +1082,8 @@ function send() { ...@@ -1065,7 +1082,8 @@ function send() {
// for each updated product, add it to its order list // for each updated product, add it to its order list
for (i in updatedProducts) { for (i in updatedProducts) {
// if product was in different orders
/* ---> The following part concerns products found in different orders */
if ('other_orders_data' in updatedProducts[i]) { if ('other_orders_data' in updatedProducts[i]) {
// for each other order of product // for each other order of product
for (other_order_data of updatedProducts[i].other_orders_data) { for (other_order_data of updatedProducts[i].other_orders_data) {
...@@ -1122,13 +1140,13 @@ function send() { ...@@ -1122,13 +1140,13 @@ function send() {
orders[other_order_data.id_po]['updated_products'].push(product_copy); orders[other_order_data.id_po]['updated_products'].push(product_copy);
} }
} }
/* <--- */
// Add product to order's prod list // Add product to order's prod list
prod_order_id = updatedProducts[i].id_po; prod_order_id = updatedProducts[i].id_po;
update_data.orders[prod_order_id]['po'].push(updatedProducts[i]); update_data.orders[prod_order_id]['po'].push(updatedProducts[i]);
} }
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({ $.ajax({
type: "PUT", type: "PUT",
url: "../update_orders", url: "../update_orders",
...@@ -1171,9 +1189,9 @@ function send() { ...@@ -1171,9 +1189,9 @@ function send() {
} }
// Set order(s) name in popup DOM // Set order(s) name in popup DOM
if (Object.keys(orders).length == 1) { // Single order if (Object.keys(orders).length === 1) { // Single order
document.getElementById("order_ref").innerHTML = orders[Object.keys(orders)[0]].name; document.getElementById("order_ref").innerHTML = orders[Object.keys(orders)[0]].name;
} else { } else { // group
document.getElementById("success_order_name_container").hidden = true; document.getElementById("success_order_name_container").hidden = true;
document.getElementById("success_orders_name_container").hidden = false; document.getElementById("success_orders_name_container").hidden = false;
...@@ -1198,9 +1216,7 @@ function send() { ...@@ -1198,9 +1216,7 @@ function send() {
openModal( openModal(
$('#modal_qtiesValidated').html(), $('#modal_qtiesValidated').html(),
function() { back,
document.location.href = "/reception";
},
'Retour à la liste des commandes', 'Retour à la liste des commandes',
true, true,
false false
...@@ -1213,9 +1229,7 @@ function send() { ...@@ -1213,9 +1229,7 @@ function send() {
openModal( openModal(
$('#templates #modal_pricesValidated').html(), $('#templates #modal_pricesValidated').html(),
function() { back,
document.location.href = "/reception";
},
'Retour à la liste des commandes', 'Retour à la liste des commandes',
true, true,
false false
...@@ -1223,38 +1237,39 @@ function send() { ...@@ -1223,38 +1237,39 @@ function send() {
} }
// Go back to to_process list if modal closed // Go back to to_process list if modal closed
$('#modal_closebtn_top').on('click', function () { $('#modal_closebtn_top').on('click', back);
document.location.href = "/reception"; $('#modal_closebtn_bottom').on('click', back);
});
$('#modal_closebtn_bottom').on('click', function () { // TODO data clearing.
document.location.href = "/reception"; // according to process state:
}); // - step1 : clear only products related datar :valid_products, updated_products & save data from step 1
// - step2 : remove orders in couchdb & groups
// -> server side ?
// Clear local storage before leaving // Clear local storage before leaving
for (order_id in orders) { // for (order_id in orders) {
localStorage.removeItem("order_" + order_id); // localStorage.removeItem("order_" + order_id);
} // }
// Delete group(s) // Delete group(s)
if (is_group) { // if (Object.keys(orders).length > 1) {
var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders')); // var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
// Remove all groups containing these orders // // Remove all groups containing these orders
for (order_id in orders) { // for (order_id in orders) {
search: // search:
for (var h = 0; i < grouped_orders.length; h++) { // for (var h = 0; i < grouped_orders.length; h++) {
for (var j = 0; j < grouped_orders[h].length; j++) { // for (var j = 0; j < grouped_orders[h].length; j++) {
if (grouped_orders[h][j] == order_id) { // if (grouped_orders[h][j] == order_id) {
grouped_orders.splice(h); // grouped_orders.splice(h);
break search; // break search;
} // }
} // }
} // }
} // }
localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders)); // localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
} // }
} catch (ee) { } catch (ee) {
err = {msg: ee.name + ' : ' + ee.message, ctx: 'callback update_orders'}; err = {msg: ee.name + ' : ' + ee.message, ctx: 'callback update_orders'};
...@@ -1268,6 +1283,8 @@ function send() { ...@@ -1268,6 +1283,8 @@ function send() {
} }
}); });
// TODO : for step 1, instead of saving a temp report, save data in couchdb ?
// Send changes between items to process and processed items // Send changes between items to process and processed items
var updates = { var updates = {
'group_amount_total' : 0, 'group_amount_total' : 0,
...@@ -1331,8 +1348,7 @@ function confirm_all_left_is_good() { ...@@ -1331,8 +1348,7 @@ function confirm_all_left_is_good() {
.draw(); .draw();
closeModal(); closeModal();
} }
/* TODO: upgrade modal
-> disable background scrolling*/
function openFAQ() { function openFAQ() {
openModal($("div#modal_FAQ_content").html(), function() {}, 'Compris !', true, false); openModal($("div#modal_FAQ_content").html(), function() {}, 'Compris !', true, false);
} }
...@@ -1359,10 +1375,10 @@ function openErrorReport() { ...@@ -1359,10 +1375,10 @@ function openErrorReport() {
function saveErrorReport() { function saveErrorReport() {
user_comments = document.getElementById("error_report").value; user_comments = document.getElementById("error_report").value;
// Save comment in local storage, in all orders // Save comments in all orders
for (order_id of Object.keys(orders)) { for (order_id of Object.keys(orders)) {
orders[order_id].user_comments = user_comments; orders[order_id].user_comments = user_comments;
localStorage.setItem("order_" + order_id, JSON.stringify(orders[order_id])); update_distant_order(order_id)
} }
document.getElementById("search_input").focus(); document.getElementById("search_input").focus();
...@@ -1374,139 +1390,21 @@ var get_barcodes = async function() { ...@@ -1374,139 +1390,21 @@ var get_barcodes = async function() {
}; };
$(document).ready(function() {
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
// Load barcodes
get_barcodes();
// Get Route parameter
var pathArray = window.location.pathname.split('/');
var id = pathArray[pathArray.length-1];
// Disable alert errors from datatables
$.fn.dataTable.ext.errMode = 'none';
// Listen for errors in tables with custom behavior
$('#table_to_process').on('error.dt', function (e, settings, techNote, message) {
var err_msg = message;
try {
var split = message.split(" ");
var row_number = null;
for (var i = 0; i < split.length; i++) {
if (split[i] == "row")
row_number = split[i+1];
}
row_number = row_number.replace(',', '');
var row_data = $('#table_to_process').DataTable()
.row(row_number)
.data();
err_msg += " - Order id: " + row_data.id_po;
err_msg += " - Product: " + row_data.product_id[1];
} catch (e) {
console.log(e);
}
err = {msg: err_msg, ctx: 'datatable: table to_process'};
console.error(err);
report_JS_error(err, 'reception');
});
$('#table_processed').on('error.dt', function (e, settings, techNote, message) {
var err_msg = message;
try {
var split = message.split(" ");
var row_number = null;
for (var i = 0; i < split.length; i++) {
if (split[i] == "row")
row_number = split[i+1];
}
row_number = row_number.replace(',', '');
var row_data = $('#table_processed').DataTable()
.row(row_number)
.data();
err_msg += " - Order id: " + row_data.id_po;
err_msg += " - Product: " + row_data.product_id[1];
} catch (e) {
console.log(e);
}
err = {msg: err_msg, ctx: 'datatable: table processed'};
console.error(err);
report_JS_error(err, 'reception');
});
try {
// Get order info from local storage (it should be there if process followed)
if (Modernizr.localstorage) {
// Look for current order in grouped orders in local storage
var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
if (grouped_orders != null) {
for (group of grouped_orders) {
for (group_element_id of group) {
if (group_element_id == id) {
// We're in a group!
is_group = true;
group_ids = group;
}
}
}
}
// if not in group, add current order to group
if (group_ids.length == 0) {
group_ids.push(id);
}
var stored_order = null;
var display_partners_name = [];
// for each order in order group
for (order_id of group_ids) {
// Get order data from local storage
stored_order = JSON.parse(localStorage.getItem('order_' + order_id));
// Add order to order list
if (stored_order != null) {
orders[order_id] = stored_order;
//Add each order's already updated and validated products to common list
if (stored_order["updated_products"])
updatedProducts = updatedProducts.concat(stored_order["updated_products"]);
if (stored_order["valid_products"])
validProducts = validProducts.concat(stored_order["valid_products"]);
// Prepare data to display in 'partner name' area
display_partners_name.push(stored_order['partner'] + ' du ' + stored_order['date_order']);
}
}
// Set current reception status: take first order's
reception_status = orders[Object.keys(orders)[0]].reception_status;
// Load user comments from local storage, get it from first order
user_comments = orders[Object.keys(orders)[0]].user_comments || "";
}
// Fetch orders data
fetch_data();
if (is_group) { /**
* Init the page according to order(s) data (texts, colors, events...)
*
* @param {Array} partners_display_data
*/
function init_dom(partners_display_data) {
// Grouped orders
if (Object.keys(orders).length > 1) {
$('#partner_name').html(Object.keys(orders).length + " commandes"); $('#partner_name').html(Object.keys(orders).length + " commandes");
// Display order data for each order // Display order data for each order
var msg = ""; var msg = "";
for (display_partner_data of display_partners_name) { for (display_partner_data of partners_display_data) {
if (msg != "") { if (msg != "") {
msg += ", "; msg += ", ";
} }
...@@ -1559,14 +1457,6 @@ $(document).ready(function() { ...@@ -1559,14 +1457,6 @@ $(document).ready(function() {
$("#modal_qtiesValidated").load("/reception/reception_qtiesValidated"); $("#modal_qtiesValidated").load("/reception/reception_qtiesValidated");
} else { } else {
// Extra security, shouldn't get in here // Extra security, shouldn't get in here
document.location.href = "/reception";
}
} catch (e) {
err = {msg: e.name + ' : ' + e.message, ctx: 'page init'};
console.error(err);
report_JS_error(err, 'reception');
alert("Erreur au chargement de cette commande. Vous allez être redirigé.");
back(); back();
} }
...@@ -1589,16 +1479,6 @@ $(document).ready(function() { ...@@ -1589,16 +1479,6 @@ $(document).ready(function() {
$('#edition_input').on('focus', function () { $('#edition_input').on('focus', function () {
$(this).on('wheel.disableScroll', function (e) { $(this).on('wheel.disableScroll', function (e) {
e.preventDefault(); e.preventDefault();
/*
Option to possibly enable page scrolling when mouse over the input, but :
- deltaY is not in pixels in Firefox
- movement not fluid on other browsers
var scrollTo = (e.originalEvent.deltaY) + $(document.documentElement).scrollTop();
$(document.documentElement).scrollTop(scrollTo);
-> other option to allow scrolling would be to loose input focus with blur(): not acceptable
*/
}); });
}) })
.on('blur', function () { .on('blur', function () {
...@@ -1687,4 +1567,166 @@ $(document).ready(function() { ...@@ -1687,4 +1567,166 @@ $(document).ready(function() {
.draw(); .draw();
select_product_from_bc(barcode); select_product_from_bc(barcode);
}); });
}
$(document).ready(function() {
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
// Load barcodes
get_barcodes();
// Get Route parameter
let pathArray = window.location.pathname.split('/');
let id = pathArray[pathArray.length-1];
// Init couchdb
dbc = new PouchDB(couchdb_dbname),
sync = PouchDB.sync(couchdb_dbname, couchdb_server, {
live: true,
retry: true,
auto_compaction: false
});
// TODO on sync change : redirect (cf order_helper)
// TODO insert fingerprint & timestamp on access to order
// Disable alert errors from datatables
$.fn.dataTable.ext.errMode = 'none';
// Listen for errors in tables with custom behavior
$('#table_to_process').on('error.dt', function (e, settings, techNote, message) {
var err_msg = message;
try {
var split = message.split(" ");
var row_number = null;
for (var i = 0; i < split.length; i++) {
if (split[i] == "row")
row_number = split[i+1];
}
row_number = row_number.replace(',', '');
var row_data = $('#table_to_process').DataTable()
.row(row_number)
.data();
err_msg += " - Order id: " + row_data.id_po;
err_msg += " - Product: " + row_data.product_id[1];
} catch (e) {
console.log(e);
}
err = {msg: err_msg, ctx: 'datatable: table to_process'};
console.error(err);
report_JS_error(err, 'reception');
});
$('#table_processed').on('error.dt', function (e, settings, techNote, message) {
var err_msg = message;
try {
var split = message.split(" ");
var row_number = null;
for (var i = 0; i < split.length; i++) {
if (split[i] == "row")
row_number = split[i+1];
}
row_number = row_number.replace(',', '');
var row_data = $('#table_processed').DataTable()
.row(row_number)
.data();
err_msg += " - Order id: " + row_data.id_po;
err_msg += " - Product: " + row_data.product_id[1];
} catch (e) {
console.log(e);
}
err = {msg: err_msg, ctx: 'datatable: table processed'};
console.error(err);
report_JS_error(err, 'reception');
});
/* Get order info from couchdb */
// Get order groups
let order_groups = []
dbc.get("grouped_orders").then((doc) => {
order_groups = doc.groups;
for (let group of order_groups) {
for (group_order_id of group) {
if (group_order_id == id) {
// We're in a group!
group_ids = group;
}
}
}
// if not in group, add current order to group
if (group_ids.length == 0) {
group_ids.push(id);
}
let partners_display_data = [];
dbc.allDocs({
include_docs: true
}).then(function (result) {
// for each order in the group
for (let order_id of group_ids) {
// find order
let order = result.rows.find(el => el.id == 'order_' + order_id);
order = order.doc;
orders[order_id] = order;
//Add each order's already updated and validated products to common list
if (order["updated_products"]) {
updatedProducts = updatedProducts.concat(order["updated_products"]);
}
if (order["valid_products"]) {
validProducts = validProducts.concat(order["valid_products"]);
}
// Prepare data to display in 'partner name' area
partners_display_data.push(order['partner'] + ' du ' + order['date_order']);
}
// Set current reception status: take first order's
reception_status = orders[Object.keys(orders)[0]].reception_status;
// Load saved user comments, get it from first order
user_comments = orders[Object.keys(orders)[0]].user_comments || "";
// Fetch orders data
fetch_data();
init_dom(partners_display_data);
})
.catch(function (e) {
let msg = ('message' in e && 'name' in e) ? e.name + ' : ' + e.message : '';
err = {msg, ctx: 'page init - get orders from couchdb', details: e};
console.error(err);
report_JS_error(err, 'reception');
// Should be there, redirect
alert("Erreur au chargement de cette commande. Vous allez être redirigé.");
back();
});
})
.catch(function (e) {
let msg = ('message' in e && 'name' in e) ? e.name + ' : ' + e.message : '';
err = {msg, ctx: 'page init - get grouped orders', details: e};
console.error(err);
report_JS_error(err, 'reception');
// Should be there, redirect
alert("Erreur au chargement de cette commande. Vous allez être redirigé.");
back();
});
}); });
...@@ -16,6 +16,5 @@ urlpatterns = [ ...@@ -16,6 +16,5 @@ 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)
] ]
...@@ -27,17 +27,12 @@ def as_text(value): ...@@ -27,17 +27,12 @@ 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 'couchdb_server': settings.COUCHDB['url'],
'db': settings.COUCHDB['dbs']['reception'],
'POUCHDB_VERSION': getattr(settings, 'POUCHDB_VERSION', '')
} }
template = loader.get_template('reception/index.html') template = loader.get_template('reception/index.html')
...@@ -75,8 +70,13 @@ def get_list_orders(request): ...@@ -75,8 +70,13 @@ def get_list_orders(request):
def produits(request, id): def produits(request, id):
""" Gets Order details """ """ Gets Order details """
context = {'title': 'Réception des produits', context = {
"TOOLS_SERVER": settings.TOOLS_SERVER} 'title': 'Réception des produits',
"TOOLS_SERVER": settings.TOOLS_SERVER,
'couchdb_server': settings.COUCHDB['url'],
'db': settings.COUCHDB['dbs']['reception'],
'POUCHDB_VERSION': getattr(settings, 'POUCHDB_VERSION', '')
}
fixed_barcode_prefix = '0490' fixed_barcode_prefix = '0490'
if hasattr(settings, 'RECEPTION_PB'): if hasattr(settings, 'RECEPTION_PB'):
...@@ -131,40 +131,6 @@ def data_validation(request): ...@@ -131,40 +131,6 @@ 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"""
...@@ -255,6 +221,7 @@ def update_orders(request): ...@@ -255,6 +221,7 @@ def update_orders(request):
# Remove order's group # Remove order's group
try: try:
# TODO remove from couchdb orders & group (here?)
if os.path.exists('temp/grouped_order.json'): if os.path.exists('temp/grouped_order.json'):
with open('temp/grouped_order.json', 'r') as json_file: with open('temp/grouped_order.json', 'r') as json_file:
saved_groups = json.load(json_file) saved_groups = json.load(json_file)
...@@ -270,6 +237,7 @@ def update_orders(request): ...@@ -270,6 +237,7 @@ def update_orders(request):
except Exception as e: except Exception as e:
# no saved groups # no saved groups
print(str(e)) print(str(e))
# TODO else if first step, save first step data (here?)
else: else:
coop_logger.error("update_orders errors : %s", str(errors)) coop_logger.error("update_orders errors : %s", str(errors))
rep = JsonResponse(answer_data, safe=False) rep = JsonResponse(answer_data, safe=False)
...@@ -298,7 +266,7 @@ def save_error_report(request): ...@@ -298,7 +266,7 @@ def save_error_report(request):
orders_partner = "" orders_partner = ""
group_ids = [] group_ids = []
for i, order in enumerate(data['orders']) : for i, order in enumerate(data['orders']) :
# list of temp files: 1 report per reception # list of temp files: 1 report per order & group
data['orders'][i]['temp_file_name'] = "temp/" + order['name'] + "_rapport-reception_temp.xlsx" data['orders'][i]['temp_file_name'] = "temp/" + order['name'] + "_rapport-reception_temp.xlsx"
group_ids.append(order['id']) group_ids.append(order['id'])
...@@ -421,7 +389,8 @@ def save_error_report(request): ...@@ -421,7 +389,8 @@ def save_error_report(request):
# Clear step 1 temp file # Clear step 1 temp file
os.remove(order['temp_file_name']) os.remove(order['temp_file_name'])
except: except:
data_comment_s1 = "Rapport de la première étape absent !" data_comment_s1 = "Données de la première étape absentes !"
# Add data from step 2 # Add data from step 2
data_full = [] data_full = []
error_total = 0 error_total = 0
...@@ -482,6 +451,7 @@ def save_error_report(request): ...@@ -482,6 +451,7 @@ def save_error_report(request):
# no updated products, do nothing # no updated products, do nothing
print("Error while updating products") print("Error while updating products")
print(exp) print(exp)
# Add remaining products, the ones edited only in step 1 # Add remaining products, the ones edited only in step 1
for product in data_qties.values(): for product in data_qties.values():
item = { item = {
...@@ -502,6 +472,8 @@ def save_error_report(request): ...@@ -502,6 +472,8 @@ def save_error_report(request):
data_full.append(item) data_full.append(item)
# For an eventual step 3, save data_full
# Sort by error amount # Sort by error amount
def sortByError(e): def sortByError(e):
return abs(e['error_line']) return abs(e['error_line'])
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
<script type="text/javascript" src="{% static 'js/datatables/dataTables.plugins.js' %}"></script> <script type="text/javascript" src="{% static 'js/datatables/dataTables.plugins.js' %}"></script>
<script type="text/javascript" src="{% static 'js/moment.min.js' %}"></script> <script type="text/javascript" src="{% static 'js/moment.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/datatables/dataTables.plugin.moment_sorting.js' %}"></script> <script type="text/javascript" src="{% static 'js/datatables/dataTables.plugin.moment_sorting.js' %}"></script>
<script type="text/javascript" src="{% static 'js/reception_index.js' %}?v="></script>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
...@@ -31,7 +30,6 @@ ...@@ -31,7 +30,6 @@
<div id="groups_items"></div> <div id="groups_items"></div>
</div> </div>
<br>
<div id="grouped_action"> <div id="grouped_action">
<button type="button" class='btn--primary' id='group_action' onclick="group_action()" hidden>Compter les produits des commandes sélectionnées</button> <button type="button" class='btn--primary' id='group_action' onclick="group_action()" hidden>Compter les produits des commandes sélectionnées</button>
</div> </div>
...@@ -52,9 +50,11 @@ ...@@ -52,9 +50,11 @@
<br/> <br/>
<script src="{% static "js/all_common.js" %}?v="></script> <script src="{% static "js/all_common.js" %}?v="></script>
<script src="{% static 'js/pouchdb.min'|add:POUCHDB_VERSION|add:'.js' %}"></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}}; var couchdb_dbname = '{{db}}';
var couchdb_server = '{{couchdb_server}}' + couchdb_dbname;
</script> </script>
<script src="{% static "js/common.js" %}?v="></script> <script type="text/javascript" src="{% static 'js/reception_index.js' %}?v="></script>
{% endblock %} {% endblock %}
...@@ -180,9 +180,13 @@ ...@@ -180,9 +180,13 @@
</div> </div>
<br/> <br/>
</div> </div>
<script src="{% static 'js/pouchdb.min'|add:POUCHDB_VERSION|add:'.js' %}"></script>
<script type="text/javascript"> <script type="text/javascript">
var tools_server = '{{TOOLS_SERVER}}' var tools_server = '{{TOOLS_SERVER}}'
var fixed_barcode_prefix = '{{FIXED_BARCODE_PREFIX}}' var fixed_barcode_prefix = '{{FIXED_BARCODE_PREFIX}}'
var couchdb_dbname = '{{db}}';
var couchdb_server = '{{couchdb_server}}' + couchdb_dbname;
</script> </script>
<script src="{% static "js/all_common.js" %}?v="></script> <script src="{% static "js/all_common.js" %}?v="></script>
<script src='{% static "js/barcodes.js" %}?v='></script> <script src='{% static "js/barcodes.js" %}?v='></script>
......
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