Commit 67d289d4 by Damien Moulard

fix merge conflict

parents 4ee73655 e5f44f2b
Pipeline #2181 passed with stage
in 1 minute 28 seconds
...@@ -355,6 +355,10 @@ ...@@ -355,6 +355,10 @@
- RECEPTION_SHELF_LABEL_PRINT = True - RECEPTION_SHELF_LABEL_PRINT = True
- DISPLAY_COL_AUTRES = True
Display "Autres" column (showing select with action "rupture fournisseur")
- COEFF_MAG_ID = 1 - COEFF_MAG_ID = 1
DB coeff id, needed to compute product shelf price DB coeff id, needed to compute product shelf price
......
...@@ -188,6 +188,11 @@ div#container_edition { ...@@ -188,6 +188,11 @@ div#container_edition {
padding-bottom: 15px; padding-bottom: 15px;
} }
.title_partner_key {
font-weight: bolder;
font-size: 2rem;
}
/* Accordion style */ /* Accordion style */
/* Style the buttons that are used to open and close the accordion panel */ /* Style the buttons that are used to open and close the accordion panel */
...@@ -247,5 +252,9 @@ hr { ...@@ -247,5 +252,9 @@ hr {
#main_content {width: 100%;} #main_content {width: 100%;}
.select_product_action { .select_product_action {
max-width: 15px; max-width: 5px;
} }
.toProcess_line_edit, .toProcess_line_valid {
min-width: 11px;
}
\ No newline at end of file
...@@ -365,9 +365,7 @@ function display_orders_table() { ...@@ -365,9 +365,7 @@ function display_orders_table() {
table_orders.clear().destroy(); table_orders.clear().destroy();
$('#orders').empty(); $('#orders').empty();
} }
for (let j in orders) {
console.log(orders[j].id);
}
table_orders = $('#orders').DataTable({ table_orders = $('#orders').DataTable({
data: orders, data: orders,
columns:[ columns:[
......
...@@ -282,6 +282,11 @@ function fetch_data() { ...@@ -282,6 +282,11 @@ function fetch_data() {
} }
} else { } else {
// Add order key in products
let order_full_data = orders[order_data.id_po];
order_data.po[i].order_key = order_full_data.key;
// Add product to list_to_process // Add product to list_to_process
list_to_process.push(order_data.po[i]); list_to_process.push(order_data.po[i]);
...@@ -310,7 +315,7 @@ function fetch_data() { ...@@ -310,7 +315,7 @@ function fetch_data() {
// Init Data & listeners // Init Data & listeners
function initLists() { function initLists() {
try { try {
// Un-disable validation buttons now the data's here // Enable validation buttons now the data's here
if (reception_status == "False") { if (reception_status == "False") {
document.getElementById("valid_qty").disabled = false; document.getElementById("valid_qty").disabled = false;
document.getElementById("valid_all_qties").disabled = false; document.getElementById("valid_all_qties").disabled = false;
...@@ -344,62 +349,151 @@ function initLists() { ...@@ -344,62 +349,151 @@ function initLists() {
} }
} }
// Init table for to_process content let columns_to_process = [];
table_to_process = $('#table_to_process').DataTable({ let columns_processed = [];
data: list_to_process,
columns:[ // In case of group orders, add "Order" as first column for ordering
{data:"product_id.0", title: "id", visible: false}, if (Object.keys(orders).length > 1) {
{data:"shelf_sortorder", title: "Rayon", className: "dt-body-center"}, columns_to_process.push({
{ data:"order_key", title: "n°", className: "dt-body-center",
data:"product_id.1", width: "20px"
title:"Produit", });
width: "45%", }
render: function (data, type, full) {
// Add tooltip with barcode over product name
let display_barcode = "Aucun";
if ('barcode' in full) {
display_barcode = full.barcode;
}
return '<div class="tooltip">' + data columns_to_process = columns_to_process.concat([
+ ' <span class="tooltiptext tt_twolines">Code barre : ' {data:"product_id.0", title: "id", visible: false},
+ display_barcode + '</span> </div>'; {data:"shelf_sortorder", title: "Rayon", className: "dt-body-center"},
{
data:"product_id.1",
title:"Produit",
width: "45%",
render: function (data, type, full) {
// Add tooltip with barcode over product name
let display_barcode = "Aucun";
if ('barcode' in full) {
display_barcode = full.barcode;
} }
return '<div class="tooltip">' + data
+ ' <span class="tooltiptext tt_twolines">Code barre : '
+ display_barcode + '</span> </div>';
}
},
{data:"product_uom.1", title: "Unité vente", className:"dt-body-center", orderable: false},
{
data:"product_qty",
title: "Qté",
className:"dt-body-center",
visible: (reception_status == "False")
},
{
data:"price_unit",
title:"Prix unit.",
className:"dt-body-center",
visible: (reception_status == "qty_valid")
},
{
title:"Editer",
defaultContent: "<a class='btn toProcess_line_edit' href='#'><i class='far fa-edit'></i></a>",
className:"dt-body-center",
orderable: false
},
{
title:"Valider",
defaultContent: "<a class='btn toProcess_line_valid' href='#'><i class='far fa-check-square'></i></a>",
className:"dt-body-center",
orderable: false
},
{
title:"",
defaultContent: "<select class='select_product_action'><option value=''></option><option value='supplier_shortage'>Rupture fournisseur</option></select>",
className:"dt-body-center",
orderable: false,
visible: display_autres === "True"
}
]);
columns_processed = [
{data:"row_counter", title:"row_counter", visible: false}, // Hidden counter to display last row first
{data:"shelf_sortorder", title: "Rayon", className:"dt-body-center"},
{
data:"product_id.1",
title:"Produit",
width: "55%",
render: function (data, type, full) {
// Add tooltip with barcode over product name
let display_barcode = "Aucun";
if ('barcode' in full) {
display_barcode = full.barcode;
}
let display = '<div class="tooltip">' + data
+ ' <span class="tooltiptext tt_twolines">Code barre : '
+ display_barcode + '</span> </div>';
if (full.supplier_shortage) {
display += ' <div class="tooltip"><i class="fas fa-info-circle"></i>'
+ ' <span class="tooltiptext tt_twolines">Rupture fournisseur'
+ '</span> </div>';
}
return display;
}
},
{data:"product_uom.1", title: "Unité vente", className:"dt-body-center", orderable: false},
{
data:"product_qty",
title:"Qté",
className:"dt-head-center dt-body-center",
visible: (reception_status == "False"),
render: function (data, type, full) {
let disp = [
full.product_qty,
(full.old_qty !== undefined)?full.old_qty:full.product_qty
].join("/");
return disp;
}, },
{data:"product_uom.1", title: "Unité vente", className:"dt-body-center", orderable: false}, orderable: false
{ },
data:"product_qty", {
title: "Qté", data:"price_unit",
className:"dt-body-center", title:"Prix unit",
visible: (reception_status == "False") className:"dt-body-center",
}, visible: (reception_status == "qty_valid")
{ },
data:"price_unit", {
title:"Prix unit.", title:"Editer",
className:"dt-body-center", defaultContent: "<a class='btn' id='processed_line_edit' href='#'><i class='far fa-edit'></i></a>",
visible: (reception_status == "qty_valid") className:"dt-body-center",
}, orderable: false
{ },
title:"Editer", {
defaultContent: "<a class='btn' id='toProcess_line_edit' href='#'><i class='far fa-edit'></i></a>", title:"Autres",
className:"dt-body-center", className:"dt-body-center",
orderable: false orderable: false,
}, visible: display_autres === "True",
{ render: function (data, type, full) {
title:"Valider", let disabled = (full.supplier_shortage) ? "disabled" : '';
defaultContent: "<a class='btn' id='toProcess_line_valid' href='#'><i class='far fa-check-square'></i></a>",
className:"dt-body-center", return "<select class='select_product_action'>"
orderable: false + "<option value=''></option>"
}, + "<option value='supplier_shortage' "+disabled+">Rupture fournisseur</option>"
{ + "</select>";
title:"Autres",
defaultContent: "<select class='select_product_action'><option value=''></option><option value='supplier_shortage'>Rupture fournisseur</option></select>",
className:"dt-body-center",
orderable: false,
visible: display_autres === "True"
} }
], }
];
console.log(columns_to_process);
// Init table for to_process content
table_to_process = $('#table_to_process').DataTable({
data: list_to_process,
columns: columns_to_process,
rowId : "product_id.0", rowId : "product_id.0",
order: [ order: [
[ [
...@@ -413,81 +507,11 @@ function initLists() { ...@@ -413,81 +507,11 @@ function initLists() {
dom: 'lrtip', // Remove the search input from that table dom: 'lrtip', // Remove the search input from that table
language: {url : '/static/js/datatables/french.json'} language: {url : '/static/js/datatables/french.json'}
}); });
// Init table for processed content // Init table for processed content
table_processed = $('#table_processed').DataTable({ table_processed = $('#table_processed').DataTable({
data: list_processed, data: list_processed,
columns:[ columns: columns_processed,
{data:"row_counter", title:"row_counter", visible: false}, // Hidden counter to display last row first
{data:"shelf_sortorder", title: "Rayon", className:"dt-body-center"},
{
data:"product_id.1",
title:"Produit",
width: "55%",
render: function (data, type, full) {
// Add tooltip with barcode over product name
let display_barcode = "Aucun";
if ('barcode' in full) {
display_barcode = full.barcode;
}
let display = '<div class="tooltip">' + data
+ ' <span class="tooltiptext tt_twolines">Code barre : '
+ display_barcode + '</span> </div>';
if (full.supplier_shortage) {
display += ' <div class="tooltip"><i class="fas fa-info-circle"></i>'
+ ' <span class="tooltiptext tt_twolines">Rupture fournisseur'
+ '</span> </div>';
}
return display;
}
},
{data:"product_uom.1", title: "Unité vente", className:"dt-body-center", orderable: false},
{
data:"product_qty",
title:"Qté",
className:"dt-head-center dt-body-center",
visible: (reception_status == "False"),
render: function (data, type, full) {
let disp = [
full.product_qty,
(full.old_qty !== undefined)?full.old_qty:full.product_qty
].join("/");
return disp;
},
orderable: false
},
{
data:"price_unit",
title:"Prix unit",
className:"dt-body-center",
visible: (reception_status == "qty_valid")
},
{
title:"Editer",
defaultContent: "<a class='btn' id='processed_line_edit' href='#'><i class='far fa-edit'></i></a>",
className:"dt-body-center",
orderable: false
},
{
title:"Autres",
className:"dt-body-center",
orderable: false,
visible: display_autres === "True",
render: function (data, type, full) {
let disabled = (full.supplier_shortage) ? "disabled" : '';
return "<select class='select_product_action'>"
+ "<option value=''></option>"
+ "<option value='supplier_shortage' "+disabled+">Rupture fournisseur</option>"
+ "</select>";
}
}
],
rowId : "product_id.0", rowId : "product_id.0",
order: [ order: [
[ [
...@@ -509,7 +533,7 @@ function initLists() { ...@@ -509,7 +533,7 @@ function initLists() {
/* Listeners */ /* Listeners */
// Direct valid from to_process // Direct valid from to_process
$('#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 {
let row = table_to_process.row($(this).parents('tr')); let row = table_to_process.row($(this).parents('tr'));
...@@ -542,7 +566,7 @@ function initLists() { ...@@ -542,7 +566,7 @@ function initLists() {
}); });
// Edit to_process line // Edit to_process line
$('#table_to_process tbody').on('click', 'a#toProcess_line_edit', function () { $('#table_to_process tbody').on('click', 'a.toProcess_line_edit', function () {
try { try {
// Prevent editing mutiple lines at a time // Prevent editing mutiple lines at a time
if (editing_product == null) { if (editing_product == null) {
...@@ -1657,7 +1681,7 @@ function init_dom(partners_display_data) { ...@@ -1657,7 +1681,7 @@ function init_dom(partners_display_data) {
}; };
} }
dbc.bulkDocs(Object.values(orders)).then((response) => { dbc.bulkDocs(Object.values(orders)).then(() => {
back(); back();
}) })
.catch((err) => { .catch((err) => {
...@@ -1964,12 +1988,13 @@ $(document).ready(function() { ...@@ -1964,12 +1988,13 @@ $(document).ready(function() {
include_docs: true include_docs: true
}).then(function (result) { }).then(function (result) {
// for each order in the group // for each order in the group
for (let order_id of group_ids) { for (let i in group_ids) {
// find order // find order
let order_id = group_ids[i];
let order = result.rows.find(el => el.id == 'order_' + order_id); let order = result.rows.find(el => el.id == 'order_' + order_id);
order = order.doc; order = order.doc;
order.key = parseInt(i) + 1;
orders[order_id] = order; orders[order_id] = order;
// Add each order's already updated and validated products to common list // Add each order's already updated and validated products to common list
...@@ -1982,7 +2007,7 @@ $(document).ready(function() { ...@@ -1982,7 +2007,7 @@ $(document).ready(function() {
} }
// Prepare data to display in 'partner name' area // Prepare data to display in 'partner name' area
partners_display_data.push(order['partner'] + ' du ' + order['date_order']); partners_display_data.push(`<span class="title_partner_key">${order.key}.</span> ${order.partner} du ${order.date_order}`);
} }
// Set current reception status: take first order's // Set current reception status: take first order's
......
...@@ -58,7 +58,11 @@ def add_products(request): ...@@ -58,7 +58,11 @@ def add_products(request):
try: try:
id = int(request.POST.get('shelf_id')) id = int(request.POST.get('shelf_id'))
barcodes = json.loads(request.POST.get('bc')) barcodes = json.loads(request.POST.get('bc'))
result = Shelf(id).add_products_by_barcodes(barcodes) m = Shelf(id)
result = m.add_products_by_barcodes(barcodes)
# Update shelf last product added date
result["update_last_product_added_date"] = m.update_last_product_added_date()
except Exception as e: except Exception as e:
result['error'] = str(e) result['error'] = str(e)
else: else:
......
...@@ -6,7 +6,7 @@ from products.models import CagetteProducts ...@@ -6,7 +6,7 @@ from products.models import CagetteProducts
from inventory.models import CagetteInventory from inventory.models import CagetteInventory
import os import os
from datetime import date from datetime import date, datetime
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.styles import Alignment, Font from openpyxl.styles import Alignment, Font
from statistics import * from statistics import *
...@@ -14,6 +14,7 @@ from statistics import * ...@@ -14,6 +14,7 @@ from statistics import *
# Prefix for temp shelf inventory files # Prefix for temp shelf inventory files
tmp_inv_file_prefix = 'temp/inventory_shelf_' tmp_inv_file_prefix = 'temp/inventory_shelf_'
default_inventory_start_datetime = "0001-01-01 00:00:00"
def as_text(value): def as_text(value):
""" Utils """ """ Utils """
...@@ -106,6 +107,7 @@ class Shelf(models.Model): ...@@ -106,6 +107,7 @@ class Shelf(models.Model):
# Inventory all done # Inventory all done
f['inventory_status'] = '' f['inventory_status'] = ''
f['date_last_inventory'] = date.today().strftime("%Y-%m-%d") f['date_last_inventory'] = date.today().strftime("%Y-%m-%d")
f['ongoing_inv_start_datetime'] = default_inventory_start_datetime # Reset
if 'last_inventory_id' in params: if 'last_inventory_id' in params:
f['last_inventory_id'] = params['last_inventory_id'] f['last_inventory_id'] = params['last_inventory_id']
...@@ -180,6 +182,18 @@ class Shelf(models.Model): ...@@ -180,6 +182,18 @@ class Shelf(models.Model):
res['error'] = "L'enregistrement n'a pas pu se réaliser" res['error'] = "L'enregistrement n'a pas pu se réaliser"
return res return res
def set_begin_inventory_datetime(self):
res = {}
now = datetime.now().isoformat()
f = {'ongoing_inv_start_datetime': now}
try:
res["update"] = self.o_api.update('product.shelfs', self.id, f)
res["inventory_begin_datetime"] = now
except Exception as e:
res['error'] = str(e)
return res
def save_tmp_inventory(self, inventory_data): def save_tmp_inventory(self, inventory_data):
"""Save inventory data in a json temp file""" """Save inventory data in a json temp file"""
......
...@@ -12,21 +12,23 @@ var validation_msg = $('#validation_msg'), ...@@ -12,21 +12,23 @@ var validation_msg = $('#validation_msg'),
process_all_items_msg = $('#process_all_items_msg'), process_all_items_msg = $('#process_all_items_msg'),
faq_content = $("#FAQ_modal_content"), faq_content = $("#FAQ_modal_content"),
issues_reporting = $("#issues_reporting"), issues_reporting = $("#issues_reporting"),
add_product_form = $("#add_product_form"), add_product_form = $("#add_product_form");
add_product_input = $("#add_product_input");
var shelf, var shelf = null,
parent_location = '/shelfs', parent_location = '/shelfs',
originView = "shelf", // or custom_list (create from order view) originView = "shelf", // or custom_list (create from order view)
list_to_process = [], list_to_process = [],
table_to_process, table_to_process = null,
table_processed, table_processed = null,
editing_item = null, // Store the item currently being edited editing_item = null, // Store the item currently being edited
editing_origin, // Keep track of where editing_item comes from editing_origin = "", // Keep track of where editing_item comes from
processed_row_counter = 0, // Keep count of the order the item were added in processed list processed_row_counter = 0, // Keep count of the order the item were added in processed list
search_chars = [], search_chars = [],
user_comments = '', user_comments = '',
adding_product = false; // True if modal to add a product is open adding_product = false, // True if modal to add a product is open.
// datetime for which shelf's ongoing_inv_start_datetime is considered null
default_inventory_start_datetime = "0001-01-01 00:00:00";
/* UTILS */ /* UTILS */
...@@ -48,6 +50,10 @@ function back() { ...@@ -48,6 +50,10 @@ function back() {
document.location.href = parent_location; document.location.href = parent_location;
} }
function refresh() {
location.reload();
}
// Directly send a line to edition when barcode is read // Directly send a line to edition when barcode is read
function select_product_from_bc(barcode) { function select_product_from_bc(barcode) {
if (editing_item == null) { if (editing_item == null) {
...@@ -95,7 +101,7 @@ function handle_blinking_effect(element) { ...@@ -95,7 +101,7 @@ function handle_blinking_effect(element) {
element.addEventListener('animationend', onAnimationEnd); element.addEventListener('animationend', onAnimationEnd);
element.addEventListener('webkitAnimationEnd', onAnimationEnd); element.addEventListener('webkitAnimationEnd', onAnimationEnd);
function onAnimationEnd(e) { function onAnimationEnd() {
element.classList.remove('blink_me'); element.classList.remove('blink_me');
} }
} }
...@@ -169,7 +175,7 @@ function clearLineEdition() { ...@@ -169,7 +175,7 @@ function clearLineEdition() {
} }
// Validate product edition // Validate product edition
function validateEdition(form) { function validateEdition() {
if (editing_item != null) { if (editing_item != null) {
if (editProductInfo(editing_item)) { if (editProductInfo(editing_item)) {
clearLineEdition(); clearLineEdition();
...@@ -405,10 +411,12 @@ function confirmProcessAllItems() { ...@@ -405,10 +411,12 @@ function confirmProcessAllItems() {
openModal(); openModal();
// Iterate over all rows in table of items to process // Iterate over all rows in table of items to process
table_to_process.rows().every(function (rowIdx, tableLoop, rowLoop) { table_to_process.rows().every(function () {
var data = this.data(); var data = this.data();
editProductInfo(data, 0); editProductInfo(data, 0);
return 1;
}); });
// Reset data // Reset data
...@@ -446,7 +454,6 @@ function send() { ...@@ -446,7 +454,6 @@ function send() {
var url = "../do_" + originView + "_inventory"; var url = "../do_" + originView + "_inventory";
var call_begin_at = new Date().getTime(); var call_begin_at = new Date().getTime();
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({ $.ajax({
type: "PUT", type: "PUT",
url: url, url: url,
...@@ -469,18 +476,19 @@ function send() { ...@@ -469,18 +476,19 @@ function send() {
} }
} }
var msg = (originView == 'shelf') ? 'Retour à la liste des rayons' : 'Retour'; var msg = (originView == 'shelf') ? 'OK, je passe à la suite !' : 'Retour';
openModal(inventory_validated_msg.html(), back, msg, true, false); // Go to step 2 if step 1 is validated and modal closed
openModal(inventory_validated_msg.html(), refresh, msg, true, false);
// Go back to list if modal closed // Go to step 2 if modal is closed
$('#modal_closebtn_top').on('click', back); $('#modal_closebtn_top').on('click', refresh);
$('#modal_closebtn_bottom').on('click', back); $('#modal_closebtn_bottom').on('click', refresh);
// Clear local storage before leaving // Clear local storage before leaving
localStorage.removeItem(originView + '_' + shelf.id); localStorage.removeItem(originView + '_' + shelf.id);
}, },
error: function(jqXHR, textStatus) { // 500 error has been thrown or web server sent a timeout error: function(jqXHR) { // 500 error has been thrown or web server sent a timeout
if (jqXHR.status == 504) { if (jqXHR.status == 504) {
/* /*
django is too long to respond. django is too long to respond.
...@@ -547,6 +555,35 @@ function exit_adding_product() { ...@@ -547,6 +555,35 @@ function exit_adding_product() {
adding_product = false; adding_product = false;
} }
/**
* Set the ongoing inventory start datetime.
* This operation is invisible to the user.
*/
function set_begin_inventory_datetime() {
if (originView === 'shelf' &&
(
shelf.ongoing_inv_start_datetime === default_inventory_start_datetime
|| shelf.ongoing_inv_start_datetime === undefined
)
) {
$.ajax({
type: "POST",
url: "/shelfs/"+shelf.id+"/set_begin_inventory_datetime",
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
shelf.ongoing_inv_start_datetime = data.res.inventory_begin_datetime;
// Update local storage
localStorage.setItem(originView + "_" + shelf.id, JSON.stringify(shelf));
},
error: function() {
console.log("Impossible de mettre à jour la date de début d'inventaire");
}
});
}
}
// Add a product that's not in the list // Add a product that's not in the list
function open_adding_product() { function open_adding_product() {
if (originView == 'shelf') { if (originView == 'shelf') {
...@@ -563,7 +600,6 @@ function do_add_product() { ...@@ -563,7 +600,6 @@ function do_add_product() {
}; };
openModal(); openModal();
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: "../"+shelf.id+"/add_product", url: "../"+shelf.id+"/add_product",
...@@ -571,7 +607,7 @@ function do_add_product() { ...@@ -571,7 +607,7 @@ function do_add_product() {
traditional: true, traditional: true,
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
data: JSON.stringify(prod_data), data: JSON.stringify(prod_data),
success: function(data) { success: function() {
exit_adding_product(); exit_adding_product();
closeModal(); closeModal();
alert('Produit ajouté !'); alert('Produit ajouté !');
...@@ -618,8 +654,6 @@ function saveIssuesReport() { ...@@ -618,8 +654,6 @@ function saveIssuesReport() {
// Get shelf data from server if not in local storage // Get shelf data from server if not in local storage
function get_shelf_data() { function get_shelf_data() {
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
var url = (originView == 'shelf') ? '../' + shelf.id : '../get_custom_list_data?id=' + shelf.id; var url = (originView == 'shelf') ? '../' + shelf.id : '../get_custom_list_data?id=' + shelf.id;
$.ajax({ $.ajax({
...@@ -631,6 +665,7 @@ function get_shelf_data() { ...@@ -631,6 +665,7 @@ function get_shelf_data() {
success: function(data) { success: function(data) {
shelf = data.res; shelf = data.res;
init(); init();
set_begin_inventory_datetime();
}, },
error: function(data) { error: function(data) {
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') { if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
...@@ -646,7 +681,6 @@ function init() { ...@@ -646,7 +681,6 @@ function init() {
// Products passed at page loading // Products passed at page loading
// TODO: get products by ajax for better ui experience (? -> warning js at loading) // TODO: get products by ajax for better ui experience (? -> warning js at loading)
// TODO : What happens if products are being put or removed from the self before the end of the inventory ? // TODO : What happens if products are being put or removed from the self before the end of the inventory ?
//console.log(shelf)
list_to_process = products; list_to_process = products;
initLists(); initLists();
...@@ -703,7 +737,7 @@ function init() { ...@@ -703,7 +737,7 @@ function init() {
$(document).on('click', 'button#add_product_to_shelf', open_adding_product); $(document).on('click', 'button#add_product_to_shelf', open_adding_product);
$(document).on('click', 'button#open_issues_report', openIssuesReport); $(document).on('click', 'button#open_issues_report', openIssuesReport);
$(document).on('click', 'button#open_faq', openFAQ); $(document).on('click', 'button#open_faq', openFAQ);
$(document).on('click', 'button#process_all_items', function (e) { $(document).on('click', 'button#process_all_items', function () {
openModal(process_all_items_msg.html(), confirmProcessAllItems, 'Confirmer', false); openModal(process_all_items_msg.html(), confirmProcessAllItems, 'Confirmer', false);
}); });
...@@ -720,7 +754,7 @@ function init() { ...@@ -720,7 +754,7 @@ function init() {
handle_blinking_effect(container_edition); handle_blinking_effect(container_edition);
// Disable mousewheel on an input number field when in focus // Disable mousewheel on an input number field when in focus
$('#edition_input').on('focus', function (e) { $('#edition_input').on('focus', function () {
$(this).on('wheel.disableScroll', function (e) { $(this).on('wheel.disableScroll', function (e) {
e.preventDefault(); e.preventDefault();
/* /*
...@@ -733,7 +767,7 @@ function init() { ...@@ -733,7 +767,7 @@ function init() {
*/ */
}); });
}) })
.on('blur', function (e) { .on('blur', function () {
$(this).off('wheel.disableScroll'); $(this).off('wheel.disableScroll');
}); });
...@@ -815,6 +849,8 @@ function init() { ...@@ -815,6 +849,8 @@ function init() {
$(document).ready(function() { $(document).ready(function() {
// Get Route parameter // Get Route parameter
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
var pathArray = window.location.pathname.split('/'); var pathArray = window.location.pathname.split('/');
shelf = {id: pathArray[pathArray.length-1]}; shelf = {id: pathArray[pathArray.length-1]};
...@@ -834,7 +870,9 @@ $(document).ready(function() { ...@@ -834,7 +870,9 @@ $(document).ready(function() {
if (stored_shelf != null) { if (stored_shelf != null) {
shelf = stored_shelf; shelf = stored_shelf;
init(); init();
set_begin_inventory_datetime();
} else { } else {
// Get shelf info if not coming from shelves list // Get shelf info if not coming from shelves list
get_shelf_data(); get_shelf_data();
......
...@@ -6,8 +6,8 @@ Informations affichées : ...@@ -6,8 +6,8 @@ Informations affichées :
*/ */
var parent_location = '/shelfs', var parent_location = '/shelfs',
shelf, shelf = null,
table_products, table_products = null,
search_chars = []; search_chars = [];
/* UTILS */ /* UTILS */
...@@ -54,7 +54,7 @@ function initList() { ...@@ -54,7 +54,7 @@ function initList() {
title:"Delta (dernier inv.)", title:"Delta (dernier inv.)",
width: "10%", width: "10%",
className:"dt-body-center", className:"dt-body-center",
render: function (data, type, full, meta) { render: function (data, type) {
if (type == "sort" || type == 'type') if (type == "sort" || type == 'type')
return data; return data;
...@@ -70,7 +70,7 @@ function initList() { ...@@ -70,7 +70,7 @@ function initList() {
title:"Pertes (dernier inv.)", title:"Pertes (dernier inv.)",
width: "10%", width: "10%",
className:"dt-body-center", className:"dt-body-center",
render: function (data, type, full, meta) { render: function (data, type) {
if (type == "sort" || type == 'type') if (type == "sort" || type == 'type')
return data; return data;
......
...@@ -137,6 +137,8 @@ var update_shelf = function() { ...@@ -137,6 +137,8 @@ var update_shelf = function() {
rData.res.p_nb = data.p_nb; rData.res.p_nb = data.p_nb;
this.data(rData.res).draw(); this.data(rData.res).draw();
} }
return 1;
}); });
closeModal(); closeModal();
} else alert(rData.res.error); } else alert(rData.res.error);
...@@ -203,12 +205,6 @@ var downloadInventoryReport = function() { ...@@ -203,12 +205,6 @@ var downloadInventoryReport = function() {
} }
}; };
var rowUpdate = function (row, rdata) {
//console.log(row, rdata)
};
// TODO put datatable common methods such as following in a file useable for all modules // TODO put datatable common methods such as following in a file useable for all modules
var rowGetData = function(clicked) { var rowGetData = function(clicked) {
var row = shelfs_table.row(clicked.parents('tr')); var row = shelfs_table.row(clicked.parents('tr'));
...@@ -217,7 +213,7 @@ var rowGetData = function(clicked) { ...@@ -217,7 +213,7 @@ var rowGetData = function(clicked) {
return row.data(); return row.data();
}; };
function coop_init_datatable(params, data, domsel, cols, action_btn) { function coop_init_datatable(params, data, domsel, cols) {
var buttons = []; var buttons = [];
var columns = []; var columns = [];
...@@ -278,10 +274,6 @@ function coop_init_datatable(params, data, domsel, cols, action_btn) { ...@@ -278,10 +274,6 @@ function coop_init_datatable(params, data, domsel, cols, action_btn) {
rowId : "id", rowId : "id",
data : data, data : data,
language: {url : '/static/js/datatables/french.json'}, language: {url : '/static/js/datatables/french.json'},
createdRow: function(row, rdata, index) {
rowUpdate(row, rdata);
},
initComplete: function() { initComplete: function() {
/* /*
if (! coop_is_connected()) if (! coop_is_connected())
...@@ -318,7 +310,7 @@ var init_and_fill_selfs_list = function() { ...@@ -318,7 +310,7 @@ var init_and_fill_selfs_list = function() {
data:"last_inventory_id", data:"last_inventory_id",
title:"Rapport dernier inventaire", title:"Rapport dernier inventaire",
className: "action", className: "action",
render: function (data, type, full, meta) { render: function (data) {
if (typeof data != "undefined" && data != 0) { if (typeof data != "undefined" && data != 0) {
return download_icon; return download_icon;
} else { } else {
......
...@@ -13,11 +13,46 @@ function init_datatable() { ...@@ -13,11 +13,46 @@ function init_datatable() {
className:"dt-body-center" className:"dt-body-center"
}, },
{data:"name", title:"Nom"}, {data:"name", title:"Nom"},
{data:"description", title:"Description", orderable: false}, // {data:"description", title:"Description", orderable: false},
{
data:"ongoing_inv_start_datetime",
title:"Début inventaire en cours",
render: function (data, type) {
// Sort on data, not rendering
if (type == "sort" || type == 'type')
return data;
if (data == '0001-01-01 00:00:00')
return "";
else {
var date = new Date(data);
return `${date.toLocaleDateString('fr-FR')} ${date.toLocaleTimeString('fr-FR')}`;
}
}
},
{
data:"date_last_product_added",
title:"Dernier ajout produit",
render: function (data, type) {
// Sort on data, not rendering
if (type == "sort" || type == 'type')
return data;
if (data == '0001-01-01')
return "";
else {
var date = new Date(data);
return date.toLocaleDateString('fr-FR');
}
}
},
{ {
data:"date_last_inventory", data:"date_last_inventory",
title:"Date dernier inventaire", title:"Dernier inventaire",
render: function (data, type, full, meta) { render: function (data, type) {
// Sort on data, not rendering // Sort on data, not rendering
if (type == "sort" || type == 'type') if (type == "sort" || type == 'type')
return data; return data;
...@@ -36,7 +71,7 @@ function init_datatable() { ...@@ -36,7 +71,7 @@ function init_datatable() {
{ {
data:"shelf_value", data:"shelf_value",
title:"Valeur théorique du rayon", title:"Valeur théorique du rayon",
render: function (data, type, full, meta) { render: function (data, type) {
if (type == "sort" || type == 'type') if (type == "sort" || type == 'type')
return data; return data;
...@@ -51,44 +86,45 @@ function init_datatable() { ...@@ -51,44 +86,45 @@ function init_datatable() {
width: "5%", width: "5%",
className:"dt-body-center" className:"dt-body-center"
}, },
{ /* NOT IN USE */
data:"last_inv_delta_percentage", // {
title:"Delta (dernier inv.)", // data:"last_inv_delta_percentage",
width: "5%", // title:"Delta (dernier inv.)",
className:"dt-body-center", // width: "5%",
render: function (data, type, full, meta) { // className:"dt-body-center",
if (type == "sort" || type == 'type') // render: function (data, type) {
return data; // if (type == "sort" || type == 'type')
// return data;
if (data == -99999999) {
return '/'; // if (data == -99999999) {
} else { // return '/';
return data + ' %'; // } else {
} // return data + ' %';
} // }
}, // }
{ // },
data:"last_inv_losses_percentage", // {
title:"Pertes (dernier inv.)", // data:"last_inv_losses_percentage",
width: "5%", // title:"Pertes (dernier inv.)",
className:"dt-body-center", // width: "5%",
render: function (data, type, full, meta) { // className:"dt-body-center",
if (type == "sort" || type == 'type') // render: function (data, type) {
return data; // if (type == "sort" || type == 'type')
// return data;
if (data == -99999999) {
return '/'; // if (data == -99999999) {
} else { // return '/';
return data + ' %'; // } else {
} // return data + ' %';
} // }
}, // }
// },
{ {
data:"inventory_status", data:"inventory_status",
title:"Inventaire à faire", title:"Inventaire à faire",
className:"dt-body-center", className:"dt-body-center",
width: "15%", width: "15%",
render: function (data, type, full, meta) { render: function (data) {
if (data == '') if (data == '')
return "<button class='btn--primary do_shelf_inventory'>Inventaire en rayon</button>"; return "<button class='btn--primary do_shelf_inventory'>Inventaire en rayon</button>";
else else
...@@ -144,11 +180,13 @@ function get_shelfs_extra_data() { ...@@ -144,11 +180,13 @@ function get_shelfs_extra_data() {
} }
function set_null_to_extra_data() { function set_null_to_extra_data() {
shelfs_table.rows().every(function (rowIdx, tableLoop, rowLoop) { shelfs_table.rows().every(function () {
var d = this.data(); var d = this.data();
d.shelf_value = -2; d.shelf_value = -2;
this.invalidate(); // invalidate the data DataTables has cached for this row this.invalidate(); // invalidate the data DataTables has cached for this row
return 1;
}); });
shelfs_table.draw(); shelfs_table.draw();
...@@ -157,7 +195,6 @@ function set_null_to_extra_data() { ...@@ -157,7 +195,6 @@ function set_null_to_extra_data() {
var getRowData = function(clicked) { var getRowData = function(clicked) {
var row = shelfs_table.row(clicked.parents('tr')); var row = shelfs_table.row(clicked.parents('tr'));
return row.data(); return row.data();
}; };
......
...@@ -17,7 +17,7 @@ function init_datatable() { ...@@ -17,7 +17,7 @@ function init_datatable() {
{ {
data:"date_last_inventory", data:"date_last_inventory",
title:"Date dernier inventaire", title:"Date dernier inventaire",
render: function (data, type, full, meta) { render: function (data, type) {
// Sort on data, not rendering // Sort on data, not rendering
if (type == "sort" || type == 'type') if (type == "sort" || type == 'type')
return data; return data;
...@@ -37,7 +37,7 @@ function init_datatable() { ...@@ -37,7 +37,7 @@ function init_datatable() {
title:"", title:"",
className:"dt-body-center", className:"dt-body-center",
width: "15%", width: "15%",
render: function (data, type, full, meta) { render: function () {
return "<button class='btn--success do_export_sales_data'>Export Ventes</button>"; return "<button class='btn--success do_export_sales_data'>Export Ventes</button>";
} }
} }
......
...@@ -14,6 +14,7 @@ urlpatterns = [ ...@@ -14,6 +14,7 @@ urlpatterns = [
url(r'^(?P<shelf_id>\d+)$', views.shelf_data), url(r'^(?P<shelf_id>\d+)$', views.shelf_data),
url(r'^(?P<shelf_id>\d+)/products$', views.products), url(r'^(?P<shelf_id>\d+)/products$', views.products),
url(r'^(?P<shelf_id>\d+)/add_product$', views.add_product), url(r'^(?P<shelf_id>\d+)/add_product$', views.add_product),
url(r'^(?P<shelf_id>\d+)/set_begin_inventory_datetime$', views.set_begin_inventory_datetime),
url(r'^do_shelf_inventory$', views.do_shelf_inventory), url(r'^do_shelf_inventory$', views.do_shelf_inventory),
url(r'^(?P<shelf_id>\d+)/last_inventory_report$', views.get_last_inventory_report), url(r'^(?P<shelf_id>\d+)/last_inventory_report$', views.get_last_inventory_report),
url(r'^shelf_inventory_FAQ', views.shelf_inventory_FAQ), url(r'^shelf_inventory_FAQ', views.shelf_inventory_FAQ),
......
...@@ -61,6 +61,15 @@ def shelf_data(request, shelf_id): ...@@ -61,6 +61,15 @@ def shelf_data(request, shelf_id):
else: else:
return JsonResponse({'res': shelf}) return JsonResponse({'res': shelf})
def set_begin_inventory_datetime(request, shelf_id):
""" Set the ongoing inventory start datetime. Set it to now. """
res = Shelf(shelf_id).set_begin_inventory_datetime()
if 'error' in res:
return JsonResponse(res, status=500)
else:
return JsonResponse({'res': res})
def all(request): def all(request):
"""Get all shelves data""" """Get all shelves data"""
......
...@@ -112,14 +112,14 @@ ...@@ -112,14 +112,14 @@
</div> </div>
<div id="validation_msg"> <div id="validation_msg">
<h3>Attention !</h3> <h3>Attention !</h3>
<p>Vous vous apprêtez valider le comptage des produits<span class="validation_msg_step2" style="display:none;"> en réserve</span> de ce rayon.</p> <p>Vous vous apprêtez à valider le comptage des produits<span class="validation_msg_step2" style="display:none;"> en réserve</span> de ce rayon.</p>
<p class="validation_msg_step2" style="display:none;"><i>Cette opération pourra pendre un peu de temps. (ex: 5min pour 120 produits)</i><br/><br/></p> <p class="validation_msg_step2" style="display:none;"><i>Cette opération pourra pendre un peu de temps. (ex: 5min pour 120 produits)</i><br/><br/></p>
<p>Êtez-vous sûr ?</p> <p>Êtez-vous sûr ?</p>
<hr /> <hr />
</div> </div>
<div id="inventory_validated"> <div id="inventory_validated">
<div class="txtcenter"> <div class="txtcenter">
<h3>Bravo, l'inventaire de ce rayon est terminé !</h3> <h3>Bravo, la première partie de l'inventaire de ce rayon est terminé !</h3>
<div id="products_missed_container" style="display:none;"> <div id="products_missed_container" style="display:none;">
<br /> <br />
<h4>Attention, les produits suivants n'ont pas pu être inventoriés : </h4> <h4>Attention, les produits suivants n'ont pas pu être inventoriés : </h4>
...@@ -130,7 +130,8 @@ ...@@ -130,7 +130,8 @@
</div> </div>
<div id="step1_validated" style="display:none;"> <div id="step1_validated" style="display:none;">
<br/> <br/>
<p>Vous pouvez continuer l'inventaire en allant comptabiliser les produits en réserve, si ce n'est pas déjà fait.</p> <p><strong>Vous allez maintenent passer à l'inventaire en réserve.</strong></p>
<p>Si vous avez un doute sur ce qu'est l'inventaire en réserve, la présence de stock ou non, demandez au.à la salarié.e responsable.</p>
</div> </div>
</div> </div>
<hr /> <hr />
......
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