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
1eecca46
Commit
1eecca46
authored
May 04, 2022
by
François C.
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev_cooperatic' into '3001-display-last-product-added-date'
# Conflicts: # shelfs/models.py
parents
e0b4c3d8
b400240d
Pipeline
#2172
passed with stage
in 1 minute 28 seconds
Changes
9
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
152 additions
and
91 deletions
+152
-91
models.py
shelfs/models.py
+7
-5
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
-13
shelfs_index.js
shelfs/static/js/shelfs_index.js
+58
-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.
shelfs/models.py
View file @
1eecca46
...
...
@@ -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,19 +182,19 @@ class Shelf(models.Model):
res
[
'error'
]
=
"L'enregistrement n'a pas pu se réaliser"
return
res
def
update_last_product_added_dat
e
(
self
):
def
set_begin_inventory_datetim
e
(
self
):
res
=
{}
today
=
date
.
today
()
.
strftime
(
"
%
Y-
%
m-
%
d"
)
f
=
{
'
date_last_product_added'
:
today
}
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"""
res
=
{}
...
...
shelfs/static/js/shelf_inventory.js
View file @
1eecca46
...
...
@@ -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 @
1eecca46
...
...
@@ -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 @
1eecca46
...
...
@@ -6,7 +6,6 @@ var main_content = $('#main-content'),
shelf_sort_order
=
create_form
.
find
(
'input[name="sort_order"]'
),
shelf_name
=
create_form
.
find
(
'input[name="name"]'
),
description
=
create_form
.
find
(
'textarea[name="description"]'
),
eye
=
'<i class="fas fa-eye"></i>'
,
delete_icon
=
'<i class="fas fa-trash"></i>'
,
add_icon
=
'<i class="fas fa-plus-circle"></i>'
,
edit_icon
=
'<i class="fas fa-edit"></i>'
,
...
...
@@ -136,6 +135,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
);
...
...
@@ -202,12 +203,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'
));
...
...
@@ -216,7 +211,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
=
[];
...
...
@@ -277,10 +272,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())
...
...
@@ -317,7 +308,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 @
1eecca46
...
...
@@ -13,7 +13,24 @@ 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"
,
...
...
@@ -34,8 +51,8 @@ function init_datatable() {
},
{
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
;
...
...
@@ -54,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
;
...
...
@@ -69,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
...
...
@@ -162,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
();
...
...
@@ -175,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 @
1eecca46
...
...
@@ -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 @
1eecca46
...
...
@@ -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 @
1eecca46
...
...
@@ -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 @
1eecca46
...
...
@@ -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