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
261
Issues
261
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
Paul
third-party
Commits
3cf3ba79
Commit
3cf3ba79
authored
Jun 16, 2021
by
Damien Moulard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reception: prevent concurrent access to same order
parent
6d4a164d
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
191 additions
and
29 deletions
+191
-29
reception_style.css
reception/static/css/reception_style.css
+9
-0
reception_index.js
reception/static/js/reception_index.js
+91
-19
reception_produits.js
reception/static/js/reception_produits.js
+75
-9
index.html
templates/reception/index.html
+15
-0
reception_produits.html
templates/reception/reception_produits.html
+1
-1
No files found.
reception/static/css/reception_style.css
View file @
3cf3ba79
...
...
@@ -35,6 +35,15 @@ input[type="number"] {
margin-bottom
:
1em
;
}
.order_last_update
{
font-weight
:
bold
;
}
.order_modified_msg
{
font-size
:
2rem
;
color
:
#e62720
;
}
/* PRODUITS */
.page_body
{
height
:
100%
;
...
...
reception/static/js/reception_index.js
View file @
3cf3ba79
...
...
@@ -11,12 +11,38 @@ var orders = [],
groups
:
[]
},
dbc
=
null
,
sync
=
null
;
sync
=
null
,
fingerprint
=
null
;
/* UTILS */
/**
* Difference between two dates
* @param {Date} date1
* @param {Date} date2
* @returns difference object
*/
function
dates_diff
(
date1
,
date2
)
{
var
diff
=
{}
var
tmp
=
date2
-
date1
;
tmp
=
Math
.
floor
(
tmp
/
1000
);
diff
.
sec
=
tmp
%
60
;
tmp
=
Math
.
floor
((
tmp
-
diff
.
sec
)
/
60
);
diff
.
min
=
tmp
%
60
;
tmp
=
Math
.
floor
((
tmp
-
diff
.
min
)
/
60
);
diff
.
hours
=
tmp
%
24
;
tmp
=
Math
.
floor
((
tmp
-
diff
.
hours
)
/
24
);
diff
.
days
=
tmp
;
return
diff
;
}
/**
* Wait for both ajax callbacks for reloading to avoid a js error
* -> reloading when ajax call not answered causes a popup to appear, which can be confusing
*/
...
...
@@ -25,6 +51,48 @@ function reload() {
document
.
location
.
reload
();
}
/**
* Check for concurent access to same order before going to reception page.
* @param {Int} id
*/
function
check_before_goto
(
id
)
{
const
order_doc_id
=
'order_'
+
id
;
dbc
.
get
(
order_doc_id
).
then
((
doc
)
=>
{
console
.
log
(
doc
);
if
(
doc
.
last_update
.
fingerprint
!==
null
&&
doc
.
last_update
.
fingerprint
!==
fingerprint
)
{
time_diff
=
dates_diff
(
new
Date
(
doc
.
last_update
.
timestamp
),
new
Date
())
diff_str
=
``
if
(
time_diff
.
days
!==
0
)
{
diff_str
+=
`
${
time_diff
.
days
}
jour(s), `
}
if
(
time_diff
.
hours
!==
0
)
{
diff_str
+=
`
${
time_diff
.
hours
}
heure(s), `
}
if
(
time_diff
.
min
!==
0
)
{
diff_str
+=
`
${
time_diff
.
min
}
min, `
}
diff_str
+=
`
${
time_diff
.
sec
}
s`
let
modal_order_access
=
$
(
'#templates #modal_order_access'
);
modal_order_access
.
find
(
".order_last_update"
).
text
(
diff_str
);
openModal
(
modal_order_access
.
html
(),
()
=>
{
goto
(
id
);
},
'Valider'
);
}
else
{
goto
(
id
);
}
})
.
catch
((
err
)
=>
{
console
.
log
(
err
);
})
}
function
goto
(
id
)
{
document
.
location
.
href
=
"produits/"
+
id
;
}
...
...
@@ -49,7 +117,7 @@ function group_goto(group_index) {
}
// go to first order
goto
(
order_groups
.
groups
[
group_index
][
0
]);
check_before_
goto
(
order_groups
.
groups
[
group_index
][
0
]);
}
/**
...
...
@@ -62,7 +130,7 @@ function create_order_doc(order_data, go_to_order = false) {
dbc
.
get
(
order_doc_id
).
then
(()
=>
{
if
(
go_to_order
===
true
)
{
goto
(
order_data
.
id
);
check_before_
goto
(
order_data
.
id
);
}
})
.
catch
(
function
(
err
)
{
...
...
@@ -71,21 +139,23 @@ function create_order_doc(order_data, go_to_order = false) {
let
order_doc
=
{
...
order_data
};
order_doc
.
_id
=
order_doc_id
;
dbc
.
put
(
order_doc
,
(
err
)
=>
{
if
(
!
err
)
{
if
(
go_to_order
===
true
)
{
goto
(
order_data
.
id
);
}
}
else
{
error
=
{
msg
:
'Erreur dans la creation de la commande dans couchdb'
,
ctx
:
'validatePrices'
,
details
:
err
};
report_JS_error
(
error
,
'reception'
);
console
.
log
(
error
);
order_doc
.
last_update
=
{
timestamp
:
Date
.
now
(),
fingerprint
:
fingerprint
,
};
dbc
.
put
(
order_doc
).
then
(()
=>
{
if
(
go_to_order
===
true
)
{
goto
(
order_data
.
id
);
}
}).
catch
((
err
)
=>
{
error
=
{
msg
:
'Erreur dans la creation de la commande dans couchdb'
,
ctx
:
'validatePrices'
,
details
:
err
};
report_JS_error
(
error
,
'reception'
);
console
.
log
(
error
);
});
}
});
...
...
@@ -184,6 +254,8 @@ function group_action() {
// Create doc for each group order if doesn't exist
create_order_doc
(
selected_data
[
i
]);
// TODO (en dernier): ask before grouping if at least one of the orders is being updated somewhere else
}
group_ids
.
sort
();
...
...
@@ -442,6 +514,8 @@ $(document).ready(function() {
openModal
();
$
.
ajaxSetup
({
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)
}
});
fingerprint
=
new
Fingerprint
({
canvas
:
true
}).
get
();
// Init couchdb
dbc
=
new
PouchDB
(
couchdb_dbname
),
sync
=
PouchDB
.
sync
(
couchdb_dbname
,
couchdb_server
,
{
...
...
@@ -493,8 +567,6 @@ $(document).ready(function() {
console
.
log
(
err
);
});
// TODO on button click to access order: verif fingerprint & timestamp
// Get or create order groups doc
dbc
.
get
(
"grouped_orders"
).
then
((
doc
)
=>
{
order_groups
=
doc
;
...
...
reception/static/js/reception_produits.js
View file @
3cf3ba79
...
...
@@ -33,7 +33,8 @@ var reception_status = null,
barcodes
=
null
;
// Barcodes stored locally
var
dbc
=
null
,
sync
=
null
;
sync
=
null
,
fingerprint
=
null
;
/* UTILS */
...
...
@@ -119,7 +120,10 @@ function select_product_from_bc(barcode) {
* @param {int} order_id
*/
function
update_distant_order
(
order_id
)
{
// TODO insert fingerprint & timestamp
orders
[
order_id
].
last_update
=
{
timestamp
:
Date
.
now
(),
fingerprint
:
fingerprint
,
};
dbc
.
put
(
orders
[
order_id
],
(
err
,
result
)
=>
{
if
(
!
err
&&
result
!==
undefined
)
{
...
...
@@ -131,6 +135,30 @@ function update_distant_order(order_id) {
});
}
/**
* Update distant orders with local data
* @param {int} order_id
*/
function
update_distant_orders
()
{
for
(
let
order_id
in
orders
)
{
orders
[
order_id
].
last_update
=
{
timestamp
:
Date
.
now
(),
fingerprint
:
fingerprint
,
};
}
dbc
.
bulkDocs
(
Object
.
values
(
orders
)).
then
((
response
)
=>
{
// Update rev of current orders after their update
for
(
let
doc
of
response
)
{
let
order_id
=
doc
.
id
.
split
(
'_'
)[
1
];
orders
[
order_id
].
_rev
=
doc
.
rev
}
})
.
catch
((
err
)
=>
{
console
.
log
(
err
);
})
}
/* INIT */
// Get order(s) data from server
...
...
@@ -1260,6 +1288,12 @@ function send() {
updated_products
:
orders
[
order_id
].
updated_products
}
orders
[
order_id
].
reception_status
=
updateType
;
// Unlock order
orders
[
order_id
].
last_update
=
{
timestamp
:
null
,
fingerprint
:
null
,
}
// Delete temp data
delete
orders
[
order_id
].
valid_products
;
...
...
@@ -1333,7 +1367,6 @@ function send() {
}
});
// TODO : for step 1, instead of saving a temp report, save data in couchdb ?
/* Create error report */
$
.
ajax
({
type
:
"POST"
,
...
...
@@ -1434,6 +1467,24 @@ var get_barcodes = async function() {
* @param {Array} partners_display_data
*/
function
init_dom
(
partners_display_data
)
{
// Back button
$
(
'#back_button'
).
on
(
'click'
,
function
()
{
// Liberate current orders
for
(
let
order_id
in
orders
)
{
orders
[
order_id
].
last_update
=
{
timestamp
:
null
,
fingerprint
:
null
,
};
}
dbc
.
bulkDocs
(
Object
.
values
(
orders
)).
then
((
response
)
=>
{
back
();
})
.
catch
((
err
)
=>
{
console
.
log
(
err
);
})
})
// Grouped orders
if
(
Object
.
keys
(
orders
).
length
>
1
)
{
$
(
'#partner_name'
).
html
(
Object
.
keys
(
orders
).
length
+
" commandes"
);
...
...
@@ -1493,7 +1544,7 @@ function init_dom(partners_display_data) {
$
(
"#modal_qtiesValidated"
).
load
(
"/reception/reception_qtiesValidated"
);
}
else
{
// Extra security, shouldn't get in here
// Extra security, shouldn't get in here
: reception status not valid
back
();
}
...
...
@@ -1609,6 +1660,8 @@ function init_dom(partners_display_data) {
$
(
document
).
ready
(
function
()
{
$
.
ajaxSetup
({
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)
}
});
fingerprint
=
new
Fingerprint
({
canvas
:
true
}).
get
();
// Load barcodes
get_barcodes
();
...
...
@@ -1625,15 +1678,25 @@ $(document).ready(function() {
auto_compaction
:
false
});
// TODO on sync change : redirect (cf order_helper)
sync
.
on
(
'change'
,
function
(
info
)
{
console
.
log
(
info
);
sync
.
on
(
'change'
,
function
(
info
)
{
if
(
info
.
direction
===
"pull"
)
{
for
(
const
doc
of
info
.
change
.
docs
)
{
// Redirect if one of the current order is being modified somewhere else
if
(
String
(
doc
.
id
)
in
orders
&&
orders
[
doc
.
id
].
_rev
!==
doc
.
_rev
)
{
alert
(
"Un autre navigateur est en train de modifier cette commande ! Vous allez être redirigé.e."
);
back
();
}
}
}
}).
on
(
'error'
,
function
(
err
)
{
if
(
err
.
status
===
409
)
{
alert
(
"Une erreur de synchronisation s'est produite, la commande a sûrement été modifiée sur un autre navigateur. Vous allez être redirigé.e."
);
back
();
}
console
.
log
(
'erreur sync'
);
console
.
log
(
err
);
});
// TODO insert fingerprint & timestamp on access to order
// Disable alert errors from datatables
$
.
fn
.
dataTable
.
ext
.
errMode
=
'none'
;
...
...
@@ -1748,6 +1811,9 @@ $(document).ready(function() {
// Load saved user comments, get it from first order
user_comments
=
orders
[
Object
.
keys
(
orders
)[
0
]].
user_comments
||
""
;
// Indicate that these orders are used in this navigator
update_distant_orders
()
// Fetch orders data
fetch_data
();
...
...
templates/reception/index.html
View file @
3cf3ba79
...
...
@@ -46,6 +46,21 @@
<p>
Êtez-vous sûr ?
</p>
<hr
/>
</div>
<div
id=
"modal_order_access"
>
<h3>
Attention !
</h3>
<br/>
<p
class=
"order_modified_msg"
>
Un autre navigateur a commencé à réceptionner cette commande il y a
<span
class=
"order_last_update"
></span>
.
</p><br/>
<p>
Si quelqu'un d'autre que vous est à l'origine de cette opération et que celle-ci est récente,
nous conseillons fortement de ne pas accéder à la commande afin d'éviter les conflits.
</p><br/>
<p>
Voulez-vous quand même y accéder ?
</p>
<hr/>
</div>
</div>
<br/>
...
...
templates/reception/reception_produits.html
View file @
3cf3ba79
...
...
@@ -19,7 +19,7 @@
{% endif %}
<div
class=
"page_body"
>
<header
class=
"flex-container"
>
<button
class=
"right btn--danger"
onclick=
"back()
"
>
Retour
</button>
<button
class=
"right btn--danger"
id=
"back_button
"
>
Retour
</button>
<div
class=
"w33 arrow-block txtcenter"
id=
"header_step_one"
>
<h4
id=
"header_step_one_content"
>
Produits à compter
</h4>
</div>
...
...
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