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
e1fd3ba1
Commit
e1fd3ba1
authored
May 17, 2021
by
Damien Moulard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
deal with multiple suppliers
parent
1eced1bc
Pipeline
#940
passed with stage
in 20 seconds
Changes
3
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
165 additions
and
76 deletions
+165
-76
oders_helper_style.css
orders/static/css/oders_helper_style.css
+5
-0
orders_helper.js
orders/static/js/orders_helper.js
+160
-75
models.py
products/models.py
+0
-1
No files found.
orders/static/css/oders_helper_style.css
View file @
e1fd3ba1
...
...
@@ -7,3 +7,7 @@
margin-right
:
10px
;
border-radius
:
5px
;
}
.product_qty_input
{
width
:
100px
;
}
\ No newline at end of file
orders/static/js/orders_helper.js
View file @
e1fd3ba1
...
...
@@ -3,43 +3,177 @@ var suppliers_list = [],
selected_suppliers
=
[],
products
=
[];
const
datatable_base_columns
=
[
'Produit'
]
/**
* Add a supplier to the selected suppliers list.
* @returns -1 if validation failed, void otherwise
*/
function
add_supplier
()
{
const
user_input
=
$
(
"#supplier_input"
).
val
();
// Check if user input is a valid supplier
const
supplier
=
suppliers_list
.
find
(
s
=>
s
.
display_name
===
user_input
)
if
(
supplier
===
undefined
)
{
alert
(
"Le fournisseur renseigné n'est pas valide.
\
n"
+
"Veuillez sélectionner un fournisseur dans la liste déroulante."
);
return
-
1
;
}
const
supplier_selected
=
selected_suppliers
.
find
(
s
=>
s
.
display_name
===
user_input
)
if
(
supplier_selected
!==
undefined
)
{
alert
(
"Ce fournisseur est déjà sélectionné."
);
return
-
1
;
}
openModal
();
selected_suppliers
.
push
(
supplier
);
let
url
=
"/orders/get_supplier_products"
;
url
+=
"?sid="
+
encodeURIComponent
(
supplier
.
id
);
// Fetch supplier products
$
.
ajax
({
type
:
'GET'
,
url
:
url
,
dataType
:
"json"
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
success
:
function
(
data
)
{
save_supplier_products
(
supplier
,
data
.
res
.
products
);
display_products
();
$
(
"#supplier_input"
).
val
(
""
)
closeModal
();
},
error
:
function
(
data
)
{
err
=
{
msg
:
"erreur serveur lors de la récupération des produits"
,
ctx
:
'get_supplier_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 produits, réessayer plus tard.'
);
}
});
}
/**
* When products are fetched, save them and the relation with the supplier.
* If product already saved, add the supplier to its suppliers list.
* Else, add product with supplier.
*
* @param {object} supplier
* @param {array} new_products
*/
function
save_supplier_products
(
supplier
,
new_products
)
{
products
=
products
.
concat
(
new_products
);
for
(
np
of
new_products
)
{
let
index
=
products
.
findIndex
(
p
=>
p
.
id
===
np
.
id
);
if
(
index
===
-
1
)
{
np
.
suppliers
=
[
supplier
];
products
.
push
(
np
)
}
else
{
products
[
index
].
suppliers
.
push
(
supplier
)
}
}
}
/**
* Look in the 'suppliers' property of a product
*
* @param {object} product
* @param {object} supplier
* @returns boolean
*/
function
is_product_related_to_supplier
(
product
,
supplier
)
{
return
product
.
suppliers
.
find
(
s
=>
s
.
id
===
supplier
.
id
)
!==
undefined
;
}
/**
* Create a string to represent a supplier column in product data
* @returns String
*/
function
supplier_column_name
(
supplier
)
{
let
parsed_name
=
supplier
.
display_name
parsed_name
=
parsed_name
.
toLowerCase
().
replaceAll
(
/
\s
+/g
,
" "
).
trim
()
parsed_name
=
parsed_name
.
replaceAll
(
" "
,
"_"
);
return
`supplier_
${
parsed_name
}
`
;
}
/* DATATABLE */
/**
* @returns Array of formatted data for datatable data setup
*/
function
prepare_datatable_data
()
{
let
data
=
[];
for
(
product
of
products
)
{
let
item
=
{
name
:
product
.
name
}
for
(
supplier
of
selected_suppliers
)
{
// If product not related to supplier : false ; else null (value to be set)
item
[
supplier_column_name
(
supplier
)]
=
is_product_related_to_supplier
(
product
,
supplier
)
?
null
:
false
;
}
data
.
push
(
item
);
}
return
data
;
}
/**
* @returns Array of formatted data for datatable columns setup
*/
function
prepare_datatable_columns
()
{
columns
=
[
{
data
:
"name"
,
title
:
"Produit"
,
}
];
for
(
supplier
of
selected_suppliers
)
{
columns
.
push
({
data
:
supplier_column_name
(
supplier
),
title
:
supplier
.
display_name
,
width
:
"8%"
,
className
:
"dt-body-center"
,
render
:
function
(
data
,
type
,
full
)
{
if
(
data
===
false
)
{
return
"X"
;
}
else
{
return
`<input type="number" class="product_qty_input">`
}
}
})
}
// TODO: Map supplier and products
// TODO: Concatenate same product in products list
return
columns
;
}
/**
* Display the Datatable containing the products
*/
function
display_products
()
{
// Empty datatable if already exists
if
(
products_table
)
{
products_table
.
destroy
();
}
/*
* TODO:
* - prepare data for datatable:
* for each product: 1 column for each supplier
* if product not related to the supplier: 'X' (clikable -> value = '')
* else: '' (render input)
* - dynamically add columns to datatables
* - remove "width: 100%" from table and allow vertical scrolling in case of many suppliers
* ...
*/
products_table
.
clear
().
destroy
();
$
(
'#products_table'
).
empty
();
}
const
data
=
prepare_datatable_data
();
const
columns
=
prepare_datatable_columns
();
products_table
=
$
(
'#products_table'
).
DataTable
({
data
:
products
,
columns
:[
{
data
:
"name"
,
title
:
"Produit"
}
],
data
:
data
,
columns
:
columns
,
order
:
[
[
0
,
1
,
"asc"
]
],
...
...
@@ -87,55 +221,6 @@ $(document).ready(function() {
$
(
"#supplier_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
const
user_input
=
$
(
"#supplier_input"
).
val
();
// Check if user input is a valid supplier
let
supplier
=
null
;
for
(
const
supplier_item
of
suppliers_list
)
{
if
(
user_input
===
supplier_item
.
display_name
)
{
supplier
=
supplier_item
;
}
}
if
(
supplier
!=
null
)
{
openModal
();
selected_suppliers
.
push
(
supplier
);
let
url
=
"/orders/get_supplier_products"
;
url
+=
"?sid="
+
encodeURIComponent
(
supplier
.
id
);
// Fetch supplier products
$
.
ajax
({
type
:
'GET'
,
url
:
url
,
dataType
:
"json"
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
success
:
function
(
data
)
{
save_supplier_products
(
supplier
,
data
.
res
.
products
);
// TODO: display suppliers on page
display_products
();
$
(
"#supplier_input"
).
val
(
""
)
closeModal
();
},
error
:
function
(
data
)
{
err
=
{
msg
:
"erreur serveur lors de la récupération des produits"
,
ctx
:
'get_supplier_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 produits, réessayer plus tard.'
);
}
});
}
else
{
alert
(
"Le fournisseur renseigné n'est pas valide.
\
n"
+
"Veuillez sélectionner un fournisseur dans la liste déroulante."
)
}
add_supplier
();
})
});
products/models.py
View file @
e1fd3ba1
...
...
@@ -396,7 +396,6 @@ class CagetteProducts(models.Model):
# todo : try with no result
try
:
today
=
datetime
.
date
.
today
()
.
strftime
(
"
%
Y-
%
m-
%
d"
)
print
(
today
)
# Get products/supplier relation
f
=
[
"product_tmpl_id"
,
'date_start'
,
'date_end'
]
...
...
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