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
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
Alexis AOUN
third-party
Commits
211f61c9
Commit
211f61c9
authored
Jun 30, 2021
by
François
Browse files
Options
Browse Files
Download
Plain Diff
resolved conflict
parents
c9d6fb42
d969d7c1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
168 additions
and
131 deletions
+168
-131
oders_helper_style.css
orders/static/css/oders_helper_style.css
+7
-0
orders_helper.js
orders/static/js/orders_helper.js
+121
-88
views.py
orders/views.py
+1
-1
models.py
products/models.py
+34
-37
urls.py
products/urls.py
+1
-1
views.py
products/views.py
+4
-4
No files found.
orders/static/css/oders_helper_style.css
View file @
211f61c9
...
...
@@ -115,6 +115,13 @@
margin-left
:
5px
;
}
.custom_cell_content
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
}
.product_qty_input
{
width
:
100px
;
}
...
...
orders/static/js/orders_helper.js
View file @
211f61c9
...
...
@@ -111,7 +111,7 @@ function add_product() {
$
.
ajax
({
type
:
'GET'
,
url
:
'/products/get_product_for_
help_order_line
/'
+
product
.
tpl_id
,
url
:
'/products/get_product_for_
order_helper
/'
+
product
.
tpl_id
,
dataType
:
"json"
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
...
...
@@ -123,7 +123,7 @@ function add_product() {
update_main_screen
({
'sort_order_dir'
:
'desc'
});
update_cdb_order
();
}
else
{
alert
(
"L'article n'a pas toutes les caractéristiques pour être ajouté."
)
alert
(
"L'article n'a pas toutes les caractéristiques pour être ajouté."
)
;
}
$
(
"#product_input"
).
val
(
''
);
},
...
...
@@ -136,7 +136,7 @@ function add_product() {
alert
(
'Erreur lors de la récupération des informations, réessayer plus tard.'
);
}
});
return
0
;
}
...
...
@@ -145,13 +145,17 @@ function add_product() {
* Set the computed qty for the first supplier only.
*/
function
compute_products_coverage_qties
()
{
for
(
const
[
key
,
product
]
of
Object
.
entries
(
products
))
{
for
(
const
[
key
,
product
]
of
Object
.
entries
(
products
))
{
let
purchase_qty_for_coverage
=
null
;
// Durée couverture produit = (stock + qté entrante + qté commandée ) / conso quotidienne
const
stock
=
product
.
qty_available
;
const
incoming_qty
=
product
.
incoming_qty
;
const
daily_conso
=
product
.
daily_conso
;
purchase_qty_for_coverage
=
order_doc
.
coverage_days
*
daily_conso
-
stock
-
incoming_qty
;
purchase_qty_for_coverage
=
(
purchase_qty_for_coverage
<
0
)
?
0
:
purchase_qty_for_coverage
;
...
...
@@ -204,6 +208,7 @@ function add_supplier() {
selected_suppliers
.
push
(
supplier
);
let
url
=
"/orders/get_supplier_products"
;
url
+=
"?sid="
+
encodeURIComponent
(
supplier
.
id
);
// Fetch supplier products
...
...
@@ -276,7 +281,8 @@ function save_supplier_product_association(product, supplier, cell) {
// If value is a number
if
(
isNaN
(
package_qty
)
||
isNaN
(
price
))
{
closeModal
();
alert
(
`Les champs "Prix" et "Colisage" doivent être remplis et valides. L'association n'a pas été sauvegardée.`
)
alert
(
`Les champs "Prix" et "Colisage" doivent être remplis et valides. L'association n'a pas été sauvegardée.`
);
return
-
1
;
}
...
...
@@ -284,7 +290,7 @@ function save_supplier_product_association(product, supplier, cell) {
product_tmpl_id
:
product
.
id
,
supplier_id
:
supplier
.
id
,
package_qty
:
package_qty
,
price
:
price
,
price
:
price
};
// Send request to create association
...
...
@@ -297,15 +303,15 @@ function save_supplier_product_association(product, supplier, cell) {
data
:
JSON
.
stringify
(
data
),
success
:
()
=>
{
// Save supplierinfo in product
if
(
!
'suppliersinfo'
in
product
)
{
product
.
suppliersinfo
=
[]
if
(
!
(
'suppliersinfo'
in
product
)
)
{
product
.
suppliersinfo
=
[]
;
}
product
.
suppliersinfo
.
push
({
supplier_id
:
supplier
.
id
,
package_qty
:
package_qty
,
price
:
price
})
})
;
// Save relation locally
save_supplier_products
(
supplier
,
[
product
]);
...
...
@@ -335,6 +341,8 @@ function save_supplier_product_association(product, supplier, cell) {
alert
(
'Erreur lors de la sauvegarde de l
\'
association. Veuillez ré-essayer plus tard.'
);
}
});
return
0
;
}
/**
...
...
@@ -398,8 +406,8 @@ function is_product_related_to_supplier(product, supplier) {
/**
* Update 'purchase_ok' of a product
*
* @param {int} p_id product id
*
* @param {int} p_id product id
* @param {Boolean} npa value to set purchase_ok to
*/
function
set_product_npa
(
p_id
,
npa
)
{
...
...
@@ -420,6 +428,7 @@ function set_product_npa(p_id, npa) {
data
:
JSON
.
stringify
(
data
),
success
:
()
=>
{
const
index
=
products
.
findIndex
(
p
=>
p
.
id
==
p_id
);
products
[
index
].
purchase_ok
=
data
[
"purchase_ok"
];
update_cdb_order
();
...
...
@@ -567,7 +576,7 @@ function order_pill_on_click() {
className
:
"error"
}
);
update_order_selection_screen
()
update_order_selection_screen
()
;
}
else
{
alert
(
'Erreur lors de la récupération de la commande. Si l
\'
erreur persiste, contactez un administrateur svp.'
);
}
...
...
@@ -656,7 +665,7 @@ function create_orders() {
'price_unit'
:
p_supplierinfo
.
price
,
'supplier_taxes_id'
:
p
.
supplier_taxes_id
,
'product_variant_ids'
:
p
.
product_variant_ids
})
})
;
}
}
}
...
...
@@ -664,6 +673,7 @@ function create_orders() {
if
(
Object
.
keys
(
orders_data
.
suppliers_data
).
length
===
0
)
{
closeModal
();
alert
(
"Commande non créée : vous n'avez rentré aucune quantité !"
);
return
-
1
;
}
...
...
@@ -685,9 +695,10 @@ function create_orders() {
'id'
:
new_order
.
id_po
,
'supplier_id'
:
new_order
.
supplier_id
,
'supplier_name'
:
supplier_name
})
})
;
let
new_order_template
=
$
(
"#templates #new_order_item_template"
);
new_order_template
.
find
(
".new_order_supplier_name"
).
text
(
supplier_name
);
new_order_template
.
find
(
".new_order_po"
).
text
(
`PO
${
new_order
.
id_po
}
`
);
new_order_template
.
find
(
".download_order_file_button"
).
attr
(
'id'
,
`download_attachment_
${
new_order
.
id_po
}
`
);
...
...
@@ -708,7 +719,8 @@ function create_orders() {
closeModal
();
},
error
:
function
(
data
)
{
let
msg
=
"erreur serveur lors de la création des product orders"
let
msg
=
"erreur serveur lors de la création des product orders"
;
err
=
{
msg
:
msg
,
ctx
:
'save_supplier_product_association'
,
data
:
orders_data
};
if
(
typeof
data
.
responseJSON
!=
'undefined'
&&
typeof
data
.
responseJSON
.
error
!=
'undefined'
)
{
err
.
msg
+=
' : '
+
data
.
responseJSON
.
error
;
...
...
@@ -719,6 +731,8 @@ function create_orders() {
alert
(
'Erreur lors de la création des commandes. Veuillez ré-essayer plus tard.'
);
}
});
return
0
;
}
/**
...
...
@@ -741,11 +755,11 @@ function get_order_attachments() {
contentType
:
"application/json; charset=utf-8"
,
success
:
function
(
data
)
{
for
(
let
res_po
of
data
.
res
)
{
$
(
`#download_attachment_
${
res_po
.
id_po
}
`
).
attr
(
'href'
,
`
${
odoo_server
}
/web/content/
${
res_po
.
id_attachment
}
?download=true`
)
$
(
`#download_attachment_
${
res_po
.
id_po
}
`
).
attr
(
'href'
,
`
${
odoo_server
}
/web/content/
${
res_po
.
id_attachment
}
?download=true`
)
;
}
$
(
'#created_orders_area .download_order_file_loading'
).
hide
()
$
(
'#created_orders_area .download_order_file_button'
).
show
()
$
(
'#created_orders_area .download_order_file_loading'
).
hide
()
;
$
(
'#created_orders_area .download_order_file_button'
).
show
()
;
},
error
:
function
()
{
$
.
notify
(
...
...
@@ -755,7 +769,7 @@ function get_order_attachments() {
className
:
"error"
}
);
setTimeout
(
get_order_attachments
,
10000
);
}
});
...
...
@@ -787,8 +801,10 @@ function back() {
* Create a string to represent a supplier column in product data
* @returns String
*/
function
supplier_column_name
(
supplier
)
{
const
supplier_id
=
(
'supplier_id'
in
supplier
)
?
supplier
.
supplier_id
:
supplier
.
id
function
supplier_column_name
(
supplier
)
{
const
supplier_id
=
(
'supplier_id'
in
supplier
)
?
supplier
.
supplier_id
:
supplier
.
id
;
return
`qty_supplier_
${
supplier_id
}
`
;
}
...
...
@@ -833,15 +849,16 @@ function _compute_product_data(product) {
let
item
=
{};
/* Supplier related data */
let
purchase_qty
=
0
;
// Calculate product's total purchase qty
let
p_package_qties
=
[];
// Look for differences in package qties
let
purchase_qty
=
0
;
// Calculate product's total purchase qty
let
p_package_qties
=
[];
// Look for differences in package qties
for
(
let
p_supplierinfo
of
product
.
suppliersinfo
)
{
// Preset qty for input if product related to supplier: existing qty or null (null -> qty to be set, display an empty input)
let
supplier_qty
=
(
"qty"
in
p_supplierinfo
)
?
p_supplierinfo
.
qty
:
null
;
item
[
supplier_column_name
(
p_supplierinfo
)]
=
supplier_qty
;
// Update product's total qty to buy if qty set for this supplier
// Update product's total qty to buy if qty set for this supplier
if
(
supplier_qty
!==
null
)
{
purchase_qty
+=
+
parseFloat
(
supplier_qty
*
p_supplierinfo
.
package_qty
).
toFixed
(
2
);
}
...
...
@@ -859,26 +876,27 @@ function _compute_product_data(product) {
}
}
if
(
p_package_qties
.
every
(
(
val
,
i
,
arr
)
=>
val
===
arr
[
0
]
))
{
if
(
p_package_qties
.
length
==
0
||
!
p_package_qties
.
every
((
val
,
i
,
arr
)
=>
val
===
arr
[
0
]))
{
// Don't display package qty if no supplierinf or if not all package qties are equals,
item
.
package_qty
=
'X'
;
}
else
{
// If all package qties are equals, display it
item
.
package_qty
=
p_package_qties
[
0
];
}
else
{
// Else display an X
item
.
package_qty
=
'X'
;
}
/* Coverage related data */
if
(
order_doc
.
coverage_days
!==
null
)
{
let
unmet_needs
=
product
.
daily_conso
*
order_doc
.
coverage_days
-
product
.
qty_available
-
product
.
incoming_qty
-
purchase_qty
;
unmet_needs
=
-
Math
.
round
(
unmet_needs
);
unmet_needs
=
(
unmet_needs
>
0
)
?
0
:
unmet_needs
;
item
.
unmet_needs
=
unmet_needs
;
}
else
{
item
.
unmet_needs
=
'X'
;
}
return
item
return
item
;
}
/**
...
...
@@ -992,20 +1010,23 @@ function prepare_datatable_columns() {
const
base_id
=
`product_
${
full
.
id
}
_supplier_
${
supplier
.
id
}
`
;
if
(
data
===
false
)
{
return
`<div id="
${
base_id
}
_cell_content" class="cell_content">X</div>`
;
return
`<div id="
${
base_id
}
_cell_content" class="c
ustom_c
ell_content">X</div>`
;
}
else
{
let
content
=
`<div id="
${
base_id
}
_cell_content" class="
cell_content">
let
content
=
`<div id="
${
base_id
}
_cell_content" class="custom_
cell_content">
<input type="number" class="product_qty_input" id="
${
base_id
}
_qty_input" min="0" value=
${
data
}
>`
;
if
(
full
.
package_qty
===
'X'
)
{
let
product_data
=
products
.
find
(
p
=>
p
.
id
==
full
.
id
);
if
(
product_data
!==
undefined
)
{
let
supplierinfo
=
product_data
.
suppliersinfo
.
find
(
psi
=>
psi
.
supplier_id
==
supplier
.
id
);
content
+=
`<span class="supplier_package_qty">Colisage :
${
supplierinfo
.
package_qty
}
</span>`
;
}
}
content
+=
`</div>`
content
+=
`</div>`
;
return
content
;
}
}
...
...
@@ -1016,14 +1037,6 @@ function prepare_datatable_columns() {
data
:
"package_qty"
,
title
:
"Colisage"
,
className
:
"dt-body-center"
,
render
:
(
data
,
type
,
full
)
=>
{
if
(
full
.
package_qty
===
'X'
)
{
return
'<div class="tooltip">'
+
data
+
' <span class="tooltiptext tt_twolines">Colisages différents !</span></div>'
}
else
{
return
data
;
}
},
width
:
"4%"
});
...
...
@@ -1072,6 +1085,7 @@ function display_products(params) {
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
;
}
...
...
@@ -1109,6 +1123,7 @@ function display_products(params) {
// On inputs change
$
(
'#products_table'
).
on
(
'change'
,
'tbody td .product_qty_input'
,
function
()
{
let
val
=
(
$
(
this
).
val
()
==
''
)
?
0
:
$
(
this
).
val
();
val
=
parseFloat
(
val
);
// If value is a number
...
...
@@ -1120,11 +1135,13 @@ function display_products(params) {
// Save value
save_product_supplier_qty
(
prod_id
,
supplier_id
,
val
);
// Update row
const
product
=
products
.
find
(
p
=>
p
.
id
==
prod_id
);
const
new_row_data
=
prepare_datatable_data
([
product
.
id
])[
0
];
products_table
.
row
(
$
(
this
).
closest
(
'tr'
)).
data
(
new_row_data
).
draw
();
products_table
.
row
(
$
(
this
).
closest
(
'tr'
)).
data
(
new_row_data
)
.
draw
();
update_cdb_order
();
}
else
{
...
...
@@ -1159,9 +1176,10 @@ function display_products(params) {
false
);
// Find existing price in another supplierinfo
// Find existing price in another supplierinfo
let
default_price
=
null
;
let
default_package_qty
=
1
;
// Default package qty is 1
let
default_package_qty
=
1
;
// Default package qty is 1
for
(
let
psi
of
product
.
suppliersinfo
)
{
if
(
'price'
in
psi
&&
psi
.
price
!==
null
)
{
default_price
=
psi
.
price
;
...
...
@@ -1173,13 +1191,13 @@ function display_products(params) {
}
// Set default value for price & package qty for new supplierinfo
$
(
".new_product_supplier_package_pty"
).
val
(
default_package_qty
);
$
(
".new_product_supplier_price"
).
val
(
default_price
);
// Default price is existing price for other supplier, or none if no other
$
(
".new_product_supplier_package_pty"
).
val
(
default_package_qty
);
$
(
".new_product_supplier_price"
).
val
(
default_price
);
// Default price is existing price for other supplier, or none if no other
new_product_supplier_association
=
{
package_qty
:
default_package_qty
,
price
:
default_price
}
}
;
$
(
'.new_product_supplier_price'
).
on
(
'input'
,
function
()
{
new_product_supplier_association
.
price
=
$
(
this
).
val
();
});
...
...
@@ -1213,6 +1231,7 @@ function display_products(params) {
// Save / unsave selected row
const
p_id
=
products_table
.
row
(
$
(
this
).
closest
(
'tr'
)).
data
().
id
;
if
(
this
.
checked
)
{
selected_rows
.
push
(
p_id
);
}
else
{
...
...
@@ -1302,7 +1321,9 @@ function update_main_screen(params) {
if
(
order_doc
.
date_planned
!==
null
)
{
// Switch format from yy-mm-dd hh:mm:ss to readable dd/mm/yy
let
date_to_format
=
order_doc
.
date_planned
.
split
(
' '
)[
0
];
let
readable_date
=
date_to_format
.
split
(
'-'
).
reverse
().
join
(
'/'
);
let
readable_date
=
date_to_format
.
split
(
'-'
).
reverse
()
.
join
(
'/'
);
$
(
"#date_planned_input"
).
val
(
readable_date
);
}
else
{
$
(
"#date_planned_input"
).
val
(
''
);
...
...
@@ -1363,11 +1384,11 @@ function switch_screen(direction = 'main_screen', from = 'main_screen') {
let
oldBox
=
null
;
let
newBox
=
null
;
let
outerWidth
=
null
;
if
(
direction
===
'main_screen'
)
{
oldBox
=
$
(
"#select_order_content"
);
newBox
=
$
(
"#main_content"
);
outerWidth
=
oldBox
.
outerWidth
(
true
);
}
else
{
if
(
from
===
'orders_created'
)
{
...
...
@@ -1375,12 +1396,12 @@ function switch_screen(direction = 'main_screen', from = 'main_screen') {
}
else
{
oldBox
=
$
(
"#main_content"
);
}
newBox
=
$
(
"#select_order_content"
);
outerWidth
=
-
oldBox
.
outerWidth
(
true
);
}
// Display the new box and place it on the right of the screen
newBox
.
css
({
"left"
:
outerWidth
+
"px"
,
"right"
:
-
outerWidth
+
"px"
,
"display"
:
""
});
// Make the old content slide to the left
...
...
@@ -1441,6 +1462,7 @@ $(document).ready(function() {
$
(
"#coverage_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
let
val
=
$
(
"#coverage_days_input"
).
val
();
val
=
parseInt
(
val
);
if
(
!
isNaN
(
val
))
{
...
...
@@ -1450,7 +1472,7 @@ $(document).ready(function() {
update_main_screen
();
}
else
{
$
(
"#coverage_days_input"
).
val
(
order_doc
.
coverage_days
);
alert
(
`Valeur non valide pour le nombre de jours de couverture !`
)
alert
(
`Valeur non valide pour le nombre de jours de couverture !`
)
;
}
});
...
...
@@ -1474,8 +1496,9 @@ $(document).ready(function() {
$
(
'#create_orders'
).
on
(
'click'
,
function
()
{
if
(
order_doc
.
date_planned
===
null
)
{
alert
(
"Veuillez rentrer une date de livraison prévue."
)
return
-
1
alert
(
"Veuillez rentrer une date de livraison prévue."
);
return
-
1
;
}
let
modal_create_order
=
$
(
'#templates #modal_create_order'
);
...
...
@@ -1488,6 +1511,8 @@ $(document).ready(function() {
'Valider'
,
false
);
return
0
;
});
$
.
datepicker
.
regional
[
'fr'
]
=
{
...
...
@@ -1514,12 +1539,13 @@ $(document).ready(function() {
'Ve'
,
'Sa'
],
dateFormat
:
date_format
,
dateFormat
:
date_format
};
$
.
datepicker
.
setDefaults
(
$
.
datepicker
.
regional
[
'fr'
]);
const
tomorrow
=
new
Date
()
tomorrow
.
setDate
(
tomorrow
.
getDate
()
+
1
)
const
tomorrow
=
new
Date
();
tomorrow
.
setDate
(
tomorrow
.
getDate
()
+
1
);
$
(
"#date_planned_input"
)
.
datepicker
({
...
...
@@ -1531,9 +1557,12 @@ $(document).ready(function() {
// When date input changes, try to read date
$
.
datepicker
.
parseDate
(
date_format
,
$
(
this
).
val
());
// No exception raised: date is valid.
// No exception raised: date is valid.
// Change format from readable (dd/mm/yy) to ISO (yy-mm-dd)
let
formatted_date
=
$
(
this
).
val
().
split
(
'/'
).
reverse
().
join
(
'-'
)
+
' 00:00:00'
;
let
formatted_date
=
$
(
this
).
val
()
.
split
(
'/'
)
.
reverse
()
.
join
(
'-'
)
+
' 00:00:00'
;
// Update doc if changed
if
(
formatted_date
!==
order_doc
.
date_planned
)
{
...
...
@@ -1576,7 +1605,7 @@ $(document).ready(function() {
source
:
suppliers_list
.
map
(
a
=>
a
.
display_name
)
});
},
error
:
function
(
data
)
{
err
=
{
msg
:
"erreur serveur lors de la récupération des fournisseurs"
,
ctx
:
'get_suppliers'
};
...
...
@@ -1592,25 +1621,27 @@ $(document).ready(function() {
//Get products
var
accentMap
=
{
"á"
:
"a"
,
"à"
:
"a"
,
"â"
:
"a"
,
"é"
:
"e"
,
"è"
:
"e"
,
"ê"
:
"e"
,
"ë"
:
"e"
,
"ç"
:
"c"
,
"ù"
:
"u"
,
"ü"
:
"u"
,
"ö"
:
"o"
"á"
:
"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
;
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
({
...
...
@@ -1624,12 +1655,14 @@ $(document).ready(function() {
// 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
)
);
})
);
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"
}
});
...
...
orders/views.py
View file @
211f61c9
...
...
@@ -42,7 +42,7 @@ def get_supplier_products(request):
""" Get supplier products """
sid
=
request
.
GET
.
get
(
'sid'
,
''
)
res
=
CagetteProducts
.
get_products_
by_suppli
er
(
sid
)
res
=
CagetteProducts
.
get_products_
for_order_help
er
(
sid
)
if
'error'
in
res
:
return
JsonResponse
(
res
,
status
=
500
)
...
...
products/models.py
View file @
211f61c9
...
...
@@ -171,19 +171,6 @@ 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."""
...
...
@@ -468,7 +455,12 @@ class CagetteProducts(models.Model):
return
res
@staticmethod
def
get_products_by_supplier
(
supplier_id
):
def
get_products_for_order_helper
(
supplier_id
,
pids
=
[]):
"""
One of the two parameters must be set.
Get products by supplier if a supplier_id is set.
If supplier_id is None, get products specified in pids.
"""
api
=
OdooAPI
()
res
=
{}
...
...
@@ -476,18 +468,21 @@ class CagetteProducts(models.Model):
try
:
today
=
datetime
.
date
.
today
()
.
strftime
(
"
%
Y-
%
m-
%
d"
)
# Get products/supplier relation
f
=
[
"product_tmpl_id"
,
'date_start'
,
'date_end'
,
'package_qty'
,
'price'
]
c
=
[[
'name'
,
'='
,
int
(
supplier_id
)]]
psi
=
api
.
search_read
(
'product.supplierinfo'
,
c
,
f
)
# Filter valid data
ptids
=
[]
for
p
in
psi
:
if
(
p
[
"product_tmpl_id"
]
is
not
False
and
(
p
[
"date_start"
]
is
False
or
p
[
"date_end"
]
is
not
False
and
p
[
"date_start"
]
<=
today
)
and
(
p
[
"date_end"
]
is
False
or
p
[
"date_end"
]
is
not
False
and
p
[
"date_end"
]
>=
today
)):
ptids
.
append
(
p
[
"product_tmpl_id"
][
0
])
if
supplier_id
is
not
None
:
# Get products/supplier relation
f
=
[
"product_tmpl_id"
,
'date_start'
,
'date_end'
,
'package_qty'
,
'price'
]
c
=
[[
'name'
,
'='
,
int
(
supplier_id
)]]
psi
=
api
.
search_read
(
'product.supplierinfo'
,
c
,
f
)
# Filter valid data
ptids
=
[]
for
p
in
psi
:
if
(
p
[
"product_tmpl_id"
]
is
not
False
and
(
p
[
"date_start"
]
is
False
or
p
[
"date_end"
]
is
not
False
and
p
[
"date_start"
]
<=
today
)
and
(
p
[
"date_end"
]
is
False
or
p
[
"date_end"
]
is
not
False
and
p
[
"date_end"
]
>=
today
)):
ptids
.
append
(
p
[
"product_tmpl_id"
][
0
])
else
:
ptids
=
pids
# Get products templates
f
=
[
...
...
@@ -506,10 +501,11 @@ class CagetteProducts(models.Model):
products_t
=
api
.
search_read
(
'product.template'
,
c
,
f
)
filtered_products_t
=
[
p
for
p
in
products_t
if
p
[
"state"
]
!=
"end"
and
p
[
"state"
]
!=
"obsolete"
]
sales_average_params
=
{
'ids'
:
ptids
,
#'from': '2019-06-10',
#'to': '2019-08-10',
}
sales_average_params
=
{
'ids'
:
ptids
,
#'from': '2019-06-10',
#'to': '2019-08-10',
}
sales
=
CagetteProducts
.
get_template_products_sales_average
(
sales_average_params
)
if
'list'
in
sales
and
len
(
sales
[
'list'
])
>
0
:
...
...
@@ -519,12 +515,13 @@ class CagetteProducts(models.Model):
# Add supplier data to product data
for
i
,
fp
in
enumerate
(
filtered_products_t
):
psi_item
=
next
(
item
for
item
in
psi
if
item
[
"product_tmpl_id"
]
is
not
False
and
item
[
"product_tmpl_id"
][
0
]
==
fp
[
"id"
])
filtered_products_t
[
i
][
'suppliersinfo'
]
=
[{
'supplier_id'
:
int
(
supplier_id
),
'package_qty'
:
psi_item
[
"package_qty"
],
'price'
:
psi_item
[
"price"
]
}]
if
supplier_id
is
not
None
:
psi_item
=
next
(
item
for
item
in
psi
if
item
[
"product_tmpl_id"
]
is
not
False
and
item
[
"product_tmpl_id"
][
0
]
==
fp
[
"id"
])
filtered_products_t
[
i
][
'suppliersinfo'
]
=
[{
'supplier_id'
:
int
(
supplier_id
),
'package_qty'
:
psi_item
[
"package_qty"
],
'price'
:
psi_item
[
"price"
]
}]
for
s
in
sales
:
if
s
[
"id"
]
==
fp
[
"id"
]:
...
...
@@ -534,7 +531,7 @@ class CagetteProducts(models.Model):
res
[
"products"
]
=
filtered_products_t
except
Exception
as
e
:
coop_logger
.
error
(
'get_products_
by_suppli
er
%
s (
%
s)'
,
str
(
e
),
str
(
supplier_id
))
coop_logger
.
error
(
'get_products_
for_order_help
er
%
s (
%
s)'
,
str
(
e
),
str
(
supplier_id
))
res
[
"error"
]
=
str
(
e
)
return
res
...
...
products/urls.py
View file @
211f61c9
...
...
@@ -5,7 +5,7 @@ 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_for_
order_helper/([0-9]+)$'
,
views
.
get_product_for_order_helper
),
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 @
211f61c9
...
...
@@ -39,12 +39,12 @@ def get_simple_list(request):
return
JsonResponse
(
res
,
safe
=
False
)
def
get_product_for_
help_order_line
(
request
,
tpl_id
):
def
get_product_for_
order_helper
(
request
,
tpl_id
):
res
=
{}
try
:
result
=
CagetteProduct
.
get_product_for_help_order_line
(
tpl_id
)
if
len
(
result
)
==
1
:
res
=
result
[
0
]
result
=
CagetteProduct
s
.
get_products_for_order_helper
(
None
,
[
int
(
tpl_id
)]
)
if
len
(
result
[
"products"
]
)
==
1
:
res
=
result
[
"products"
][
0
]
except
Exception
as
e
:
coop_logger
.
error
(
"get_product_for_help_order_line :
%
s"
,
str
(
e
))
res
[
'error'
]
=
str
(
e
)
...
...
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