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
32241a99
Commit
32241a99
authored
Jun 29, 2021
by
Damien Moulard
Browse files
Options
Browse Files
Download
Plain Diff
merge conflict
parents
a15908ef
71fcc738
Pipeline
#1109
failed with stage
in 1 minute 19 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
196 additions
and
8 deletions
+196
-8
orders_helper.js
orders/static/js/orders_helper.js
+135
-7
models.py
products/models.py
+24
-0
urls.py
products/urls.py
+2
-0
views.py
products/views.py
+27
-0
helper.html
templates/orders/helper.html
+8
-1
No files found.
orders/static/js/orders_helper.js
View file @
32241a99
var
suppliers_list
=
[],
products_list
=
[],
products_table
=
null
,
products
=
[],
selected_suppliers
=
[],
...
...
@@ -67,6 +68,67 @@ function dates_diff(date1, date2) {
return
diff
;
}
/* - PRODUCTS */
/**
* Add a product.
*
* @returns -1 if validation failed, 0 otherwise
*/
function
add_product
()
{
const
user_input
=
$
(
"#product_input"
).
val
();
// Check if user input is a valid article
const
product
=
products_list
.
find
(
s
=>
s
.
display_name
===
user_input
);
if
(
product
===
undefined
)
{
alert
(
"L'article renseigné n'est pas valide.
\
n"
+
"Veuillez sélectionner un article dans la liste déroulante."
);
return
-
1
;
}
const
product_exists
=
products
.
findIndex
(
p
=>
p
.
name
===
user_input
);
if
(
product_exists
!==
-
1
)
{
alert
(
"Cet article est déjà dans le tableau."
);
$
(
"#product_input"
).
val
(
''
);
return
-
1
;
}
$
.
ajax
({
type
:
'GET'
,
url
:
'/products/get_product_for_help_order_line/'
+
product
.
tpl_id
,
dataType
:
"json"
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
success
:
function
(
data
)
{
if
(
typeof
data
.
id
!=
"undefined"
)
{
data
.
suppliersinfo
=
[];
data
.
default_code
=
' '
;
products
.
unshift
(
data
);
update_main_screen
({
'sort_order_dir'
:
'desc'
});
update_cdb_order
();
}
else
{
alert
(
"L'article n'a pas toutes les caractéristiques pour être ajouté."
)
}
$
(
"#product_input"
).
val
(
''
);
},
error
:
function
(
data
)
{
err
=
{
msg
:
"erreur serveur lors de la récupération des données liées à l'article"
,
ctx
:
'get_product_for_help_order_line'
};
if
(
typeof
data
.
responseJSON
!=
'undefined'
&&
typeof
data
.
responseJSON
.
error
!=
'undefined'
)
{
err
.
msg
+=
' : '
+
data
.
responseJSON
.
error
;
}
report_JS_error
(
err
,
'orders'
);
alert
(
'Erreur lors de la récupération des informations, réessayer plus tard.'
);
}
});
return
0
;
}
/* - SUPPLIERS */
/**
...
...
@@ -842,7 +904,7 @@ function prepare_datatable_columns() {
/**
* Display the Datatable containing the products
*/
function
display_products
()
{
function
display_products
(
params
)
{
if
(
products
.
length
==
0
)
{
$
(
'.main'
).
hide
();
$
(
'#create_orders'
).
hide
();
...
...
@@ -859,14 +921,17 @@ function display_products() {
const
data
=
prepare_datatable_data
();
const
columns
=
prepare_datatable_columns
();
let
sort_order_dir
=
"asc"
;
if
(
params
!=
undefined
&&
typeof
params
.
sort_order_dir
!=
"undefined"
)
{
sort_order_dir
=
params
.
sort_order_dir
;
}
products_table
=
$
(
'#products_table'
).
DataTable
({
data
:
data
,
columns
:
columns
,
order
:
[
[
5
,
// Order by default by first supplier
"asc"
6
,
// Order by default by first supplier
sort_order_dir
]
],
stripeClasses
:
[],
// Remove datatable cells coloring
...
...
@@ -1027,7 +1092,7 @@ function unselect_all_rows() {
/**
* Update DOM display on main screen
*/
function
update_main_screen
()
{
function
update_main_screen
(
params
)
{
// Remove listener before recreating them
$
(
'#products_table'
).
off
(
'input'
,
'tbody td .product_qty_input'
);
$
(
'#products_table'
).
off
(
'click'
,
'tbody .product_not_from_supplier'
);
...
...
@@ -1037,7 +1102,7 @@ function update_main_screen() {
$
(
".order_name_container"
).
text
(
order_doc
.
_id
);
display_suppliers
();
display_products
();
display_products
(
params
);
// Re-select previously selected rows
if
(
selected_rows
.
length
>
0
)
{
...
...
@@ -1192,6 +1257,11 @@ $(document).ready(function() {
add_supplier
();
});
$
(
"#product_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
add_product
();
});
$
(
"#do_inventory"
).
on
(
"click"
,
function
()
{
generate_inventory
();
});
...
...
@@ -1304,7 +1374,7 @@ $(document).ready(function() {
source
:
suppliers_list
.
map
(
a
=>
a
.
display_name
)
});
closeModal
();
},
error
:
function
(
data
)
{
err
=
{
msg
:
"erreur serveur lors de la récupération des fournisseurs"
,
ctx
:
'get_suppliers'
};
...
...
@@ -1317,4 +1387,62 @@ $(document).ready(function() {
alert
(
'Erreur lors de la récupération des fournisseurs, rechargez la page plus tard'
);
}
});
//Get products
var
accentMap
=
{
"á"
:
"a"
,
"à"
:
"a"
,
"â"
:
"a"
,
"é"
:
"e"
,
"è"
:
"e"
,
"ê"
:
"e"
,
"ë"
:
"e"
,
"ç"
:
"c"
,
"ù"
:
"u"
,
"ü"
:
"u"
,
"ö"
:
"o"
};
var
normalize
=
function
(
term
)
{
var
ret
=
""
;
for
(
var
i
=
0
;
i
<
term
.
length
;
i
++
)
{
ret
+=
accentMap
[
term
.
charAt
(
i
)
]
||
term
.
charAt
(
i
);
}
return
ret
;
};
$
.
ajax
({
type
:
'GET'
,
url
:
"/products/simple_list"
,
dataType
:
"json"
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
success
:
function
(
data
)
{
products_list
=
data
.
list
;
// Set up autocomplete on product input
$
(
"#product_input"
).
autocomplete
({
source
:
function
(
request
,
response
)
{
var
matcher
=
new
RegExp
(
$
.
ui
.
autocomplete
.
escapeRegex
(
request
.
term
),
"i"
);
response
(
$
.
grep
(
products_list
.
map
(
a
=>
a
.
display_name
),
function
(
value
)
{
value
=
value
.
label
||
value
.
value
||
value
;
return
matcher
.
test
(
value
)
||
matcher
.
test
(
normalize
(
value
)
);
})
);
},
position
:
{
collision
:
"flip"
}
});
closeModal
();
},
error
:
function
(
data
)
{
err
=
{
msg
:
"erreur serveur lors de la récupération des articles"
,
ctx
:
'get_products'
};
if
(
typeof
data
.
responseJSON
!=
'undefined'
&&
typeof
data
.
responseJSON
.
error
!=
'undefined'
)
{
err
.
msg
+=
' : '
+
data
.
responseJSON
.
error
;
}
report_JS_error
(
err
,
'orders'
);
closeModal
();
alert
(
'Erreur lors de la récupération des articles, rechargez la page plus tard'
);
}
});
});
products/models.py
View file @
32241a99
...
...
@@ -165,10 +165,34 @@ class CagetteProduct(models.Model):
return
res
@staticmethod
def
get_product_for_help_order_line
(
product_tmpl_id
):
api
=
OdooAPI
()
res
=
[]
try
:
f
=
[
"id"
,
"state"
,
"name"
,
"default_code"
,
"qty_available"
,
"incoming_qty"
,
"uom_id"
,
"purchase_ok"
]
# TODO fetch only 'purchase_ok' products ?
c
=
[[
'id'
,
'='
,
product_tmpl_id
],
[
'purchase_ok'
,
'='
,
True
]]
products_t
=
api
.
search_read
(
'product.template'
,
c
,
f
)
res
=
[
p
for
p
in
products_t
if
p
[
"state"
]
!=
"end"
and
p
[
"state"
]
!=
"obsolete"
]
except
Exception
as
e
:
coop_logger
.
error
(
"Odoo API get_product_for_help_order_line (tpl_id =
%
s) :
%
s"
,
str
(
product_tmpl_id
),
str
(
e
))
return
res
class
CagetteProducts
(
models
.
Model
):
"""Initially used to make massive barcode update."""
@staticmethod
def
get_simple_list
():
res
=
[]
api
=
OdooAPI
()
try
:
res
=
api
.
execute
(
'lacagette.products'
,
'get_simple_list'
,
{
'only_purchase_ok'
:
True
})
except
Exception
as
e
:
coop_logger
.
error
(
"Odoo api products simple list :
%
s"
,
str
(
e
))
return
res
@staticmethod
def
__unique_product_list
(
plist
):
# 276
upl
=
{}
...
...
products/urls.py
View file @
32241a99
...
...
@@ -4,6 +4,8 @@ from . import views
urlpatterns
=
[
url
(
r'^$'
,
views
.
home
),
url
(
r'^simple_list$'
,
views
.
get_simple_list
),
url
(
r'^get_product_for_help_order_line/([0-9]+)$'
,
views
.
get_product_for_help_order_line
),
url
(
r'^get_product_data$'
,
views
.
get_product_data
),
url
(
r'^get_products_stdprices$'
,
views
.
get_products_stdprices
),
url
(
r'^update_product_stock$'
,
views
.
update_product_stock
),
...
...
products/views.py
View file @
32241a99
...
...
@@ -26,6 +26,33 @@ def home(request):
return
HttpResponse
(
template
.
render
(
context
,
request
))
def
get_simple_list
(
request
):
res
=
{}
try
:
res
=
CagetteProducts
.
get_simple_list
()
except
Exception
as
e
:
coop_logger
.
error
(
"Get products simple list :
%
s"
,
str
(
e
))
res
[
'error'
]
=
str
(
e
)
if
(
'error'
in
res
):
return
JsonResponse
(
res
,
status
=
500
)
else
:
return
JsonResponse
(
res
,
safe
=
False
)
def
get_product_for_help_order_line
(
request
,
tpl_id
):
res
=
{}
try
:
result
=
CagetteProduct
.
get_product_for_help_order_line
(
tpl_id
)
if
len
(
result
)
==
1
:
res
=
result
[
0
]
except
Exception
as
e
:
coop_logger
.
error
(
"get_product_for_help_order_line :
%
s"
,
str
(
e
))
res
[
'error'
]
=
str
(
e
)
if
(
'error'
in
res
):
return
JsonResponse
(
res
,
status
=
500
)
else
:
return
JsonResponse
(
res
,
safe
=
False
)
def
get_product_data
(
request
):
barcode
=
request
.
GET
[
'barcode'
]
res
=
CagetteProduct
.
get_product_from_barcode
(
barcode
)
...
...
templates/orders/helper.html
View file @
32241a99
...
...
@@ -61,7 +61,14 @@
</div>
<div
id=
"orders_creation_area"
>
<div
class=
"add_product_container"
></div>
<div
class=
"add_product_container"
>
<div
id=
"product_form_container"
>
<form
action=
"javascript:;"
id=
"product_form"
>
<input
type=
"text"
name=
"article"
id=
"product_input"
placeholder=
"Rechercher un article"
>
<button
type=
"submit"
class=
'btn--primary'
>
Ajouter l'article
</button>
</form>
</div>
</div>
<button
type=
"button"
class=
'btn--primary'
id=
"create_orders"
style=
"display:none;"
>
Générer les commandes
</button>
...
...
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