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
261
Issues
261
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
Paul
third-party
Commits
191b57a5
Commit
191b57a5
authored
Jul 02, 2021
by
Damien Moulard
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'aide_a_la_commande' into dev_cooperatic
parents
32fe6120
e94b0ad6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
244 additions
and
223 deletions
+244
-223
oders_helper_style.css
orders/static/css/oders_helper_style.css
+5
-1
orders_helper.js
orders/static/js/orders_helper.js
+221
-213
models.py
products/models.py
+4
-3
helper.html
templates/orders/helper.html
+14
-6
No files found.
orders/static/css/oders_helper_style.css
View file @
191b57a5
...
...
@@ -2,7 +2,7 @@
position
:
relative
;
}
.page_content
{
.page_content
,
.login_area
{
position
:
absolute
;
top
:
0
;
left
:
0
;
...
...
@@ -154,6 +154,10 @@
cursor
:
pointer
;
}
.product_not_from_supplier
:hover
{
background-color
:
#c7cace
;
}
.product_name
,
.supplier_name
,
.product_npa
{
font-weight
:
bold
;
}
...
...
orders/static/js/orders_helper.js
View file @
191b57a5
...
...
@@ -187,7 +187,7 @@ function check_products_data() {
"Vérfication des informations produits..."
,
{
globalPosition
:
"top left"
,
className
:
"
warning
"
className
:
"
info
"
}
);
...
...
@@ -823,6 +823,8 @@ function create_orders() {
contentType
:
"application/json; charset=utf-8"
,
data
:
JSON
.
stringify
(
orders_data
),
success
:
(
result
)
=>
{
$
(
'#created_orders_area'
).
empty
();
// Display new orders
for
(
let
new_order
of
result
.
res
.
created
)
{
const
supplier_name
=
suppliers_list
.
find
(
s
=>
s
.
id
==
new_order
.
supplier_id
).
display_name
;
...
...
@@ -1037,12 +1039,11 @@ function _compute_product_data(product) {
let
days_covered
=
0
;
if
(
product
.
daily_conso
!==
0
)
{
qty_not_covered
=
product
.
daily_conso
*
order_doc
.
coverage_days
-
product
.
qty_available
-
product
.
incoming_qty
-
purchase_qty
;
days_covered
=
qty_not_covered
/
product
.
daily_conso
;
qty_not_covered
=
-
Math
.
ceil
(
qty_not_covered
);
// round up, so if a value is not fully covered display it
qty_not_covered
=
(
qty_not_covered
>
0
)
?
0
:
qty_not_covered
;
// only display qty not covered (neg value)
days_covered
=
-
Math
.
ceil
(
days_covered
);
days_covered
=
(
product
.
qty_available
+
product
.
incoming_qty
+
purchase_qty
)
/
product
.
daily_conso
;
days_covered
=
Math
.
floor
(
days_covered
);
}
item
.
qty_not_covered
=
qty_not_covered
;
...
...
@@ -1469,7 +1470,7 @@ function display_total_values() {
let
order_total_value
=
0
;
for
(
let
supplier
of
selected_suppliers
)
{
$
(
`#pill_supplier_
${
supplier
.
id
}
`
).
find
(
'.supplier_total_value'
).
text
(
supplier
.
total_value
);
$
(
`#pill_supplier_
${
supplier
.
id
}
`
).
find
(
'.supplier_total_value'
).
text
(
parseFloat
(
supplier
.
total_value
).
toFixed
(
2
)
);
order_total_value
+=
supplier
.
total_value
;
}
...
...
@@ -1637,243 +1638,250 @@ function init_pouchdb_sync() {
$
(
document
).
ready
(
function
()
{
fingerprint
=
new
Fingerprint
({
canvas
:
true
}).
get
();
$
.
ajaxSetup
({
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)
}
});
if
(
coop_is_connected
())
{
$
(
'#new_order_form'
).
show
();
$
(
'#existing_orders_area'
).
show
();
openModal
();
fingerprint
=
new
Fingerprint
({
canvas
:
true
}).
get
();
$
.
ajaxSetup
({
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)
}
});
init_pouchdb_sync
();
openModal
();
// Main screen
$
(
"#coverage_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
if
(
is_time_to
(
'submit_coverage_form'
,
1000
))
{
let
val
=
$
(
"#coverage_days_input"
).
val
();
val
=
parseInt
(
val
);
if
(
!
isNaN
(
val
))
{
order_doc
.
coverage_days
=
val
;
compute_products_coverage_qties
();
update_cdb_order
();
update_main_screen
();
}
else
{
$
(
"#coverage_days_input"
).
val
(
order_doc
.
coverage_days
);
alert
(
`Valeur non valide pour le nombre de jours de couverture !`
);
init_pouchdb_sync
();
// Main screen
$
(
"#coverage_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
if
(
is_time_to
(
'submit_coverage_form'
,
1000
))
{
let
val
=
$
(
"#coverage_days_input"
).
val
();
val
=
parseInt
(
val
);
if
(
!
isNaN
(
val
))
{
order_doc
.
coverage_days
=
val
;
compute_products_coverage_qties
();
update_cdb_order
();
update_main_screen
();
}
else
{
$
(
"#coverage_days_input"
).
val
(
order_doc
.
coverage_days
);
alert
(
`Valeur non valide pour le nombre de jours de couverture !`
);
}
}
}
});
});
$
(
"#supplier_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
if
(
is_time_to
(
'add_product'
,
1000
))
{
add_supplier
();
}
});
$
(
"#supplier_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
if
(
is_time_to
(
'add_product'
,
1000
))
{
add_supplier
();
}
});
$
(
"#product_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
if
(
is_time_to
(
'add_product'
,
1000
))
{
add_product
();
}
});
$
(
"#product_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
if
(
is_time_to
(
'add_product'
,
1000
))
{
add_product
();
}
});
$
(
"#do_inventory"
).
on
(
"click"
,
function
()
{
if
(
is_time_to
(
'generate_inventory'
,
1000
))
{
generate_inventory
();
}
});
$
(
"#do_inventory"
).
on
(
"click"
,
function
()
{
if
(
is_time_to
(
'generate_inventory'
,
1000
))
{
generate_inventory
();
}
});
$
(
'#back_to_order_selection_from_main'
).
on
(
'click'
,
function
()
{
if
(
is_time_to
(
'back_to_order_selection_from_main'
,
1000
))
{
back
();
}
});
$
(
'#back_to_order_selection_from_main'
).
on
(
'click'
,
function
()
{
if
(
is_time_to
(
'back_to_order_selection_from_main'
,
1000
))
{
back
();
}
});
$
(
'#create_orders'
).
on
(
'click'
,
function
()
{
if
(
is_time_to
(
'create_orders'
,
1000
))
{
let
modal_create_order
=
$
(
'#templates #modal_create_order'
);
modal_create_order
.
find
(
'.suppliers_date_planned_area'
).
empty
();
for
(
let
supplier
of
selected_suppliers
)
{
let
supplier_date_planned_template
=
$
(
'#templates #modal_create_order__supplier_date_planned'
);
$
(
'#create_orders'
).
on
(
'click'
,
function
()
{
if
(
is_time_to
(
'create_orders'
,
1000
))
{
let
modal_create_order
=
$
(
'#templates #modal_create_order'
);
modal_create_order
.
find
(
'.suppliers_date_planned_area'
).
empty
();
supplier_date_planned_template
.
find
(
".supplier_name"
).
text
(
supplier
.
display_name
);
supplier_date_planned_template
.
find
(
".modal_input_container"
).
attr
(
'id'
,
`container_date_planned_supplier_
${
supplier
.
id
}
`
);
modal_create_order
.
find
(
'.suppliers_date_planned_area'
).
append
(
supplier_date_planned_template
.
html
());
}
openModal
(
modal_create_order
.
html
(),
()
=>
{
if
(
is_time_to
(
'validate_create_orders'
))
{
create_orders
();
}
},
'Valider'
,
false
);
// Add id to input once modal is displayed
for
(
let
supplier
of
selected_suppliers
)
{
$
(
`#modal #container_date_planned_supplier_
${
supplier
.
id
}
`
).
find
(
".supplier_date_planned"
).
attr
(
'id'
,
`date_planned_supplier_
${
supplier
.
id
}
`
);
}
$
(
"#modal .supplier_date_planned"
)
.
datepicker
({
defaultDate
:
"+1d"
,
minDate
:
new
Date
()
})
.
on
(
'change'
,
function
()
{
try
{
// When date input changes, try to read date
$
.
datepicker
.
parseDate
(
date_format
,
$
(
this
).
val
());
}
catch
{
alert
(
'Date invalide'
);
$
(
this
).
val
(
''
);
}
});
}
for
(
let
supplier
of
selected_suppliers
)
{
let
supplier_date_planned_template
=
$
(
'#templates #modal_create_order__supplier_date_planned'
);
return
0
;
});
supplier_date_planned_template
.
find
(
".supplier_name"
).
text
(
supplier
.
display_name
);
supplier_date_planned_template
.
find
(
".modal_input_container"
).
attr
(
'id'
,
`container_date_planned_supplier_
${
supplier
.
id
}
`
);
modal_create_order
.
find
(
'.suppliers_date_planned_area'
).
append
(
supplier_date_planned_template
.
html
());
}
openModal
(
modal_create_order
.
html
(),
()
=>
{
if
(
is_time_to
(
'validate_create_orders'
))
{
create_orders
();
}
},
'Valider'
,
false
);
// Add id to input once modal is displayed
for
(
let
supplier
of
selected_suppliers
)
{
$
(
`#modal #container_date_planned_supplier_
${
supplier
.
id
}
`
).
find
(
".supplier_date_planned"
).
attr
(
'id'
,
`date_planned_supplier_
${
supplier
.
id
}
`
);
}
$
(
"#modal .supplier_date_planned"
)
.
datepicker
({
defaultDate
:
"+1d"
,
minDate
:
new
Date
()
})
.
on
(
'change'
,
function
()
{
try
{
// When date input changes, try to read date
$
.
datepicker
.
parseDate
(
date_format
,
$
(
this
).
val
());
}
catch
{
alert
(
'Date invalide'
);
$
(
this
).
val
(
''
);
}
});
}
return
0
;
});
$
.
datepicker
.
regional
[
'fr'
]
=
{
monthNames
:
[
'Janvier'
,
'Fevrier'
,
'Mars'
,
'Avril'
,
'Mai'
,
'Juin'
,
'Juillet'
,
'Aout'
,
'Septembre'
,
'Octobre'
,
'Novembre'
,
'Decembre'
],
dayNamesMin
:
[
'Di'
,
'Lu'
,
'Ma'
,
'Me'
,
'Je'
,
'Ve'
,
'Sa'
],
dateFormat
:
date_format
};
$
.
datepicker
.
setDefaults
(
$
.
datepicker
.
regional
[
'fr'
]);
$
.
datepicker
.
regional
[
'fr'
]
=
{
monthNames
:
[
'Janvier'
,
'Fevrier'
,
'Mars'
,
'Avril'
,
'Mai'
,
'Juin'
,
'Juillet'
,
'Aout'
,
'Septembre'
,
'Octobre'
,
'Novembre'
,
'Decembre'
],
dayNamesMin
:
[
'Di'
,
'Lu'
,
'Ma'
,
'Me'
,
'Je'
,
'Ve'
,
'Sa'
],
dateFormat
:
date_format
};
$
.
datepicker
.
setDefaults
(
$
.
datepicker
.
regional
[
'fr'
]);
// Order selection screen
update_order_selection_screen
();
// Order selection screen
update_order_selection_screen
();
$
(
"#new_order_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
if
(
is_time_to
(
'submit_new_order_form'
,
1000
))
{
create_cdb_order
();
}
});
$
(
"#new_order_form"
).
on
(
"submit"
,
function
(
e
)
{
e
.
preventDefault
();
if
(
is_time_to
(
'submit_new_order_form'
,
1000
))
{
create_cdb_order
();
}
});
// Orders created screen
$
(
'#back_to_order_selection_from_orders_created'
).
on
(
'click'
,
function
()
{
if
(
is_time_to
(
'back_to_order_selection_from_orders_created'
,
1000
))
{
switch_screen
(
'order_selection'
,
'orders_created'
);
}
});
// Orders created screen
$
(
'#back_to_order_selection_from_orders_created'
).
on
(
'click'
,
function
()
{
if
(
is_time_to
(
'back_to_order_selection_from_orders_created'
,
1000
))
{
switch_screen
(
'order_selection'
,
'orders_created'
);
}
});
// Get suppliers
$
.
ajax
({
type
:
'GET'
,
url
:
"/orders/get_suppliers"
,
dataType
:
"json"
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
success
:
function
(
data
)
{
suppliers_list
=
data
.
res
;
// Get suppliers
$
.
ajax
({
type
:
'GET'
,
url
:
"/orders/get_suppliers"
,
dataType
:
"json"
,
traditional
:
true
,
contentType
:
"application/json; charset=utf-8"
,
success
:
function
(
data
)
{
suppliers_list
=
data
.
res
;
// Set up autocomplete on supplier input
$
(
"#supplier_input"
).
autocomplete
({
source
:
suppliers_list
.
map
(
a
=>
a
.
display_name
)
});
// Set up autocomplete on supplier input
$
(
"#supplier_input"
).
autocomplete
({
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'
};
if
(
typeof
data
.
responseJSON
!=
'undefined'
&&
typeof
data
.
responseJSON
.
error
!=
'undefined'
)
{
err
.
msg
+=
' : '
+
data
.
responseJSON
.
error
;
},
error
:
function
(
data
)
{
err
=
{
msg
:
"erreur serveur lors de la récupération des fournisseurs"
,
ctx
:
'get_suppliers'
};
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 fournisseurs, rechargez la page plus tard'
);
}
report_JS_error
(
err
,
'orders'
);
}
);
closeModal
();
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"
};
//Get products
var
accentMap
=
{
"á"
:
"a"
,
"à"
:
"a"
,
"â"
:
"a"
,
"é"
:
"e"
,
"è"
:
"e"
,
"ê"
:
"e"
,
"ë"
:
"e"
,
"ç"
:
"c"
,
"ù"
:
"u"
,
"ü"
:
"u"
,
"ö"
:
"o"
};
var
normalize
=
function
(
term
)
{
var
ret
=
""
;
var
normalize
=
function
(
term
)
{
var
ret
=
""
;
for
(
var
i
=
0
;
i
<
term
.
length
;
i
++
)
{
ret
+=
accentMap
[
term
.
charAt
(
i
)
]
||
term
.
charAt
(
i
);
}
for
(
var
i
=
0
;
i
<
term
.
length
;
i
++
)
{
ret
+=
accentMap
[
term
.
charAt
(
i
)
]
||
term
.
charAt
(
i
);
}
return
ret
;
};
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
;
$
.
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"
);
// 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
;
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"
}
});
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
();
},
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
;
closeModal
();
alert
(
'Erreur lors de la récupération des articles, rechargez la page plus tard'
);
}
report_JS_error
(
err
,
'orders'
);
closeModal
();
alert
(
'Erreur lors de la récupération des articles, rechargez la page plus tard'
);
}
});
});
}
else
{
$
(
'#not_connected_content'
).
show
();
}
});
products/models.py
View file @
191b57a5
...
...
@@ -148,7 +148,8 @@ class CagetteProduct(models.Model):
'product_purchase_ok'
:
product
[
"purchase_ok"
],
'price'
:
price
,
'base_price'
:
price
,
'package_qty'
:
package_qty
'package_qty'
:
package_qty
,
'sequence'
:
1000
# lowest priority for the new suppliers
}
res
=
api
.
create
(
'product.supplierinfo'
,
f
)
...
...
@@ -503,8 +504,8 @@ class CagetteProducts(models.Model):
sales_average_params
=
{
'ids'
:
ptids
,
#
'from': '2019-04-10',
#
'to': '2019-08-10',
'from'
:
'2019-04-10'
,
'to'
:
'2019-08-10'
,
}
sales
=
CagetteProducts
.
get_template_products_sales_average
(
sales_average_params
)
...
...
templates/orders/helper.html
View file @
191b57a5
...
...
@@ -16,14 +16,20 @@
{% block content %}
<div
class=
"page_body"
>
<div
id=
"select_order_content"
class=
"page_content txtcenter"
>
<div
class=
"login_area"
>
{% include "common/conn_admin.html" %}
</div>
<div
id=
"new_order_area"
>
<h2>
Créer une nouvelle commande
</h2>
<form
id=
"new_order_form"
>
<div
class=
"txtcenter"
id=
"not_connected_content"
style=
"display:none;"
>
<p>
Vous devez vous connecter avec un compte Odoo pour accéder au module d'aide à la commande.
</p>
</div>
<form
id=
"new_order_form"
style=
"display:none;"
>
<input
type=
"text"
id=
"new_order_name"
placeholder=
"Nom de la commande..."
>
<button
type=
"submit"
class=
"btn btn--primary"
>
Valider
</button>
<button
type=
"submit"
class=
"btn btn--primary"
>
C'est parti !
</button>
</form>
</div>
<div
id=
"existing_orders_area"
>
<div
id=
"existing_orders_area"
style=
"display:none;"
>
<h2>
Ou, continuer une commande en cours de création
</h2>
<div
id=
"existing_orders"
></div>
</div>
...
...
@@ -34,9 +40,11 @@
<button
type=
"button"
class=
"btn--danger"
id=
"back_to_order_selection_from_main"
>
<i
class=
"fas fa-arrow-left"
></i>
Retour
</button>
<button
type=
"button"
class=
'btn--primary'
id=
"do_inventory"
style=
"display:none;"
>
Faire un inventaire
</button>
<div
class=
"rights_buttons"
>
<button
type=
"button"
class=
'btn--primary'
id=
"do_inventory"
style=
"display:none;"
>
Faire un inventaire
</button>
</div>
</div>
<div
class=
"header txtcenter"
>
...
...
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