Commit 9f56118c by Damien Moulard

[WIP] replace localstorage by couchdb in reception

parent 520b3262
......@@ -19,7 +19,8 @@ COUCHDB = {
'member': 'coops',
'inventory': 'inventory',
'envelops': 'envelop',
'shop': 'shopping_carts'
'shop': 'shopping_carts',
'reception': 'reception_test'
}
}
......
......@@ -11,6 +11,10 @@ input[type="number"] {
}
/* INDEX */
.group_line {
margin-bottom: 5px;
}
#orders tbody tr {
cursor: pointer;
}
......
var order = {
var orders = [],
order = {
'id' : null
},
table_orders = null,
callback_update = false,
callback_report = false,
selection_type = null,
saved_groups = [];
order_groups = {
_id: null,
groups: []
},
dbc = null,
sync = null;
/* 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() {
if (callback_update && callback_report)
document.location.reload();
......@@ -20,178 +29,74 @@ function goto(id) {
document.location.href = "produits/" + id;
}
/*
/**
* Go to Products page for an existing group
* params :
* 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)
* @param {int} group_index index of group in groups array
*/
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: 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 group_goto(group_index) {
console.log(order_groups.groups);
// Make sure a couchdb document exists for all group's orders
for (let i in order_groups.groups[group_index]) {
let order_data = null;
// Find order data
for (let order of orders) {
if (order.id == order_groups.groups[group_index][i]) {
order_data = order
}
}
}
}
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;
}
}
}
}
create_order_doc(order_data);
}
// Add server groups to stored groups
grouped_orders = grouped_orders.concat(server_stored_groups);
localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
// go to first order
goto(order_groups.groups[group_index][0]);
}
/*
* 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() {
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];
function create_order_doc(order_data, go_to_order = false) {
const order_doc_id = 'order_' + order_data.id;
g.push(order);
// remove raw from table
table_orders.rows(i).remove()
.draw();
dbc.get(order_doc_id).then(() => {
if (go_to_order === true) {
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;
dbc.put(order_doc, (err) => {
if (!err) {
if (go_to_order === true) {
goto(order_data.id)
}
}
}
// 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 + ", ";
error = {
msg: 'Erreur dans la creation de la commande dans couchdb',
ctx: 'validatePrices',
details: err
};
report_JS_error(error, 'reception');
console.log(error);
}
}
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 */
// Validate all prices of an order
function validatePrices() {
/**
* Validate all prices of an order
*/
function validatePrices() {
// Loading on
openModal();
......@@ -210,9 +115,19 @@ function validatePrices() {
contentType: "application/json; charset=utf-8",
data: JSON.stringify(update_data),
success: function() {
localStorage.removeItem("order_" + order["id"]);
callback_update = true;
reload();
// Remove order
dbc.get(`order_${order['id']}`).then((doc) => {
return dbc.remove(doc);
})
.then(() => {
callback_update = true;
reload();
})
.catch((err) => {
// No doc found
console.log(err);
reload();
});
},
error: function() {
closeModal();
......@@ -251,72 +166,38 @@ function validatePrices() {
});
}
// Action fired when orders are grouped (new group)
/**
* Action fired when orders are grouped (new group)
* @returns
*/
function group_action() {
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
// Use local storage to pass order data to next page
if (Modernizr.localstorage) {
var selected_data = table_orders.rows('.selected').data();
var group_ids = [];
// Select orders id
for (var i = 0; i < selected_data.length; i++) {
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() {
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;
}
let pswd = prompt('Merci de demander à un.e salarié.e le mot de passe pour fusionner ces commandes.');
// Add each order to local storage
set_local_storage(selected_data[i]);
}
// Get array of grouped orders
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);
// Minimum security level
if (pswd == merge_orders_pswd) {
let selected_data = table_orders.rows('.selected').data();
let group_ids = [];
// store grouped orders array
localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
for (let i = 0; i < selected_data.length; i++) {
// Select group orders id
group_ids.push(selected_data[i].id);
// 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.");
}
}
});
// Create doc for each group order if doesn't exist
create_order_doc(selected_data[i]);
}
group_ids.sort();
} else {
alert("Le local storage n'est pas disponible. Merci de contacter un.e salarié.e !");
}
// Save group
order_groups.groups.push(group_ids);
dbc.put(order_groups, (err) => {
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);
}
});
} else if (pswd == null) {
return;
......@@ -325,17 +206,71 @@ function group_action() {
}
}
/* DISPLAY */
$(document).ready(function() {
openModal();
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
// Set date format for DataTable so date ordering can work
$.fn.dataTable.moment('D/M/Y');
/**
* 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];
group_orders.push(order);
// remove table row
table_orders.rows(i).remove()
.draw();
}
}
}
// 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 {
group_row += "<b>" + group_orders[i].partner + "</b> du " + group_orders[i].date_order + ", ";
}
}
if (group_orders[0].reception_status == 'False') {
group_row += "<button class='btn--primary' onClick='group_goto("
+ group_index
+ ")'>Compter les produits</button>";
} else {
group_row += "<button class='btn--success' onClick='group_goto("
+ group_index
+ ")'>Mettre à jour les prix</button>";
}
group_row += "</li>";
groups_display_content += group_row;
}
$('#container_groups').show();
$('#groups_items').append(groups_display_content);
}
}
/**
* Display the main orders table
*/
function display_orders_table() {
table_orders = $('#orders').DataTable({
ajax: "get_list_orders",
data: orders,
columns:[
{
data:"id",
......@@ -417,13 +352,7 @@ $(document).ready(function() {
]
],
iDisplayLength: 25,
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();
}
language: {url : '/static/js/datatables/french.json'}
});
// Set rows event on click
......@@ -482,12 +411,10 @@ $(document).ready(function() {
document.getElementById("group_action").hidden = true;
}
} 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") {
// Use local storage to pass order data to next page
set_local_storage(row_data);
goto(row_data.id);
// Use couchdb to pass order data to next page
create_order_doc(row_data, true);
}
} else if (this.cellIndex == 3 && row_data.reception_status == "qty_valid") {
// If 'update prices' step, click on before-last cell -> validate all prices
......@@ -502,6 +429,68 @@ $(document).ready(function() {
.search(jQuery.fn.DataTable.ext.type.search.string(this.value))
.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 :
* Associative array of current order(s)
* If more than 1 element: group of orders
* If 1 element: single order
* -> check for Object.keys(orders).length to know if we're in a group case
*/
var orders = {},
is_group = false,
group_ids = [];
var reception_status = null,
......@@ -32,6 +32,8 @@ var reception_status = null,
updateType = "", // step 1: qty_valid; step2: br_valid
barcodes = null; // Barcodes stored locally
var dbc = null,
sync = null;
/* UTILS */
......@@ -112,12 +114,29 @@ function select_product_from_bc(barcode) {
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 */
// Get order(s) data from server
function fetch_data() {
try {
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({
type: 'POST',
url: '../get_orders_lines',
......@@ -198,7 +217,7 @@ function initLists() {
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++) {
let product = updatedProducts[i];
......@@ -384,17 +403,18 @@ function initLists() {
$('#table_to_process tbody').on('click', 'a#toProcess_line_valid', function () {
if (is_time_to('reception_direct_valid_order_line', 500)) {
try {
var row = table_to_process.row($(this).parents('tr'));
var data = row.data();
let row = table_to_process.row($(this).parents('tr'));
let data = row.data();
add_to_processed(data);
remove_from_toProcess(row, data);
// Update local storage of product's order
if (!orders[data.id_po]['valid_products'])
// Update product's order
if (!orders[data.id_po]['valid_products']) {
orders[data.id_po]['valid_products'] = [];
}
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
document.getElementById('search_input').value = '';
......@@ -719,8 +739,8 @@ function set_supplier_shortage(row, product, from_processed = false) {
}
add_to_processed(product);
// Update local storage of product's order
localStorage.setItem("order_" + product.id_po, JSON.stringify(orders[product.id_po]));
// Update product's order
update_distant_order(product.id_po);
// Reset search
document.getElementById('search_input').value = '';
......@@ -856,10 +876,10 @@ function editProductInfo (productToEdit, value = null) {
if (firstUpdate) {
updatedProducts.push(productToEdit);
/* Update local storage of product order */
// 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'] = [];
}
// Add product to order's updated products if first update
orders[productToEdit.id_po]['updated_products'].push(productToEdit);
......@@ -881,8 +901,8 @@ function editProductInfo (productToEdit, value = null) {
}
}
// Update local storage of product order
localStorage.setItem("order_" + productToEdit.id_po, JSON.stringify(orders[productToEdit.id_po]));
// Update product order
update_distant_order(productToEdit.id_po);
add_to_processed(productToEdit);
} catch (e) {
......@@ -918,8 +938,6 @@ function setAllQties() {
.draw();
}
/* ACTIONS */
// Get labels to print for current orders from server
......@@ -1010,7 +1028,6 @@ function pre_send(type) {
function data_validation() {
openModal();
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({
type: "POST",
url: "../data_validation",
......@@ -1065,7 +1082,8 @@ function send() {
// for each updated product, add it to its order list
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]) {
// for each other order of product
for (other_order_data of updatedProducts[i].other_orders_data) {
......@@ -1122,13 +1140,13 @@ function send() {
orders[other_order_data.id_po]['updated_products'].push(product_copy);
}
}
/* <--- */
// Add product to order's prod list
prod_order_id = updatedProducts[i].id_po;
update_data.orders[prod_order_id]['po'].push(updatedProducts[i]);
}
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({
type: "PUT",
url: "../update_orders",
......@@ -1171,9 +1189,9 @@ function send() {
}
// 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;
} else {
} else { // group
document.getElementById("success_order_name_container").hidden = true;
document.getElementById("success_orders_name_container").hidden = false;
......@@ -1198,9 +1216,7 @@ function send() {
openModal(
$('#modal_qtiesValidated').html(),
function() {
document.location.href = "/reception";
},
back,
'Retour à la liste des commandes',
true,
false
......@@ -1213,9 +1229,7 @@ function send() {
openModal(
$('#templates #modal_pricesValidated').html(),
function() {
document.location.href = "/reception";
},
back,
'Retour à la liste des commandes',
true,
false
......@@ -1223,38 +1237,39 @@ function send() {
}
// Go back to to_process list if modal closed
$('#modal_closebtn_top').on('click', function () {
document.location.href = "/reception";
});
$('#modal_closebtn_top').on('click', back);
$('#modal_closebtn_bottom').on('click', back);
$('#modal_closebtn_bottom').on('click', function () {
document.location.href = "/reception";
});
// TODO data clearing.
// 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
for (order_id in orders) {
localStorage.removeItem("order_" + order_id);
}
// for (order_id in orders) {
// localStorage.removeItem("order_" + order_id);
// }
// Delete group(s)
if (is_group) {
var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
// Remove all groups containing these orders
for (order_id in orders) {
search:
for (var h = 0; i < grouped_orders.length; h++) {
for (var j = 0; j < grouped_orders[h].length; j++) {
if (grouped_orders[h][j] == order_id) {
grouped_orders.splice(h);
break search;
}
}
}
}
localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
}
// if (Object.keys(orders).length > 1) {
// var grouped_orders = JSON.parse(localStorage.getItem('grouped_orders'));
// // Remove all groups containing these orders
// for (order_id in orders) {
// search:
// for (var h = 0; i < grouped_orders.length; h++) {
// for (var j = 0; j < grouped_orders[h].length; j++) {
// if (grouped_orders[h][j] == order_id) {
// grouped_orders.splice(h);
// break search;
// }
// }
// }
// }
// localStorage.setItem('grouped_orders', JSON.stringify(grouped_orders));
// }
} catch (ee) {
err = {msg: ee.name + ' : ' + ee.message, ctx: 'callback update_orders'};
......@@ -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
var updates = {
'group_amount_total' : 0,
......@@ -1331,8 +1348,7 @@ function confirm_all_left_is_good() {
.draw();
closeModal();
}
/* TODO: upgrade modal
-> disable background scrolling*/
function openFAQ() {
openModal($("div#modal_FAQ_content").html(), function() {}, 'Compris !', true, false);
}
......@@ -1359,10 +1375,10 @@ function openErrorReport() {
function saveErrorReport() {
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)) {
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();
......@@ -1374,199 +1390,73 @@ 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) {
$('#partner_name').html(Object.keys(orders).length + " commandes");
// Display order data for each order
var msg = "";
for (display_partner_data of display_partners_name) {
if (msg != "") {
msg += ", ";
}
msg += display_partner_data;
/**
* 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");
// Display order data for each order
var msg = "";
for (display_partner_data of partners_display_data) {
if (msg != "") {
msg += ", ";
}
$('#container_multiple_partners').append('<h6> ' + msg + '</h6>');
} else {
$('#partner_name').html(orders[Object.keys(orders)[0]].partner);
msg += display_partner_data;
}
$('#container_multiple_partners').append('<h6> ' + msg + '</h6>');
} else {
$('#partner_name').html(orders[Object.keys(orders)[0]].partner);
}
/* Set DOM according to reception status */
if (reception_status == "qty_valid") { // Step 2
// Header
document.getElementById('header_step_two').classList.add('step_two_active');
var check_icon = document.createElement('i');
check_icon.className = 'far fa-check-circle';
document.getElementById('header_step_one_content').appendChild(check_icon);
/* Set DOM according to reception status */
if (reception_status == "qty_valid") { // Step 2
// Header
document.getElementById('header_step_two').classList.add('step_two_active');
var check_icon = document.createElement('i');
// Products lists containers
document.getElementById('container_left').style.border = "3px solid #0275D8"; // container qty_checked
document.getElementById('container_right').style.border = "3px solid #5CB85C"; // container processed items
document.getElementById('header_container_left').innerHTML = "Prix à mettre à jour";
document.getElementById('header_container_right').innerHTML = "Prix mis à jour";
check_icon.className = 'far fa-check-circle';
document.getElementById('header_step_one_content').appendChild(check_icon);
// Edition
document.getElementById('edition_header').innerHTML = "Editer les prix";
document.getElementById('edition_input_label').innerHTML = "Prix unit.";
// Products lists containers
document.getElementById('container_left').style.border = "3px solid #0275D8"; // container qty_checked
document.getElementById('container_right').style.border = "3px solid #5CB85C"; // container processed items
document.getElementById('header_container_left').innerHTML = "Prix à mettre à jour";
document.getElementById('header_container_right').innerHTML = "Prix mis à jour";
// Validation buttons
document.getElementById("valid_all").innerHTML = "<button class='btn--danger full_width_button' id='valid_all_uprices' onclick=\"openModal($('#templates #modal_no_prices').html(), confirmPricesAllValid, 'Confirmer', false);\" disabled>Pas de prix sur le bon de livraison</button>";
document.getElementById("validation_button").innerHTML = "<button class='btn--success full_width_button' id='valid_uprice' onclick=\"pre_send('br_valid')\" disabled>Valider la mise à jour des prix</button>";
// Edition
document.getElementById('edition_header').innerHTML = "Editer les prix";
document.getElementById('edition_input_label').innerHTML = "Prix unit.";
// Modal content after validation
$("#modal_pricesValidated").load("/reception/reception_pricesValidated");
} else if (reception_status == "False") { // Step 1
document.getElementById('header_step_one').classList.add('step_one_active');
// Validation buttons
document.getElementById("valid_all").innerHTML = "<button class='btn--danger full_width_button' id='valid_all_uprices' onclick=\"openModal($('#templates #modal_no_prices').html(), confirmPricesAllValid, 'Confirmer', false);\" disabled>Pas de prix sur le bon de livraison</button>";
document.getElementById("validation_button").innerHTML = "<button class='btn--success full_width_button' id='valid_uprice' onclick=\"pre_send('br_valid')\" disabled>Valider la mise à jour des prix</button>";
document.getElementById('container_left').style.border = "3px solid #212529"; // container products to process
document.getElementById('container_right').style.border = "3px solid #0275D8"; // container qty_checked
document.getElementById('header_container_left').innerHTML = "Produits à compter";
document.getElementById('header_container_right').innerHTML = "Produits déjà comptés";
// Modal content after validation
$("#modal_pricesValidated").load("/reception/reception_pricesValidated");
} else if (reception_status == "False") { // Step 1
document.getElementById('header_step_one').classList.add('step_one_active');
document.getElementById('edition_header').innerHTML = "Editer les quantités";
document.getElementById('edition_input_label').innerHTML = "Qté";
document.getElementById('container_left').style.border = "3px solid #212529"; // container products to process
document.getElementById('container_right').style.border = "3px solid #0275D8"; // container qty_checked
document.getElementById('header_container_left').innerHTML = "Produits à compter";
document.getElementById('header_container_right').innerHTML = "Produits déjà comptés";
document.getElementById("valid_all").innerHTML = "<button class='btn--danger full_width_button' id='valid_all_qties' onclick=\"openModal($('#templates #modal_no_qties').html(), setAllQties, 'Confirmer');\" disabled>Il n'y a plus de produits à compter</button>";
document.getElementById("validation_button").innerHTML = "<button class='btn--primary full_width_button' id='valid_qty' onclick=\"pre_send('qty_valid')\" disabled>Valider le comptage des produits</button>";
document.getElementById('edition_header').innerHTML = "Editer les quantités";
document.getElementById('edition_input_label').innerHTML = "Qté";
$("#modal_qtiesValidated").load("/reception/reception_qtiesValidated");
} else {
// 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');
document.getElementById("valid_all").innerHTML = "<button class='btn--danger full_width_button' id='valid_all_qties' onclick=\"openModal($('#templates #modal_no_qties').html(), setAllQties, 'Confirmer');\" disabled>Il n'y a plus de produits à compter</button>";
document.getElementById("validation_button").innerHTML = "<button class='btn--primary full_width_button' id='valid_qty' onclick=\"pre_send('qty_valid')\" disabled>Valider le comptage des produits</button>";
alert("Erreur au chargement de cette commande. Vous allez être redirigé.");
$("#modal_qtiesValidated").load("/reception/reception_qtiesValidated");
} else {
// Extra security, shouldn't get in here
back();
}
......@@ -1589,16 +1479,6 @@ $(document).ready(function() {
$('#edition_input').on('focus', function () {
$(this).on('wheel.disableScroll', function (e) {
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 () {
......@@ -1687,4 +1567,166 @@ $(document).ready(function() {
.draw();
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 = [
url(r'^reception_qtiesValidated', views.reception_qtiesValidated),
url(r'^reception_pricesValidated', views.reception_pricesValidated),
# url(r'^update_order_status/([0-9]+)$', views.tmp_update_order_status),
url(r'^po_process_picking$', views.po_process_picking),
url(r'^save_order_group$', views.save_order_group)
url(r'^po_process_picking$', views.po_process_picking)
]
......@@ -27,17 +27,12 @@ def as_text(value):
def home(request):
"""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 = {
'title': 'Reception',
'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')
......@@ -75,8 +70,13 @@ def get_list_orders(request):
def produits(request, id):
""" Gets Order details """
context = {'title': 'Réception des produits',
"TOOLS_SERVER": settings.TOOLS_SERVER}
context = {
'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'
if hasattr(settings, 'RECEPTION_PB'):
......@@ -131,40 +131,6 @@ def data_validation(request):
coop_logger.error("Orders data validation : %s", str(e))
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):
"""Update orders lines: quantity and unit prices"""
......@@ -255,6 +221,7 @@ def update_orders(request):
# Remove order's group
try:
# TODO remove from couchdb orders & group (here?)
if os.path.exists('temp/grouped_order.json'):
with open('temp/grouped_order.json', 'r') as json_file:
saved_groups = json.load(json_file)
......@@ -270,6 +237,7 @@ def update_orders(request):
except Exception as e:
# no saved groups
print(str(e))
# TODO else if first step, save first step data (here?)
else:
coop_logger.error("update_orders errors : %s", str(errors))
rep = JsonResponse(answer_data, safe=False)
......@@ -298,7 +266,7 @@ def save_error_report(request):
orders_partner = ""
group_ids = []
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"
group_ids.append(order['id'])
......@@ -421,7 +389,8 @@ def save_error_report(request):
# Clear step 1 temp file
os.remove(order['temp_file_name'])
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
data_full = []
error_total = 0
......@@ -482,6 +451,7 @@ def save_error_report(request):
# no updated products, do nothing
print("Error while updating products")
print(exp)
# Add remaining products, the ones edited only in step 1
for product in data_qties.values():
item = {
......@@ -502,6 +472,8 @@ def save_error_report(request):
data_full.append(item)
# For an eventual step 3, save data_full
# Sort by error amount
def sortByError(e):
return abs(e['error_line'])
......
......@@ -11,7 +11,6 @@
<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/datatables/dataTables.plugin.moment_sorting.js' %}"></script>
<script type="text/javascript" src="{% static 'js/reception_index.js' %}?v="></script>
{% endblock %}
{% block content %}
......@@ -31,7 +30,6 @@
<div id="groups_items"></div>
</div>
<br>
<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>
</div>
......@@ -52,9 +50,11 @@
<br/>
<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">
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 src="{% static "js/common.js" %}?v="></script>
<script type="text/javascript" src="{% static 'js/reception_index.js' %}?v="></script>
{% endblock %}
......@@ -180,9 +180,13 @@
</div>
<br/>
</div>
<script src="{% static 'js/pouchdb.min'|add:POUCHDB_VERSION|add:'.js' %}"></script>
<script type="text/javascript">
var tools_server = '{{TOOLS_SERVER}}'
var fixed_barcode_prefix = '{{FIXED_BARCODE_PREFIX}}'
var couchdb_dbname = '{{db}}';
var couchdb_server = '{{couchdb_server}}' + couchdb_dbname;
</script>
<script src="{% static "js/all_common.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