Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
third-party
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cooperatic-foodcoops
third-party
Commits
67d289d4
Commit
67d289d4
authored
May 05, 2022
by
Damien Moulard
Browse files
Options
Browse Files
Download
Plain Diff
fix merge conflict
parents
4ee73655
e5f44f2b
Pipeline
#2181
passed with stage
in 1 minute 28 seconds
Changes
14
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
256 additions
and
123 deletions
+256
-123
config.md
outils/config.md
+4
-0
reception_style.css
reception/static/css/reception_style.css
+11
-1
reception_index.js
reception/static/js/reception_index.js
+1
-3
reception_produits.js
reception/static/js/reception_produits.js
+57
-32
admin.py
shelfs/admin.py
+5
-1
models.py
shelfs/models.py
+15
-1
shelf_inventory.js
shelfs/static/js/shelf_inventory.js
+63
-25
shelf_view.js
shelfs/static/js/shelf_view.js
+4
-4
shelfs_admin.js
shelfs/static/js/shelfs_admin.js
+4
-12
shelfs_index.js
shelfs/static/js/shelfs_index.js
+76
-39
shelfs_sales.js
shelfs/static/js/shelfs_sales.js
+2
-2
urls.py
shelfs/urls.py
+1
-0
views.py
shelfs/views.py
+9
-0
shelf_inventory.html
templates/shelfs/shelf_inventory.html
+4
-3
No files found.
outils/config.md
View file @
67d289d4
...
...
@@ -355,6 +355,10 @@
-
RECEPTION_SHELF_LABEL_PRINT = True
-
DISPLAY_COL_AUTRES = True
Display "Autres" column (showing select with action "rupture fournisseur")
-
COEFF_MAG_ID = 1
DB coeff id, needed to compute product shelf price
...
...
reception/static/css/reception_style.css
View file @
67d289d4
...
...
@@ -188,6 +188,11 @@ div#container_edition {
padding-bottom
:
15px
;
}
.title_partner_key
{
font-weight
:
bolder
;
font-size
:
2rem
;
}
/* Accordion style */
/* Style the buttons that are used to open and close the accordion panel */
...
...
@@ -247,5 +252,9 @@ hr {
#main_content
{
width
:
100%
;}
.select_product_action
{
max-width
:
15px
;
max-width
:
5px
;
}
.toProcess_line_edit
,
.toProcess_line_valid
{
min-width
:
11px
;
}
\ No newline at end of file
reception/static/js/reception_index.js
View file @
67d289d4
...
...
@@ -365,9 +365,7 @@ function display_orders_table() {
table_orders
.
clear
().
destroy
();
$
(
'#orders'
).
empty
();
}
for
(
let
j
in
orders
)
{
console
.
log
(
orders
[
j
].
id
);
}
table_orders
=
$
(
'#orders'
).
DataTable
({
data
:
orders
,
columns
:[
...
...
reception/static/js/reception_produits.js
View file @
67d289d4
...
...
@@ -282,6 +282,11 @@ function fetch_data() {
}
}
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
list_to_process
.
push
(
order_data
.
po
[
i
]);
...
...
@@ -310,7 +315,7 @@ function fetch_data() {
// Init Data & listeners
function
initLists
()
{
try
{
//
Un-dis
able validation buttons now the data's here
//
En
able validation buttons now the data's here
if
(
reception_status
==
"False"
)
{
document
.
getElementById
(
"valid_qty"
).
disabled
=
false
;
document
.
getElementById
(
"valid_all_qties"
).
disabled
=
false
;
...
...
@@ -344,10 +349,18 @@ function initLists() {
}
}
// Init table for to_process content
table_to_process
=
$
(
'#table_to_process'
).
DataTable
({
data
:
list_to_process
,
columns
:[
let
columns_to_process
=
[];
let
columns_processed
=
[];
// In case of group orders, add "Order" as first column for ordering
if
(
Object
.
keys
(
orders
).
length
>
1
)
{
columns_to_process
.
push
({
data
:
"order_key"
,
title
:
"n°"
,
className
:
"dt-body-center"
,
width
:
"20px"
});
}
columns_to_process
=
columns_to_process
.
concat
([
{
data
:
"product_id.0"
,
title
:
"id"
,
visible
:
false
},
{
data
:
"shelf_sortorder"
,
title
:
"Rayon"
,
className
:
"dt-body-center"
},
{
...
...
@@ -382,41 +395,26 @@ function initLists() {
},
{
title
:
"Editer"
,
defaultContent
:
"<a class='btn' id='
toProcess_line_edit' href='#'><i class='far fa-edit'></i></a>"
,
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' id='
toProcess_line_valid' href='#'><i class='far fa-check-square'></i></a>"
,
defaultContent
:
"<a class='btn
toProcess_line_valid' href='#'><i class='far fa-check-square'></i></a>"
,
className
:
"dt-body-center"
,
orderable
:
false
},
{
title
:
"Autres
"
,
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"
}
],
rowId
:
"product_id.0"
,
order
:
[
[
0
,
"asc"
]
],
scrollY
:
"33vh"
,
scrollCollapse
:
true
,
paging
:
false
,
dom
:
'lrtip'
,
// Remove the search input from that table
language
:
{
url
:
'/static/js/datatables/french.json'
}
});
// Init table for processed content
table_processed
=
$
(
'#table_processed'
).
DataTable
({
data
:
list_processed
,
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"
},
{
...
...
@@ -487,7 +485,33 @@ function initLists() {
+
"</select>"
;
}
}
];
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"
,
order
:
[
[
0
,
"asc"
]
],
scrollY
:
"33vh"
,
scrollCollapse
:
true
,
paging
:
false
,
dom
:
'lrtip'
,
// Remove the search input from that table
language
:
{
url
:
'/static/js/datatables/french.json'
}
});
// Init table for processed content
table_processed
=
$
(
'#table_processed'
).
DataTable
({
data
:
list_processed
,
columns
:
columns_processed
,
rowId
:
"product_id.0"
,
order
:
[
[
...
...
@@ -509,7 +533,7 @@ function initLists() {
/* Listeners */
// 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
))
{
try
{
let
row
=
table_to_process
.
row
(
$
(
this
).
parents
(
'tr'
));
...
...
@@ -542,7 +566,7 @@ function initLists() {
});
// 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
{
// Prevent editing mutiple lines at a time
if
(
editing_product
==
null
)
{
...
...
@@ -1657,7 +1681,7 @@ function init_dom(partners_display_data) {
};
}
dbc
.
bulkDocs
(
Object
.
values
(
orders
)).
then
((
response
)
=>
{
dbc
.
bulkDocs
(
Object
.
values
(
orders
)).
then
(()
=>
{
back
();
})
.
catch
((
err
)
=>
{
...
...
@@ -1964,12 +1988,13 @@ $(document).ready(function() {
include_docs
:
true
}).
then
(
function
(
result
)
{
// for each order in the group
for
(
let
order_id
of
group_ids
)
{
for
(
let
i
in
group_ids
)
{
// find order
let
order_id
=
group_ids
[
i
];
let
order
=
result
.
rows
.
find
(
el
=>
el
.
id
==
'order_'
+
order_id
);
order
=
order
.
doc
;
order
.
key
=
parseInt
(
i
)
+
1
;
orders
[
order_id
]
=
order
;
// Add each order's already updated and validated products to common list
...
...
@@ -1982,7 +2007,7 @@ $(document).ready(function() {
}
// 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
...
...
shelfs/admin.py
View file @
67d289d4
...
...
@@ -58,7 +58,11 @@ def add_products(request):
try
:
id
=
int
(
request
.
POST
.
get
(
'shelf_id'
))
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
:
result
[
'error'
]
=
str
(
e
)
else
:
...
...
shelfs/models.py
View file @
67d289d4
...
...
@@ -6,7 +6,7 @@ from products.models import CagetteProducts
from
inventory.models
import
CagetteInventory
import
os
from
datetime
import
date
from
datetime
import
date
,
datetime
from
openpyxl
import
Workbook
from
openpyxl.styles
import
Alignment
,
Font
from
statistics
import
*
...
...
@@ -14,6 +14,7 @@ from statistics import *
# Prefix for temp shelf inventory files
tmp_inv_file_prefix
=
'temp/inventory_shelf_'
default_inventory_start_datetime
=
"0001-01-01 00:00:00"
def
as_text
(
value
):
""" Utils """
...
...
@@ -106,6 +107,7 @@ class Shelf(models.Model):
# Inventory all done
f
[
'inventory_status'
]
=
''
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
:
f
[
'last_inventory_id'
]
=
params
[
'last_inventory_id'
]
...
...
@@ -180,6 +182,18 @@ class Shelf(models.Model):
res
[
'error'
]
=
"L'enregistrement n'a pas pu se réaliser"
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
):
"""Save inventory data in a json temp file"""
...
...
shelfs/static/js/shelf_inventory.js
View file @
67d289d4
...
...
@@ -12,21 +12,23 @@ var validation_msg = $('#validation_msg'),
process_all_items_msg
=
$
(
'#process_all_items_msg'
),
faq_content
=
$
(
"#FAQ_modal_content"
),
issues_reporting
=
$
(
"#issues_reporting"
),
add_product_form
=
$
(
"#add_product_form"
),
add_product_input
=
$
(
"#add_product_input"
);
add_product_form
=
$
(
"#add_product_form"
);
var
shelf
,
var
shelf
=
null
,
parent_location
=
'/shelfs'
,
originView
=
"shelf"
,
// or custom_list (create from order view)
list_to_process
=
[],
table_to_process
,
table_processed
,
table_to_process
=
null
,
table_processed
=
null
,
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
search_chars
=
[],
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 */
...
...
@@ -48,6 +50,10 @@ function back() {
document
.
location
.
href
=
parent_location
;
}
function
refresh
()
{
location
.
reload
();
}
// Directly send a line to edition when barcode is read
function
select_product_from_bc
(
barcode
)
{
if
(
editing_item
==
null
)
{
...
...
@@ -95,7 +101,7 @@ function handle_blinking_effect(element) {
element
.
addEventListener
(
'animationend'
,
onAnimationEnd
);
element
.
addEventListener
(
'webkitAnimationEnd'
,
onAnimationEnd
);
function
onAnimationEnd
(
e
)
{
function
onAnimationEnd
()
{
element
.
classList
.
remove
(
'blink_me'
);
}
}
...
...
@@ -169,7 +175,7 @@ function clearLineEdition() {
}
// Validate product edition
function
validateEdition
(
form
)
{
function
validateEdition
()
{
if
(
editing_item
!=
null
)
{
if
(
editProductInfo
(
editing_item
))
{
clearLineEdition
();
...
...
@@ -405,10 +411,12 @@ function confirmProcessAllItems() {
openModal
();
// 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
();
editProductInfo
(
data
,
0
);
return
1
;
});
// Reset data
...
...
@@ -446,7 +454,6 @@ function send() {
var
url
=
"../do_"
+
originView
+
"_inventory"
;
var
call_begin_at
=
new
Date
().
getTime
();
$
.
ajaxSetup
({
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)
}
});
$
.
ajax
({
type
:
"PUT"
,
url
:
url
,
...
...
@@ -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
$
(
'#modal_closebtn_top'
).
on
(
'click'
,
back
);
$
(
'#modal_closebtn_bottom'
).
on
(
'click'
,
back
);
// Go
to step 2 if modal is
closed
$
(
'#modal_closebtn_top'
).
on
(
'click'
,
refresh
);
$
(
'#modal_closebtn_bottom'
).
on
(
'click'
,
refresh
);
// Clear local storage before leaving
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
)
{
/*
django is too long to respond.
...
...
@@ -547,6 +555,35 @@ function exit_adding_product() {
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
function
open_adding_product
()
{
if
(
originView
==
'shelf'
)
{
...
...
@@ -563,7 +600,6 @@ function do_add_product() {
};
openModal
();
$
.
ajaxSetup
({
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)
}
});
$
.
ajax
({
type
:
"POST"
,
url
:
"../"
+
shelf
.
id
+
"/add_product"
,
...
...
@@ -571,7 +607,7 @@ function do_add_product() {
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
data
:
JSON
.
stringify
(
prod_data
),
success
:
function
(
data
)
{
success
:
function
()
{
exit_adding_product
();
closeModal
();
alert
(
'Produit ajouté !'
);
...
...
@@ -618,8 +654,6 @@ function saveIssuesReport() {
// Get shelf data from server if not in local storage
function
get_shelf_data
()
{
$
.
ajaxSetup
({
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)
}
});
var
url
=
(
originView
==
'shelf'
)
?
'../'
+
shelf
.
id
:
'../get_custom_list_data?id='
+
shelf
.
id
;
$
.
ajax
({
...
...
@@ -631,6 +665,7 @@ function get_shelf_data() {
success
:
function
(
data
)
{
shelf
=
data
.
res
;
init
();
set_begin_inventory_datetime
();
},
error
:
function
(
data
)
{
if
(
typeof
data
.
responseJSON
!=
'undefined'
&&
typeof
data
.
responseJSON
.
error
!=
'undefined'
)
{
...
...
@@ -646,7 +681,6 @@ function init() {
// Products passed at page 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 ?
//console.log(shelf)
list_to_process
=
products
;
initLists
();
...
...
@@ -703,7 +737,7 @@ function init() {
$
(
document
).
on
(
'click'
,
'button#add_product_to_shelf'
,
open_adding_product
);
$
(
document
).
on
(
'click'
,
'button#open_issues_report'
,
openIssuesReport
);
$
(
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
);
});
...
...
@@ -720,7 +754,7 @@ function init() {
handle_blinking_effect
(
container_edition
);
// 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
)
{
e
.
preventDefault
();
/*
...
...
@@ -733,7 +767,7 @@ function init() {
*/
});
})
.
on
(
'blur'
,
function
(
e
)
{
.
on
(
'blur'
,
function
()
{
$
(
this
).
off
(
'wheel.disableScroll'
);
});
...
...
@@ -815,6 +849,8 @@ function init() {
$
(
document
).
ready
(
function
()
{
// Get Route parameter
$
.
ajaxSetup
({
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)
}
});
var
pathArray
=
window
.
location
.
pathname
.
split
(
'/'
);
shelf
=
{
id
:
pathArray
[
pathArray
.
length
-
1
]};
...
...
@@ -834,7 +870,9 @@ $(document).ready(function() {
if
(
stored_shelf
!=
null
)
{
shelf
=
stored_shelf
;
init
();
set_begin_inventory_datetime
();
}
else
{
// Get shelf info if not coming from shelves list
get_shelf_data
();
...
...
shelfs/static/js/shelf_view.js
View file @
67d289d4
...
...
@@ -6,8 +6,8 @@ Informations affichées :
*/
var
parent_location
=
'/shelfs'
,
shelf
,
table_products
,
shelf
=
null
,
table_products
=
null
,
search_chars
=
[];
/* UTILS */
...
...
@@ -54,7 +54,7 @@ function initList() {
title
:
"Delta (dernier inv.)"
,
width
:
"10%"
,
className
:
"dt-body-center"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
render
:
function
(
data
,
type
)
{
if
(
type
==
"sort"
||
type
==
'type'
)
return
data
;
...
...
@@ -70,7 +70,7 @@ function initList() {
title
:
"Pertes (dernier inv.)"
,
width
:
"10%"
,
className
:
"dt-body-center"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
render
:
function
(
data
,
type
)
{
if
(
type
==
"sort"
||
type
==
'type'
)
return
data
;
...
...
shelfs/static/js/shelfs_admin.js
View file @
67d289d4
...
...
@@ -137,6 +137,8 @@ var update_shelf = function() {
rData
.
res
.
p_nb
=
data
.
p_nb
;
this
.
data
(
rData
.
res
).
draw
();
}
return
1
;
});
closeModal
();
}
else
alert
(
rData
.
res
.
error
);
...
...
@@ -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
var
rowGetData
=
function
(
clicked
)
{
var
row
=
shelfs_table
.
row
(
clicked
.
parents
(
'tr'
));
...
...
@@ -217,7 +213,7 @@ var rowGetData = function(clicked) {
return
row
.
data
();
};
function
coop_init_datatable
(
params
,
data
,
domsel
,
cols
,
action_btn
)
{
function
coop_init_datatable
(
params
,
data
,
domsel
,
cols
)
{
var
buttons
=
[];
var
columns
=
[];
...
...
@@ -278,10 +274,6 @@ function coop_init_datatable(params, data, domsel, cols, action_btn) {
rowId
:
"id"
,
data
:
data
,
language
:
{
url
:
'/static/js/datatables/french.json'
},
createdRow
:
function
(
row
,
rdata
,
index
)
{
rowUpdate
(
row
,
rdata
);
},
initComplete
:
function
()
{
/*
if (! coop_is_connected())
...
...
@@ -318,7 +310,7 @@ var init_and_fill_selfs_list = function() {
data
:
"last_inventory_id"
,
title
:
"Rapport dernier inventaire"
,
className
:
"action"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
render
:
function
(
data
)
{
if
(
typeof
data
!=
"undefined"
&&
data
!=
0
)
{
return
download_icon
;
}
else
{
...
...
shelfs/static/js/shelfs_index.js
View file @
67d289d4
...
...
@@ -13,11 +13,46 @@ function init_datatable() {
className
:
"dt-body-center"
},
{
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"
,
title
:
"D
ate d
ernier inventaire"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
title
:
"Dernier inventaire"
,
render
:
function
(
data
,
type
)
{
// Sort on data, not rendering
if
(
type
==
"sort"
||
type
==
'type'
)
return
data
;
...
...
@@ -36,7 +71,7 @@ function init_datatable() {
{
data
:
"shelf_value"
,
title
:
"Valeur théorique du rayon"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
render
:
function
(
data
,
type
)
{
if
(
type
==
"sort"
||
type
==
'type'
)
return
data
;
...
...
@@ -51,44 +86,45 @@ function init_datatable() {
width
:
"5%"
,
className
:
"dt-body-center"
},
{
data
:
"last_inv_delta_percentage"
,
title
:
"Delta (dernier inv.)"
,
width
:
"5%"
,
className
:
"dt-body-center"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
if
(
type
==
"sort"
||
type
==
'type'
)
return
data
;
if
(
data
==
-
99999999
)
{
return
'/'
;
}
else
{
return
data
+
' %'
;
}
}
},
{
data
:
"last_inv_losses_percentage"
,
title
:
"Pertes (dernier inv.)"
,
width
:
"5%"
,
className
:
"dt-body-center"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
if
(
type
==
"sort"
||
type
==
'type'
)
return
data
;
if
(
data
==
-
99999999
)
{
return
'/'
;
}
else
{
return
data
+
' %'
;
}
}
},
/* NOT IN USE */
// {
// data:"last_inv_delta_percentage",
// title:"Delta (dernier inv.)",
// width: "5%",
// className:"dt-body-center",
// render: function (data, type) {
// if (type == "sort" || type == 'type')
// return data;
// if (data == -99999999) {
// return '/';
// } else {
// return data + ' %';
// }
// }
// },
// {
// data:"last_inv_losses_percentage",
// title:"Pertes (dernier inv.)",
// width: "5%",
// className:"dt-body-center",
// render: function (data, type) {
// if (type == "sort" || type == 'type')
// return data;
// if (data == -99999999) {
// return '/';
// } else {
// return data + ' %';
// }
// }
// },
{
data
:
"inventory_status"
,
title
:
"Inventaire à faire"
,
className
:
"dt-body-center"
,
width
:
"15%"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
render
:
function
(
data
)
{
if
(
data
==
''
)
return
"<button class='btn--primary do_shelf_inventory'>Inventaire en rayon</button>"
;
else
...
...
@@ -144,11 +180,13 @@ function get_shelfs_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
();
d
.
shelf_value
=
-
2
;
this
.
invalidate
();
// invalidate the data DataTables has cached for this row
return
1
;
});
shelfs_table
.
draw
();
...
...
@@ -157,7 +195,6 @@ function set_null_to_extra_data() {
var
getRowData
=
function
(
clicked
)
{
var
row
=
shelfs_table
.
row
(
clicked
.
parents
(
'tr'
));
return
row
.
data
();
};
...
...
shelfs/static/js/shelfs_sales.js
View file @
67d289d4
...
...
@@ -17,7 +17,7 @@ function init_datatable() {
{
data
:
"date_last_inventory"
,
title
:
"Date dernier inventaire"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
render
:
function
(
data
,
type
)
{
// Sort on data, not rendering
if
(
type
==
"sort"
||
type
==
'type'
)
return
data
;
...
...
@@ -37,7 +37,7 @@ function init_datatable() {
title
:
""
,
className
:
"dt-body-center"
,
width
:
"15%"
,
render
:
function
(
data
,
type
,
full
,
meta
)
{
render
:
function
()
{
return
"<button class='btn--success do_export_sales_data'>Export Ventes</button>"
;
}
}
...
...
shelfs/urls.py
View file @
67d289d4
...
...
@@ -14,6 +14,7 @@ urlpatterns = [
url
(
r'^(?P<shelf_id>\d+)$'
,
views
.
shelf_data
),
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+)/set_begin_inventory_datetime$'
,
views
.
set_begin_inventory_datetime
),
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'^shelf_inventory_FAQ'
,
views
.
shelf_inventory_FAQ
),
...
...
shelfs/views.py
View file @
67d289d4
...
...
@@ -61,6 +61,15 @@ def shelf_data(request, shelf_id):
else
:
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
):
"""Get all shelves data"""
...
...
templates/shelfs/shelf_inventory.html
View file @
67d289d4
...
...
@@ -112,14 +112,14 @@
</div>
<div
id=
"validation_msg"
>
<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>
Êtez-vous sûr ?
</p>
<hr
/>
</div>
<div
id=
"inventory_validated"
>
<div
class=
"txtcenter"
>
<h3>
Bravo, l'inventaire de ce rayon est terminé !
</h3>
<h3>
Bravo, l
a première partie de l
'inventaire de ce rayon est terminé !
</h3>
<div
id=
"products_missed_container"
style=
"display:none;"
>
<br
/>
<h4>
Attention, les produits suivants n'ont pas pu être inventoriés :
</h4>
...
...
@@ -130,7 +130,8 @@
</div>
<div
id=
"step1_validated"
style=
"display:none;"
>
<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>
<hr
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment