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
f8b23369
Commit
f8b23369
authored
May 23, 2022
by
Damien Moulard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
INV: save UTC time & display according to locale timezone (+ linting)
parent
4f963d49
Pipeline
#2211
passed with stage
in 3 minutes 48 seconds
Changes
4
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
62 additions
and
27 deletions
+62
-27
models.py
shelfs/models.py
+2
-2
shelf_inventory.js
shelfs/static/js/shelf_inventory.js
+46
-19
shelfs_admin.js
shelfs/static/js/shelfs_admin.js
+7
-6
shelfs_index.js
shelfs/static/js/shelfs_index.js
+7
-0
No files found.
shelfs/models.py
View file @
f8b23369
...
@@ -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
,
datetime
from
datetime
import
date
,
datetime
,
timezone
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
*
...
@@ -196,7 +196,7 @@ class Shelf(models.Model):
...
@@ -196,7 +196,7 @@ class Shelf(models.Model):
def
set_begin_inventory_datetime
(
self
):
def
set_begin_inventory_datetime
(
self
):
res
=
{}
res
=
{}
now
=
datetime
.
now
(
)
.
isoformat
()
now
=
datetime
.
now
(
timezone
.
utc
)
.
isoformat
()
# save UTC time
f
=
{
'ongoing_inv_start_datetime'
:
now
}
f
=
{
'ongoing_inv_start_datetime'
:
now
}
try
:
try
:
...
...
shelfs/static/js/shelf_inventory.js
View file @
f8b23369
...
@@ -58,12 +58,13 @@ function back() {
...
@@ -58,12 +58,13 @@ function back() {
function
get_added_qties_sum
(
item
)
{
function
get_added_qties_sum
(
item
)
{
let
total
=
null
;
let
total
=
null
;
function
add
(
accumulator
,
a
)
{
// for array sum
function
add
(
accumulator
,
a
)
{
// for array sum
result
=
0
;
result
=
0
;
if
(
a
)
{
if
(
a
)
{
if
(
item
.
uom_id
[
1
]
==
"kg"
)
{
if
(
item
.
uom_id
[
1
]
==
"kg"
)
{
if
(
typeof
a
===
"string"
)
{
if
(
typeof
a
===
"string"
)
{
a
=
a
.
replace
(
','
,
'.'
)
a
=
a
.
replace
(
','
,
'.'
);
}
}
result
=
parseFloat
(
accumulator
)
+
parseFloat
(
a
);
result
=
parseFloat
(
accumulator
)
+
parseFloat
(
a
);
result
=
result
.
toFixed
(
3
);
result
=
result
.
toFixed
(
3
);
...
@@ -71,6 +72,7 @@ function get_added_qties_sum(item) {
...
@@ -71,6 +72,7 @@ function get_added_qties_sum(item) {
result
=
parseInt
(
accumulator
,
10
)
+
parseInt
(
a
,
10
);
result
=
parseInt
(
accumulator
,
10
)
+
parseInt
(
a
,
10
);
}
}
}
}
return
result
;
return
result
;
}
}
if
(
typeof
item
.
added_qties
!=
"undefined"
&&
item
.
added_qties
.
length
>
0
)
{
if
(
typeof
item
.
added_qties
!=
"undefined"
&&
item
.
added_qties
.
length
>
0
)
{
...
@@ -82,6 +84,7 @@ function get_added_qties_sum(item) {
...
@@ -82,6 +84,7 @@ function get_added_qties_sum(item) {
}
}
function
barcode_analyzer
(
chars
)
{
function
barcode_analyzer
(
chars
)
{
let
barcode
=
chars
;
let
barcode
=
chars
;
if
(
barcode
&&
barcode
.
length
>=
13
)
{
if
(
barcode
&&
barcode
.
length
>=
13
)
{
barcode
=
barcode
.
substring
(
barcode
.
length
-
13
);
barcode
=
barcode
.
substring
(
barcode
.
length
-
13
);
}
else
if
(
barcode
&&
barcode
.
length
==
12
&&
barcode
.
indexOf
(
'0'
)
!==
0
)
{
}
else
if
(
barcode
&&
barcode
.
length
==
12
&&
barcode
.
indexOf
(
'0'
)
!==
0
)
{
...
@@ -125,6 +128,7 @@ function refresh() {
...
@@ -125,6 +128,7 @@ function refresh() {
function
select_product_from_bc
(
barcode
)
{
function
select_product_from_bc
(
barcode
)
{
var
found
=
null
,
var
found
=
null
,
qty
=
null
;
qty
=
null
;
if
(
isValidEAN13
(
barcode
))
{
if
(
isValidEAN13
(
barcode
))
{
var
scannedProduct
=
barcodes
.
get_corresponding_odoo_product
(
barcode
);
var
scannedProduct
=
barcodes
.
get_corresponding_odoo_product
(
barcode
);
...
@@ -155,9 +159,13 @@ function select_product_from_bc(barcode) {
...
@@ -155,9 +159,13 @@ function select_product_from_bc(barcode) {
found
=
e
;
found
=
e
;
if
(
qty
)
{
if
(
qty
)
{
let
message
=
"Attention, ce produit a déjà été compté.
\
n"
;
let
message
=
"Attention, ce produit a déjà été compté.
\
n"
;
message
+=
"La quantité "
+
qty
+
" n'a pas été ajoutée !
\
n"
;
message
+=
"La quantité "
+
qty
+
" n'a pas été ajoutée !
\
n"
;
// temporary add read qty and recorded one to added_qties to compute sum
// temporary add read qty and recorded one to added_qties to compute sum
found
.
added_qties
=
[
qty
,
found
.
qty
]
found
.
added_qties
=
[
qty
,
found
.
qty
];
message
+=
"Le total serait "
+
get_added_qties_sum
(
found
);
message
+=
"Le total serait "
+
get_added_qties_sum
(
found
);
alert
(
message
);
alert
(
message
);
qty
=
null
;
qty
=
null
;
...
@@ -173,17 +181,20 @@ function select_product_from_bc(barcode) {
...
@@ -173,17 +181,20 @@ function select_product_from_bc(barcode) {
setLineEdition
(
found
,
qty
);
setLineEdition
(
found
,
qty
);
if
(
editing_origin
===
'to_process'
)
{
if
(
editing_origin
===
'to_process'
)
{
let
row
=
table_to_process
.
row
(
$
(
'tr#'
+
found
.
id
));
let
row
=
table_to_process
.
row
(
$
(
'tr#'
+
found
.
id
));
remove_from_toProcess
(
row
);
remove_from_toProcess
(
row
);
}
else
{
}
else
{
let
row
=
table_processed
.
row
(
$
(
'tr#'
+
found
.
id
));
let
row
=
table_processed
.
row
(
$
(
'tr#'
+
found
.
id
));
remove_from_processed
(
row
);
remove_from_processed
(
row
);
}
}
}
else
{
}
else
{
console
.
log
(
'Code barre introuvable'
);
console
.
log
(
'Code barre introuvable'
);
}
}
}
else
if
(
barcode
==
editing_item
.
barcode
&&
qty
){
}
else
if
(
barcode
==
editing_item
.
barcode
&&
qty
)
{
// We scan the same product as the current one
// We scan the same product as the current one
let
edition_input
=
$
(
'#edition_input'
);
let
edition_input
=
$
(
'#edition_input'
);
if
(
typeof
editing_item
.
added_qties
==
"undefined"
)
{
if
(
typeof
editing_item
.
added_qties
==
"undefined"
)
{
editing_item
.
added_qties
=
[
edition_input
.
val
()];
editing_item
.
added_qties
=
[
edition_input
.
val
()];
}
}
...
@@ -377,9 +388,10 @@ function record_products_shelf_on_server(data) {
...
@@ -377,9 +388,10 @@ function record_products_shelf_on_server(data) {
// call on change_shelf_btn click action
// call on change_shelf_btn click action
async
function
open_change_shelf_modal
()
{
async
function
open_change_shelf_modal
()
{
selected_products_for_shelf_change
=
[];
selected_products_for_shelf_change
=
[];
$
(
'.select_product_cb:checked'
).
each
(
function
(
idx
,
elt
)
{
$
(
'.select_product_cb:checked'
).
each
(
function
(
idx
,
elt
)
{
const
row
=
$
(
elt
).
closest
(
'tr'
);
const
row
=
$
(
elt
).
closest
(
'tr'
);
selected_products_for_shelf_change
.
push
(
table_to_process
.
row
(
row
).
data
())
selected_products_for_shelf_change
.
push
(
table_to_process
.
row
(
row
).
data
());
});
});
if
(
selected_products_for_shelf_change
.
length
>
0
)
{
if
(
selected_products_for_shelf_change
.
length
>
0
)
{
/*
/*
...
@@ -388,6 +400,7 @@ async function open_change_shelf_modal() {
...
@@ -388,6 +400,7 @@ async function open_change_shelf_modal() {
*/
*/
let
shelfs
=
await
get_all_shelfs
();
let
shelfs
=
await
get_all_shelfs
();
if
(
shelfs
!==
null
)
{
if
(
shelfs
!==
null
)
{
let
modal_content
=
$
(
'#templates #change_shelf_form'
).
clone
(),
let
modal_content
=
$
(
'#templates #change_shelf_form'
).
clone
(),
shelf_selector
=
$
(
'<select>'
).
addClass
(
'shelf_selection'
),
shelf_selector
=
$
(
'<select>'
).
addClass
(
'shelf_selection'
),
...
@@ -395,12 +408,13 @@ async function open_change_shelf_modal() {
...
@@ -395,12 +408,13 @@ async function open_change_shelf_modal() {
/* construct shelfs selector */
/* construct shelfs selector */
// first of all, sort by name
// first of all, sort by name
shelfs
.
sort
((
a
,
b
)
=>
(
a
.
name
>
b
.
name
)
?
1
:
((
b
.
name
>
a
.
name
)
?
-
1
:
0
));
shelfs
.
sort
((
a
,
b
)
=>
(
a
.
name
>
b
.
name
)
?
1
:
((
b
.
name
>
a
.
name
)
?
-
1
:
0
));
// if ahead_shelfs_ids is not empty, put them ahead
// if ahead_shelfs_ids is not empty, put them ahead
if
(
ahead_shelfs_ids
.
length
>
0
)
{
if
(
ahead_shelfs_ids
.
length
>
0
)
{
let
to_move
=
{},
let
to_move
=
{},
idx
=
0
;
idx
=
0
;
// find index of shelfs to move
// find index of shelfs to move
shelfs
.
forEach
((
shelf
)
=>
{
shelfs
.
forEach
((
shelf
)
=>
{
if
(
ahead_shelfs_ids
.
indexOf
(
shelf
.
id
)
>
-
1
)
{
if
(
ahead_shelfs_ids
.
indexOf
(
shelf
.
id
)
>
-
1
)
{
to_move
[
shelf
.
id
]
=
idx
;
to_move
[
shelf
.
id
]
=
idx
;
...
@@ -410,27 +424,30 @@ async function open_change_shelf_modal() {
...
@@ -410,27 +424,30 @@ async function open_change_shelf_modal() {
// Respecting ahead_shelfs_ids order, move shelf ahead
// Respecting ahead_shelfs_ids order, move shelf ahead
// splice can not be used, since more than 1 elt could be involved
// splice can not be used, since more than 1 elt could be involved
let
ahead_elts
=
[];
let
ahead_elts
=
[];
ahead_shelfs_ids
.
forEach
((
shelf_id
)
=>
{
ahead_shelfs_ids
.
forEach
((
shelf_id
)
=>
{
let
shelf
=
shelfs
[
to_move
[
shelf_id
]];
let
shelf
=
shelfs
[
to_move
[
shelf_id
]];
ahead_elts
.
push
(
shelf
);
ahead_elts
.
push
(
shelf
);
});
});
//remove ahead elts
//remove ahead elts
shelfs
=
shelfs
.
filter
((
item
)
=>
{
return
!
ahead_elts
.
includes
(
item
.
id
)});
shelfs
=
shelfs
.
filter
((
item
)
=>
{
return
!
ahead_elts
.
includes
(
item
.
id
);
});
// put them ahead by concatenation
// put them ahead by concatenation
shelfs
=
ahead_elts
.
concat
(
shelfs
);
shelfs
=
ahead_elts
.
concat
(
shelfs
);
}
}
shelfs
.
forEach
(
shelfs
.
forEach
((
shelf
)
=>
{
(
shelf
)
=>
{
let
option
=
$
(
'<option>'
)
let
option
=
$
(
'<option>'
)
.
val
(
shelf
.
id
)
.
val
(
shelf
.
id
)
.
text
(
shelf
.
name
+
' ('
+
shelf
.
sort_order
+
')'
);
.
text
(
shelf
.
name
+
' ('
+
shelf
.
sort_order
+
')'
);
shelf_selector
.
append
(
option
);
shelf_selector
.
append
(
option
);
});
});
/* add product rows */
/* add product rows */
selected_products_for_shelf_change
.
forEach
(
selected_products_for_shelf_change
.
forEach
((
product
)
=>
{
(
product
)
=>
{
let
tr
=
$
(
'<tr>'
).
attr
(
'data-id'
,
product
.
id
)
let
tr
=
$
(
'<tr>'
).
attr
(
'data-id'
,
product
.
id
)
.
append
(
$
(
'<td>'
).
text
(
product
.
name
))
.
append
(
$
(
'<td>'
).
text
(
product
.
name
))
.
append
(
$
(
'<td>'
).
append
(
shelf_selector
.
clone
()));
.
append
(
$
(
'<td>'
).
append
(
shelf_selector
.
clone
()));
...
@@ -444,19 +461,22 @@ async function open_change_shelf_modal() {
...
@@ -444,19 +461,22 @@ async function open_change_shelf_modal() {
make_change
=
async
()
=>
{
make_change
=
async
()
=>
{
// Prepare data to be transmitted to server to be recorded
// Prepare data to be transmitted to server to be recorded
let
data
=
[];
let
data
=
[];
$
(
'.overlay-content table tbody tr'
).
each
(
function
(
idx
,
e
){
$
(
'.overlay-content table tbody tr'
).
each
(
function
(
idx
,
e
)
{
data
.
push
({
data
.
push
({
product_id
:
$
(
e
).
data
(
'id'
),
product_id
:
$
(
e
).
data
(
'id'
),
shelf_id
:
$
(
e
).
find
(
'select'
).
val
()
shelf_id
:
$
(
e
).
find
(
'select'
)
.
val
()
});
});
});
});
const
update_result
=
await
record_products_shelf_on_server
(
data
);
const
update_result
=
await
record_products_shelf_on_server
(
data
);
if
(
update_result
!==
null
)
{
if
(
update_result
!==
null
)
{
update_result
.
forEach
(
update_result
.
forEach
((
product_id
)
=>
{
(
product_id
)
=>
{
remove_from_toProcess
(
table_to_process
.
row
(
$
(
'tr#'
+
product_id
)));
remove_from_toProcess
(
table_to_process
.
row
(
$
(
'tr#'
+
product_id
)));
});
});
let
message
=
"L'opération a bien réussi."
;
let
message
=
"L'opération a bien réussi."
;
if
(
update_result
.
length
!==
data
.
length
)
{
if
(
update_result
.
length
!==
data
.
length
)
{
message
=
"L'opération a partiellement réussi.
\
n"
;
message
=
"L'opération a partiellement réussi.
\
n"
;
message
+=
(
data
.
length
-
update_result
.
length
)
+
" produit(s) non déplacé(s)."
;
message
+=
(
data
.
length
-
update_result
.
length
)
+
" produit(s) non déplacé(s)."
;
...
@@ -470,14 +490,14 @@ async function open_change_shelf_modal() {
...
@@ -470,14 +490,14 @@ async function open_change_shelf_modal() {
}
}
);
);
}
}
}
}
;
make_change
();
make_change
();
}
}
},
},
'Changer les produits de rayons'
'Changer les produits de rayons'
);
);
}
else
{
}
else
{
alert
(
"Les informations des autres rayons n'ont pas pu être récupérées."
)
alert
(
"Les informations des autres rayons n'ont pas pu être récupérées."
)
;
}
}
}
}
...
@@ -1123,6 +1143,7 @@ function init() {
...
@@ -1123,6 +1143,7 @@ function init() {
});
});
if
(
$
(
this
).
val
().
length
>
0
)
{
if
(
$
(
this
).
val
().
length
>
0
)
{
let
reset_icon
=
$
(
"#reset_to_previous_qty"
);
let
reset_icon
=
$
(
"#reset_to_previous_qty"
);
reset_icon
.
show
();
reset_icon
.
show
();
reset_icon
.
off
();
reset_icon
.
off
();
reset_icon
.
on
(
"click"
,
reset_previous_value
);
reset_icon
.
on
(
"click"
,
reset_previous_value
);
...
@@ -1132,6 +1153,7 @@ function init() {
...
@@ -1132,6 +1153,7 @@ function init() {
})
})
.
on
(
'blur'
,
function
()
{
.
on
(
'blur'
,
function
()
{
const
current_val
=
$
(
this
).
val
();
const
current_val
=
$
(
this
).
val
();
$
(
this
).
off
(
'wheel.disableScroll'
);
$
(
this
).
off
(
'wheel.disableScroll'
);
if
(
editing_item
!==
null
)
{
if
(
editing_item
!==
null
)
{
...
@@ -1140,13 +1162,17 @@ function init() {
...
@@ -1140,13 +1162,17 @@ function init() {
if
(
typeof
editing_item
.
added_qties
!==
"undefined"
)
{
if
(
typeof
editing_item
.
added_qties
!==
"undefined"
)
{
// total may have been affected by manual typing
// total may have been affected by manual typing
const
total
=
get_added_qties_sum
(
editing_item
);
const
total
=
get_added_qties_sum
(
editing_item
);
if
(
current_val
!=
total
)
{
if
(
current_val
!=
total
)
{
// add difference in added_qties array
// add difference in added_qties array
editing_item
.
added_qties
.
push
(
current_val
-
total
);
editing_item
.
added_qties
.
push
(
current_val
-
total
);
}
}
}
else
{
}
else
{
// Init added_qties to take change into account
// Init added_qties to take change into account
editing_item
.
added_qties
=
[
editing_item
.
qty
,
current_val
-
editing_item
.
qty
];
editing_item
.
added_qties
=
[
editing_item
.
qty
,
current_val
-
editing_item
.
qty
];
}
}
}
}
...
@@ -1214,6 +1240,7 @@ function init() {
...
@@ -1214,6 +1240,7 @@ function init() {
$
(
document
).
on
(
'scan.pos.barcode'
,
function
(
event
)
{
$
(
document
).
on
(
'scan.pos.barcode'
,
function
(
event
)
{
//access `event.code` - barcode data
//access `event.code` - barcode data
var
barcode
=
event
.
code
;
var
barcode
=
event
.
code
;
barcode_analyzer
(
barcode
);
barcode_analyzer
(
barcode
);
});
});
...
...
shelfs/static/js/shelfs_admin.js
View file @
f8b23369
...
@@ -357,7 +357,7 @@ var is_product_in_shelf_adding_queue_list = function(testing_pid) {
...
@@ -357,7 +357,7 @@ var is_product_in_shelf_adding_queue_list = function(testing_pid) {
var
printProduct
=
function
()
{
var
printProduct
=
function
()
{
let
clicked
=
$
(
this
);
let
clicked
=
$
(
this
);
let
tr_to_print
=
clicked
.
closest
(
'tr'
);
let
tr_to_print
=
clicked
.
closest
(
'tr'
);
let
barcode
=
tr_to_print
.
data
(
'bc'
)
let
barcode
=
tr_to_print
.
data
(
'bc'
);
openModal
();
openModal
();
try
{
try
{
...
@@ -366,8 +366,9 @@ var printProduct = function () {
...
@@ -366,8 +366,9 @@ var printProduct = function () {
data
:
{
'barcode'
:
barcode
}
data
:
{
'barcode'
:
barcode
}
})
})
.
done
(
function
(
res
)
{
.
done
(
function
(
res
)
{
var
product
=
res
.
product
var
product
=
res
.
product
;
var
product_tmpl_id
=
product
.
product_tmpl_id
[
0
]
var
product_tmpl_id
=
product
.
product_tmpl_id
[
0
];
$
.
ajax
({
$
.
ajax
({
url
:
'/products/label_print/'
+
product_tmpl_id
url
:
'/products/label_print/'
+
product_tmpl_id
})
})
...
@@ -379,9 +380,9 @@ var printProduct = function () {
...
@@ -379,9 +380,9 @@ var printProduct = function () {
}
else
{
}
else
{
alert
(
'Impression lancée'
);
alert
(
'Impression lancée'
);
}
}
})
});
})
});
}
catch
(
e
)
{
}
catch
(
e
)
{
closeModal
();
closeModal
();
alert
(
'Une erreur est survenue...'
);
alert
(
'Une erreur est survenue...'
);
}
}
...
...
shelfs/static/js/shelfs_index.js
View file @
f8b23369
...
@@ -29,6 +29,13 @@ function init_datatable() {
...
@@ -29,6 +29,13 @@ function init_datatable() {
else
{
else
{
var
date
=
new
Date
(
data
);
var
date
=
new
Date
(
data
);
// Get local timezone offset in minutes
const
offset
=
date
.
getTimezoneOffset
();
// Add offset to saved time.
// offset is negative if the local time zone is ahead of UTC.
date
.
setTime
(
date
.
getTime
()
-
offset
*
60
*
1000
);
return
`
${
date
.
toLocaleDateString
(
'fr-FR'
)}
${
date
.
toLocaleTimeString
(
'fr-FR'
)}
`
;
return
`
${
date
.
toLocaleDateString
(
'fr-FR'
)}
${
date
.
toLocaleTimeString
(
'fr-FR'
)}
`
;
}
}
}
}
...
...
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