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
45a126c9
Commit
45a126c9
authored
Jul 29, 2021
by
Damien Moulard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update product ref
parent
1533010a
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
182 additions
and
19 deletions
+182
-19
oders_helper_style.css
orders/static/css/oders_helper_style.css
+11
-2
orders_helper.js
orders/static/js/orders_helper.js
+137
-17
models.py
products/models.py
+22
-0
urls.py
products/urls.py
+1
-0
views.py
products/views.py
+11
-0
No files found.
orders/static/css/oders_helper_style.css
View file @
45a126c9
...
@@ -227,18 +227,27 @@
...
@@ -227,18 +227,27 @@
width
:
100px
;
width
:
100px
;
}
}
.product_ref_input
{
padding
:
.5rem
.5rem
;
}
.supplier_package_qty
{
.supplier_package_qty
{
font-style
:
italic
;
font-style
:
italic
;
font-size
:
1.3rem
;
font-size
:
1.3rem
;
}
}
.product_not_from_supplier
{
.product_not_from_supplier
{
background-color
:
#e
7e9ed
;
background-color
:
#e
8ebf0
;
cursor
:
pointer
;
cursor
:
pointer
;
}
}
.product_not_from_supplier
:hover
{
.product_not_from_supplier
:hover
{
background-color
:
#c7cace
;
background-color
:
#d3d7db
;
}
.product_ref_cell
:hover
{
background-color
:
#d3d7db
;
cursor
:
pointer
;
}
}
.product_name
,
.supplier_name
,
.product_npa
{
.product_name
,
.supplier_name
,
.product_npa
{
...
...
orders/static/js/orders_helper.js
View file @
45a126c9
...
@@ -292,6 +292,73 @@ function check_products_data() {
...
@@ -292,6 +292,73 @@ function check_products_data() {
});
});
}
}
/**
* Update the product internal reference ('default_code')
*
* @param {HTMLElement} input_el
* @param {int} p_id
* @param {int} p_index
*/
function
update_product_ref
(
input_el
,
p_id
,
p_index
)
{
const
val
=
$
(
input_el
).
val
();
const
existing_val
=
products
[
p_index
].
default_code
.
replace
(
"[input]"
,
""
);
products
[
p_index
].
default_code
=
val
;
const
row
=
$
(
input_el
).
closest
(
'tr'
);
const
new_row_data
=
prepare_datatable_data
([
p_id
])[
0
];
products_table
.
row
(
row
).
data
(
new_row_data
)
.
draw
();
$
(
'#products_table'
)
.
off
(
'blur'
,
'tbody .product_ref_input'
)
.
off
(
'keypress'
,
'tbody .product_ref_input'
);
// Update in backend if value changed
if
(
existing_val
!==
val
)
{
const
data
=
{
'product_tmpl_id'
:
p_id
,
'default_code'
:
val
};
// Send request to create association
$
.
ajax
({
type
:
"POST"
,
url
:
"/products/update_product_internal_ref"
,
dataType
:
"json"
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
data
:
JSON
.
stringify
(
data
),
success
:
()
=>
{
update_cdb_order
();
$
(
".actions_buttons_area .right_action_buttons"
).
notify
(
"Référence sauvegardée !"
,
{
elementPosition
:
"bottom right"
,
className
:
"success"
,
arrowShow
:
false
}
);
},
error
:
function
(
data
)
{
let
msg
=
"erreur serveur lors de la sauvegarde de la référence"
;
msg
+=
` (product_tmpl_id:
${
product
.
id
}
`
;
err
=
{
msg
:
msg
,
ctx
:
'update_product_ref'
};
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 sauvegarde de la référence dans Odoo. Veuillez recharger la page et ré-essayer plus tard.'
);
}
});
}
}
/* - SUPPLIERS */
/* - SUPPLIERS */
...
@@ -303,9 +370,9 @@ function check_products_data() {
...
@@ -303,9 +370,9 @@ function check_products_data() {
function
add_supplier
()
{
function
add_supplier
()
{
const
user_input
=
$
(
"#supplier_input"
).
val
();
const
user_input
=
$
(
"#supplier_input"
).
val
();
// Check if user input is a valid supplier
let
supplier
=
suppliers_list
.
find
(
s
=>
s
.
display_name
===
user_input
);
let
supplier
=
suppliers_list
.
find
(
s
=>
s
.
display_name
===
user_input
);
// Check if user input is a valid supplier
if
(
supplier
===
undefined
)
{
if
(
supplier
===
undefined
)
{
alert
(
"Le fournisseur renseigné n'est pas valide.
\
n"
alert
(
"Le fournisseur renseigné n'est pas valide.
\
n"
+
"Veuillez sélectionner un fournisseur dans la liste déroulante."
);
+
"Veuillez sélectionner un fournisseur dans la liste déroulante."
);
...
@@ -323,10 +390,6 @@ function add_supplier() {
...
@@ -323,10 +390,6 @@ function add_supplier() {
openModal
();
openModal
();
supplier
.
total_value
=
0
;
supplier
.
total_packages
=
0
;
selected_suppliers
.
push
(
supplier
);
// Fetch supplier products
// Fetch supplier products
$
.
ajax
({
$
.
ajax
({
type
:
'GET'
,
type
:
'GET'
,
...
@@ -339,6 +402,10 @@ function add_supplier() {
...
@@ -339,6 +402,10 @@ function add_supplier() {
traditional
:
true
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
contentType
:
"application/json; charset=utf-8"
,
success
:
function
(
data
)
{
success
:
function
(
data
)
{
supplier
.
total_value
=
0
;
supplier
.
total_packages
=
0
;
selected_suppliers
.
push
(
supplier
);
save_supplier_products
(
supplier
,
data
.
res
.
products
);
save_supplier_products
(
supplier
,
data
.
res
.
products
);
update_main_screen
();
update_main_screen
();
$
(
"#supplier_input"
).
val
(
""
);
$
(
"#supplier_input"
).
val
(
""
);
...
@@ -448,7 +515,8 @@ function save_supplier_product_association(product, supplier, cell) {
...
@@ -448,7 +515,8 @@ function save_supplier_product_association(product, supplier, cell) {
closeModal
();
closeModal
();
},
},
error
:
function
(
data
)
{
error
:
function
(
data
)
{
let
msg
=
"erreur serveur lors de la sauvegarde de l'association product/supplier"
.
let
msg
=
"erreur serveur lors de la sauvegarde de l'association product/supplier"
;
msg
+=
` (product_tmpl_id:
${
product
.
id
}
; supplier_id:
${
supplier
.
id
}
)`
;
msg
+=
` (product_tmpl_id:
${
product
.
id
}
; supplier_id:
${
supplier
.
id
}
)`
;
err
=
{
msg
:
msg
,
ctx
:
'save_supplier_product_association'
};
err
=
{
msg
:
msg
,
ctx
:
'save_supplier_product_association'
};
...
@@ -593,6 +661,7 @@ function _compute_total_values_by_supplier() {
...
@@ -593,6 +661,7 @@ function _compute_total_values_by_supplier() {
// Value
// Value
let
product_supplier_value
=
(
'qty'
in
supinfo
)
?
supinfo
.
qty
*
supinfo
.
package_qty
*
supinfo
.
price
:
0
;
let
product_supplier_value
=
(
'qty'
in
supinfo
)
?
supinfo
.
qty
*
supinfo
.
package_qty
*
supinfo
.
price
:
0
;
selected_suppliers
[
supplier_index
].
total_value
+=
product_supplier_value
;
selected_suppliers
[
supplier_index
].
total_value
+=
product_supplier_value
;
// Packages
// Packages
...
@@ -721,7 +790,7 @@ function generate_inventory() {
...
@@ -721,7 +790,7 @@ function generate_inventory() {
"Inventaire créé !"
,
"Inventaire créé !"
,
{
{
elementPosition
:
"bottom center"
,
elementPosition
:
"bottom center"
,
className
:
"success"
,
className
:
"success"
}
}
);
);
},
200
);
},
200
);
...
@@ -883,7 +952,7 @@ function delete_cdb_order() {
...
@@ -883,7 +952,7 @@ function delete_cdb_order() {
alert
(
"Erreur lors de la suppression de la commande... Si l'erreur persiste contactez un administrateur svp."
);
alert
(
"Erreur lors de la suppression de la commande... Si l'erreur persiste contactez un administrateur svp."
);
console
.
log
(
err
);
console
.
log
(
err
);
reject
();
reject
(
new
Error
(
'fail'
)
);
}
}
});
});
});
});
...
@@ -1260,9 +1329,20 @@ function prepare_datatable_columns() {
...
@@ -1260,9 +1329,20 @@ function prepare_datatable_columns() {
{
{
data
:
"default_code"
,
data
:
"default_code"
,
title
:
"Ref"
,
title
:
"Ref"
,
width
:
"6%"
,
width
:
"8%"
,
render
:
function
(
data
)
{
render
:
function
(
data
,
type
,
full
)
{
return
(
data
===
false
)
?
""
:
data
;
if
(
data
===
false
)
{
return
""
;
}
else
if
(
data
.
includes
(
"[input]"
))
{
let
val
=
data
.
replace
(
"[input]"
,
""
);
return
`<div class="custom_cell_content">
<input type="text" class="product_ref_input" id="
${
full
.
id
}
_ref_input" value="
${
val
}
">
</div>`
;
}
else
{
return
data
;
}
}
}
},
},
{
{
...
@@ -1433,13 +1513,15 @@ function display_products(params) {
...
@@ -1433,13 +1513,15 @@ function display_products(params) {
scrollX
:
true
,
scrollX
:
true
,
language
:
{
url
:
'/static/js/datatables/french.json'
},
language
:
{
url
:
'/static/js/datatables/french.json'
},
createdRow
:
function
(
row
)
{
createdRow
:
function
(
row
)
{
for
(
const
cell_node
of
row
.
cells
)
{
for
(
var
i
=
0
;
i
<
row
.
cells
.
length
;
i
++
)
{
const
cell_node
=
row
.
cells
[
i
];
const
cell
=
$
(
cell_node
);
const
cell
=
$
(
cell_node
);
if
(
cell
.
hasClass
(
"supplier_input_cell"
))
{
if
(
cell
.
hasClass
(
"supplier_input_cell"
)
&&
cell
.
text
()
===
"X"
)
{
if
(
cell
.
text
()
==
"X"
)
{
cell
.
addClass
(
'product_not_from_supplier'
);
cell
.
addClass
(
'product_not_from_supplier'
);
}
}
else
if
(
i
===
1
)
{
// Column at index 1 is product reference
cell
.
addClass
(
'product_ref_cell'
);
}
}
}
}
}
}
...
@@ -1576,6 +1658,41 @@ function display_products(params) {
...
@@ -1576,6 +1658,41 @@ function display_products(params) {
new_product_supplier_association
.
package_qty
=
$
(
this
).
val
();
new_product_supplier_association
.
package_qty
=
$
(
this
).
val
();
});
});
});
});
// Display input on click on product ref cell
$
(
'#products_table'
).
on
(
'click'
,
'tbody .product_ref_cell'
,
function
()
{
if
(
$
(
this
).
find
(
'input'
).
length
===
0
)
{
const
row
=
$
(
this
).
closest
(
'tr'
);
const
p_id
=
products_table
.
row
(
row
).
data
().
id
;
const
p_index
=
products
.
findIndex
(
p
=>
p
.
id
===
p_id
);
const
existing_ref
=
products
[
p_index
].
default_code
===
false
?
''
:
products
[
p_index
].
default_code
;
products
[
p_index
].
default_code
=
"[input]"
+
existing_ref
;
const
new_row_data
=
prepare_datatable_data
([
p_id
])[
0
];
products_table
.
row
(
row
).
data
(
new_row_data
)
.
draw
();
let
ref_input
=
$
(
`#
${
p_id
}
_ref_input`
);
ref_input
.
focus
();
ref_input
.
select
();
$
(
'#products_table'
)
.
on
(
'blur'
,
'tbody .product_ref_input'
,
function
()
{
update_product_ref
(
this
,
p_id
,
p_index
);
})
.
on
(
'keypress'
,
'tbody .product_ref_input'
,
function
(
e
)
{
// Validate on Enter pressed
if
(
e
.
which
==
13
)
{
update_product_ref
(
this
,
p_id
,
p_index
);
}
});
}
});
// Select row(s) on checkbox change
// Select row(s) on checkbox change
$
(
products_table
.
table
().
header
()).
on
(
'click'
,
'th #select_all_products_cb'
,
function
()
{
$
(
products_table
.
table
().
header
()).
on
(
'click'
,
'th #select_all_products_cb'
,
function
()
{
if
(
this
.
checked
)
{
if
(
this
.
checked
)
{
...
@@ -1691,6 +1808,7 @@ function update_main_screen(params) {
...
@@ -1691,6 +1808,7 @@ function update_main_screen(params) {
// Remove listener before recreating them
// Remove listener before recreating them
$
(
'#products_table'
).
off
(
'change'
,
'tbody td .product_qty_input'
);
$
(
'#products_table'
).
off
(
'change'
,
'tbody td .product_qty_input'
);
$
(
'#products_table'
).
off
(
'click'
,
'tbody .product_not_from_supplier'
);
$
(
'#products_table'
).
off
(
'click'
,
'tbody .product_not_from_supplier'
);
$
(
'#products_table'
).
off
(
'click'
,
'tbody .product_ref_cell'
);
$
(
'#products_table'
).
off
(
'click'
,
'thead th #select_all_products_cb'
);
$
(
'#products_table'
).
off
(
'click'
,
'thead th #select_all_products_cb'
);
$
(
'#products_table'
).
off
(
'click'
,
'tbody td .select_product_cb'
);
$
(
'#products_table'
).
off
(
'click'
,
'tbody td .select_product_cb'
);
$
(
".remove_supplier_icon"
).
off
();
$
(
".remove_supplier_icon"
).
off
();
...
@@ -1765,6 +1883,7 @@ function update_order_selection_screen() {
...
@@ -1765,6 +1883,7 @@ function update_order_selection_screen() {
let
order_id
=
$
(
order_name_container
).
text
();
let
order_id
=
$
(
order_name_container
).
text
();
let
modal_remove_order
=
$
(
'#templates #modal_remove_order'
);
let
modal_remove_order
=
$
(
'#templates #modal_remove_order'
);
modal_remove_order
.
find
(
".remove_order_name"
).
text
(
order_id
);
modal_remove_order
.
find
(
".remove_order_name"
).
text
(
order_id
);
openModal
(
openModal
(
...
@@ -1930,7 +2049,7 @@ $(document).ready(function() {
...
@@ -1930,7 +2049,7 @@ $(document).ready(function() {
}
}
});
});
$
(
"#toggle_action_buttons"
).
on
(
"click"
,
function
(
e
)
{
$
(
"#toggle_action_buttons"
).
on
(
"click"
,
function
()
{
if
(
$
(
'#actions_buttons_container'
).
is
(
":visible"
))
{
if
(
$
(
'#actions_buttons_container'
).
is
(
":visible"
))
{
$
(
'#actions_buttons_container'
).
hide
();
$
(
'#actions_buttons_container'
).
hide
();
$
(
'.toggle_action_buttons_icon'
).
empty
()
$
(
'.toggle_action_buttons_icon'
).
empty
()
...
@@ -1992,9 +2111,10 @@ $(document).ready(function() {
...
@@ -1992,9 +2111,10 @@ $(document).ready(function() {
}
}
});
});
$
(
"#delete_order_button"
).
on
(
"click"
,
function
(
e
)
{
$
(
"#delete_order_button"
).
on
(
"click"
,
function
()
{
if
(
is_time_to
(
'press_delete_order_button'
,
1000
))
{
if
(
is_time_to
(
'press_delete_order_button'
,
1000
))
{
let
modal_remove_order
=
$
(
'#templates #modal_remove_order'
);
let
modal_remove_order
=
$
(
'#templates #modal_remove_order'
);
modal_remove_order
.
find
(
".remove_order_name"
).
text
(
order_doc
.
_id
);
modal_remove_order
.
find
(
".remove_order_name"
).
text
(
order_doc
.
_id
);
openModal
(
openModal
(
...
...
products/models.py
View file @
45a126c9
...
@@ -130,6 +130,7 @@ class CagetteProduct(models.Model):
...
@@ -130,6 +130,7 @@ class CagetteProduct(models.Model):
@staticmethod
@staticmethod
def
associate_supplier_to_product
(
data
):
def
associate_supplier_to_product
(
data
):
api
=
OdooAPI
()
api
=
OdooAPI
()
res
=
{}
product_tmpl_id
=
data
[
"product_tmpl_id"
]
product_tmpl_id
=
data
[
"product_tmpl_id"
]
partner_id
=
data
[
"supplier_id"
]
partner_id
=
data
[
"supplier_id"
]
...
@@ -151,7 +152,11 @@ class CagetteProduct(models.Model):
...
@@ -151,7 +152,11 @@ class CagetteProduct(models.Model):
'package_qty'
:
package_qty
,
'package_qty'
:
package_qty
,
'sequence'
:
1000
# lowest priority for the new suppliers
'sequence'
:
1000
# lowest priority for the new suppliers
}
}
try
:
res
=
api
.
create
(
'product.supplierinfo'
,
f
)
res
=
api
.
create
(
'product.supplierinfo'
,
f
)
except
Exception
as
e
:
res
[
'error'
]
=
str
(
e
)
return
res
return
res
...
@@ -188,6 +193,23 @@ class CagetteProduct(models.Model):
...
@@ -188,6 +193,23 @@ class CagetteProduct(models.Model):
return
res
return
res
@staticmethod
def
update_product_internal_ref
(
product_tmpl_id
,
default_code
):
api
=
OdooAPI
()
res
=
{}
f
=
{
'default_code'
:
default_code
}
try
:
res
[
"update"
]
=
api
.
update
(
'product.template'
,
product_tmpl_id
,
f
)
except
Exception
as
e
:
res
[
"error"
]
=
str
(
e
)
print
(
str
(
e
))
return
res
class
CagetteProducts
(
models
.
Model
):
class
CagetteProducts
(
models
.
Model
):
"""Initially used to make massive barcode update."""
"""Initially used to make massive barcode update."""
...
...
products/urls.py
View file @
45a126c9
...
@@ -10,6 +10,7 @@ urlpatterns = [
...
@@ -10,6 +10,7 @@ urlpatterns = [
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
),
url
(
r'^update_product_internal_ref$'
,
views
.
update_product_internal_ref
),
url
(
r'^labels_appli_csv(\/?[a-z]*)$'
,
views
.
labels_appli_csv
,
name
=
'labels_appli_csv'
),
url
(
r'^labels_appli_csv(\/?[a-z]*)$'
,
views
.
labels_appli_csv
,
name
=
'labels_appli_csv'
),
url
(
r'^label_print/([0-9]+)/?([0-9\.]*)/?([a-z]*)/?([0-9]*)$'
,
views
.
label_print
),
url
(
r'^label_print/([0-9]+)/?([0-9\.]*)/?([a-z]*)/?([0-9]*)$'
,
views
.
label_print
),
url
(
r'^shelf_labels$'
,
views
.
shelf_labels
),
# massive print
url
(
r'^shelf_labels$'
,
views
.
shelf_labels
),
# massive print
...
...
products/views.py
View file @
45a126c9
...
@@ -114,6 +114,17 @@ def update_product_purchase_ok(request):
...
@@ -114,6 +114,17 @@ def update_product_purchase_ok(request):
else
:
else
:
return
JsonResponse
({
"res"
:
res
})
return
JsonResponse
({
"res"
:
res
})
def
update_product_internal_ref
(
request
):
res
=
{}
data
=
json
.
loads
(
request
.
body
.
decode
())
res
=
CagetteProduct
.
update_product_internal_ref
(
data
[
"product_tmpl_id"
],
data
[
"default_code"
])
if
(
'error'
in
res
):
return
JsonResponse
(
res
,
status
=
500
)
else
:
return
JsonResponse
({
"res"
:
res
})
def
labels_appli_csv
(
request
,
params
):
def
labels_appli_csv
(
request
,
params
):
"""Generate files to put in DAV directory to be retrieved by scales app."""
"""Generate files to put in DAV directory to be retrieved by scales app."""
withCandidate
=
False
withCandidate
=
False
...
...
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