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
abe34fb6
Commit
abe34fb6
authored
3 weeks ago
by
Yvon Kerdoncuff
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
several changes in inventaire par article app
parent
6963f5a9
migration-v12
…
7747-inventaire-par-article
7848-cannot-validate-qty-with-decimal-on-kg-product
2 merge requests
!277
WIP: get modifications from third-party-v12 repo
,
!284
several changes in inventaire par article app
Pipeline
#4179
failed with stage
Changes
6
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
72 additions
and
34 deletions
+72
-34
models.py
products/models.py
+8
-0
products.css
products/static/css/products.css
+4
-3
products_index.js
products/static/js/products_index.js
+30
-25
urls.py
products/urls.py
+1
-0
views.py
products/views.py
+25
-1
index.html
templates/products/index.html
+4
-5
No files found.
products/models.py
View file @
abe34fb6
...
@@ -397,6 +397,14 @@ class CagetteProducts(models.Model):
...
@@ -397,6 +397,14 @@ class CagetteProducts(models.Model):
return
api
.
search_read
(
'product.product'
,
cond
,
fields
)
return
api
.
search_read
(
'product.product'
,
cond
,
fields
)
@staticmethod
@staticmethod
def
get_active_products_from_name
(
name
):
api
=
OdooAPI
()
cond
=
[[
'active'
,
'='
,
True
],
[
'name'
,
'ilike'
,
name
]]
fields
=
[
'id'
,
'uom_id'
,
'name'
,
'qty_available'
,
'barcode'
,
'active'
,
'shelf_id'
,
'product_tmpl_id'
]
return
api
.
search_read
(
'product.product'
,
cond
,
fields
)
@staticmethod
def
get_vrac_products_from_cats
(
cats
,
withCandidate
=
False
,
fields
=
[]):
def
get_vrac_products_from_cats
(
cats
,
withCandidate
=
False
,
fields
=
[]):
api
=
OdooAPI
()
api
=
OdooAPI
()
cond
=
[[
'active'
,
'='
,
True
],
cond
=
[[
'active'
,
'='
,
True
],
...
...
This diff is collapsed.
Click to expand it.
products/static/css/products.css
View file @
abe34fb6
.main
,
.barcode_search_area
{
.main
,
.barcode_
or_name_
search_area
{
margin-top
:
20px
;
margin-top
:
20px
;
}
}
#barcode_selector
{
#barcode_
or_name_
selector
{
border
:
1px
solid
#555
;
border
:
1px
solid
#555
;
border-radius
:
15px
;
border-radius
:
15px
;
}
}
.stock_edit_input
{
.stock_edit_input
{
max-width
:
5
0px
;
max-width
:
10
0px
;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
products/static/js/products_index.js
View file @
abe34fb6
/*
/*
* Récupération d'un produit par scan et affichage des informations du produits.
* Récupération d'un produit par scan et affichage des informations du produits.
* Les informations actuellements récupérées sont :
* Les informations actuellements récupérées sont :
* - Numéro de Rayon
* - Numéro de Rayon
(not anymore : too slow)
* - Stock théorique
* - Stock théorique
*
*
* Les informations actuellement modifiables sont :
* Les informations actuellement modifiables sont :
...
@@ -11,10 +11,11 @@
...
@@ -11,10 +11,11 @@
var
products
=
[],
var
products
=
[],
products_table
=
null
,
products_table
=
null
,
search_chars
=
[];
search_chars
=
[];
search_history
=
[];
function
reset_focus
()
{
function
reset_focus
()
{
$
(
'#barcode_selector'
).
val
(
''
);
$
(
'#barcode_
or_name_
selector'
).
val
(
''
);
$
(
'#barcode_selector'
).
focus
();
$
(
'#barcode_
or_name_
selector'
).
focus
();
}
}
function
add_product
(
product
)
{
function
add_product
(
product
)
{
...
@@ -45,7 +46,6 @@ function add_product(product) {
...
@@ -45,7 +46,6 @@ function add_product(product) {
+
display_barcode
+
'</span> </div>'
;
+
display_barcode
+
'</span> </div>'
;
}
}
},
},
{
data
:
"shelf_sortorder"
,
title
:
"Rayon"
},
{
{
data
:
"uom_id.1"
,
data
:
"uom_id.1"
,
title
:
"Unité de vente"
,
title
:
"Unité de vente"
,
...
@@ -83,7 +83,7 @@ function add_product(product) {
...
@@ -83,7 +83,7 @@ function add_product(product) {
.
find
(
'input'
)
.
find
(
'input'
)
.
val
();
.
val
();
if
(
row_data
.
uom_id
[
0
]
==
1
)
{
if
(
row_data
.
uom_id
[
0
]
==
1
)
{
if
(
qty
/
parseInt
(
qty
)
!=
1
)
{
if
(
qty
!=
0
&&
qty
/
parseInt
(
qty
)
!=
1
)
{
$
.
notify
(
$
.
notify
(
"Ce produit est vendu à l'unité : la valeur doit être un nombre entier !"
,
"Ce produit est vendu à l'unité : la valeur doit être un nombre entier !"
,
{
{
...
@@ -189,19 +189,18 @@ function update_product_stock(p_data) {
...
@@ -189,19 +189,18 @@ function update_product_stock(p_data) {
}
}
// Fetch a product when barcode is read
// Fetch a product when barcode is read
function
fetch_product
_from_bc
(
barcode
)
{
function
fetch_product
s_from_bc_or_name
(
input
)
{
if
(
barcode
==
''
)
{
if
(
input
==
''
)
{
reset_focus
();
reset_focus
();
return
0
;
return
0
;
}
}
for
(
p
of
products
)
{
if
(
search_history
.
includes
(
input
))
{
if
(
p
.
barcode
==
barcode
)
{
$
.
notify
(
$
.
notify
(
"Produit déjà récupéré
!"
,
"Recherche déjà effectuée
!"
,
{
{
globalPosition
:
"top left"
,
globalPosition
:
"top left"
,
className
:
"info"
className
:
"info"
}
}
);
);
...
@@ -209,27 +208,24 @@ function fetch_product_from_bc(barcode) {
...
@@ -209,27 +208,24 @@ function fetch_product_from_bc(barcode) {
reset_focus
();
reset_focus
();
return
0
;
return
0
;
}
}
else
{
search_history
.
push
(
input
)
}
}
$
.
ajax
({
$
.
ajax
({
url
:
"/products/get_product
_data?barcode="
+
barcode
,
url
:
"/products/get_product
s_data_by_barcode_or_name?input="
+
input
,
success
:
function
(
data
)
{
success
:
function
(
data
)
{
reset_focus
();
reset_focus
();
if
(
data
.
product
.
active
==
false
)
{
for
(
const
product
of
data
.
products
)
{
alert
(
'Ce produit est archivé !'
);
add_product
(
product
);
return
0
;
}
}
add_product
(
data
.
product
);
},
},
error
:
function
(
data
)
{
error
:
function
(
data
)
{
if
(
data
.
status
==
404
)
{
if
(
data
.
status
==
404
)
{
// Product not found (shouldn't rise)
// Product not found (shouldn't rise)
$
.
notify
(
$
.
notify
(
"Aucun produit trouvé
avec ce code barre
!"
,
"Aucun produit trouvé !"
,
{
{
globalPosition
:
"top left"
,
globalPosition
:
"top left"
,
className
:
"error"
className
:
"error"
...
@@ -238,7 +234,7 @@ function fetch_product_from_bc(barcode) {
...
@@ -238,7 +234,7 @@ function fetch_product_from_bc(barcode) {
reset_focus
();
reset_focus
();
}
else
{
}
else
{
// server error
// server error
err
=
{
msg
:
"erreur serveur lors de la récupération du produit"
,
ctx
:
'fetch_product
_from_bc
'
};
err
=
{
msg
:
"erreur serveur lors de la récupération du produit"
,
ctx
:
'fetch_product
s_from_bc_or_name
'
};
if
(
typeof
data
.
responseJSON
!=
'undefined'
&&
typeof
data
.
responseJSON
.
error
!=
'undefined'
)
{
if
(
typeof
data
.
responseJSON
!=
'undefined'
&&
typeof
data
.
responseJSON
.
error
!=
'undefined'
)
{
err
.
msg
+=
' : '
+
data
.
responseJSON
.
error
;
err
.
msg
+=
' : '
+
data
.
responseJSON
.
error
;
}
}
...
@@ -255,9 +251,18 @@ $(document).ready(function() {
...
@@ -255,9 +251,18 @@ $(document).ready(function() {
reset_focus
();
reset_focus
();
$
(
'#button_barcode_selector'
).
on
(
'click'
,
function
()
{
$
(
'#button_barcode_or_name_selector'
).
on
(
'click'
,
function
()
{
bc
=
$
(
'#barcode_selector'
).
val
();
input
=
$
(
'#barcode_or_name_selector'
).
val
();
fetch_product_from_bc
(
bc
);
fetch_products_from_bc_or_name
(
input
);
});
// Interception de la touche "Enter" dans le champ de texte
$
(
'#barcode_or_name_selector'
).
on
(
'keypress'
,
function
(
e
)
{
if
(
e
.
which
===
13
)
{
// Si la touche pressée est "Enter" (key code 13)
e
.
preventDefault
();
// Empêche le comportement par défaut (rechargement ou soumission de formulaire)
input
=
$
(
'#barcode_or_name_selector'
).
val
();
fetch_products_from_bc_or_name
(
input
);
// Appelle la fonction de recherche
}
});
});
// Barcode reader: listen for 13 digits read in a very short time
// Barcode reader: listen for 13 digits read in a very short time
...
@@ -271,7 +276,7 @@ $(document).ready(function() {
...
@@ -271,7 +276,7 @@ $(document).ready(function() {
if
(
!
isNaN
(
barcode
))
{
if
(
!
isNaN
(
barcode
))
{
search_chars
=
[];
search_chars
=
[];
setTimeout
(
function
()
{
setTimeout
(
function
()
{
fetch_product
_from_bc
(
barcode
);
fetch_product
s_from_bc_or_name
(
barcode
);
},
300
);
},
300
);
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
products/urls.py
View file @
abe34fb6
...
@@ -7,6 +7,7 @@ urlpatterns = [
...
@@ -7,6 +7,7 @@ urlpatterns = [
url
(
r'^simple_list$'
,
views
.
get_simple_list
),
url
(
r'^simple_list$'
,
views
.
get_simple_list
),
url
(
r'^get_product_for_order_helper$'
,
views
.
get_product_for_order_helper
),
url
(
r'^get_product_for_order_helper$'
,
views
.
get_product_for_order_helper
),
url
(
r'^get_product_data$'
,
views
.
get_product_data
),
url
(
r'^get_product_data$'
,
views
.
get_product_data
),
url
(
r'^get_products_data_by_barcode_or_name$'
,
views
.
get_products_data_by_barcode_or_name
),
url
(
r'^get_products_stdprices$'
,
views
.
get_products_stdprices
),
url
(
r'^get_products_stdprices$'
,
views
.
get_products_stdprices
),
url
(
r'^update_product_stock$'
,
views
.
update_product_stock
),
url
(
r'^update_product_stock$'
,
views
.
update_product_stock
),
url
(
r'^update_product_purchase_ok$'
,
views
.
update_product_purchase_ok
),
url
(
r'^update_product_purchase_ok$'
,
views
.
update_product_purchase_ok
),
...
...
This diff is collapsed.
Click to expand it.
products/views.py
View file @
abe34fb6
...
@@ -55,6 +55,25 @@ def get_product_for_order_helper(request):
...
@@ -55,6 +55,25 @@ def get_product_for_order_helper(request):
else
:
else
:
return
JsonResponse
(
res
,
safe
=
False
)
return
JsonResponse
(
res
,
safe
=
False
)
def
get_products_data_by_barcode_or_name
(
request
):
input
=
request
.
GET
[
'input'
]
# check if it is probably a barcode input
if
input
.
isdigit
()
and
len
(
input
)
>
6
:
products
=
CagetteProduct
.
get_product_from_barcode
(
input
)
# or a text input
else
:
products
=
CagetteProducts
.
get_active_products_from_name
(
input
)
#commented because too slow
#for product in products:
# add_shelf_sortorder(product)
if
not
products
:
return
JsonResponse
({
"product"
:
products
},
status
=
404
)
else
:
return
JsonResponse
({
"products"
:
products
})
def
get_product_data
(
request
):
def
get_product_data
(
request
):
barcode
=
request
.
GET
[
'barcode'
]
barcode
=
request
.
GET
[
'barcode'
]
res
=
CagetteProduct
.
get_product_from_barcode
(
barcode
)
res
=
CagetteProduct
.
get_product_from_barcode
(
barcode
)
...
@@ -63,6 +82,12 @@ def get_product_data(request):
...
@@ -63,6 +82,12 @@ def get_product_data(request):
return
JsonResponse
({
"product"
:
res
},
status
=
404
)
return
JsonResponse
({
"product"
:
res
},
status
=
404
)
p
=
res
[
0
]
p
=
res
[
0
]
add_shelf_sortorder
(
p
)
return
JsonResponse
({
"product"
:
p
})
def
add_shelf_sortorder
(
p
):
if
p
[
'shelf_id'
]
is
not
False
:
if
p
[
'shelf_id'
]
is
not
False
:
shelfs_sortorder
=
Shelfs
.
get_shelfs_sortorder
([
p
[
'shelf_id'
][
0
]])
shelfs_sortorder
=
Shelfs
.
get_shelfs_sortorder
([
p
[
'shelf_id'
][
0
]])
...
@@ -73,7 +98,6 @@ def get_product_data(request):
...
@@ -73,7 +98,6 @@ def get_product_data(request):
else
:
else
:
p
[
'shelf_sortorder'
]
=
'X'
p
[
'shelf_sortorder'
]
=
'X'
return
JsonResponse
({
"product"
:
p
})
def
get_products_stdprices
(
request
):
def
get_products_stdprices
(
request
):
ids
=
json
.
loads
(
request
.
body
.
decode
())
ids
=
json
.
loads
(
request
.
body
.
decode
())
...
...
This diff is collapsed.
Click to expand it.
templates/products/index.html
View file @
abe34fb6
...
@@ -15,13 +15,12 @@
...
@@ -15,13 +15,12 @@
{% block content %}
{% block content %}
<div
class=
"header txtcenter"
>
<div
class=
"header txtcenter"
>
<h1>
In
formations sur les produits du magasin
</h1>
<h1>
In
ventaire par produits
</h1>
</div>
</div>
<div
class=
"barcode_search_area txtcenter"
>
<div
class=
"barcode_or_name_search_area txtcenter"
>
<p><i>
Passez un produit sous la douchette ! Si rien ne se passe, cliquez sur le champ ci-dessous puis ré-essayez.
</i></p>
<input
type=
"text"
id=
"barcode_or_name_selector"
name=
"barcode_or_name_selector"
placeholder=
"Nom ou codebarre"
>
<input
type=
"text"
id=
"barcode_selector"
name=
"barcode_selector"
placeholder=
"Codebarre"
>
<button
type=
"button"
class=
"btn--primary"
id=
"button_barcode_or_name_selector"
name=
"button"
>
Recherche
</button>
<button
type=
"button"
class=
"btn--primary"
id=
"button_barcode_selector"
name=
"button"
>
Recherche
</button>
</div>
</div>
<div
class=
"main"
>
<div
class=
"main"
>
...
...
This diff is collapsed.
Click to expand it.
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