Commit 97eaabd2 by Damien Moulard

Merge branch 'aide_a_la_commande' into dev_cooperatic

parents f4fd7818 aa99f68f
...@@ -109,3 +109,6 @@ RECEPTION_PB = "Ici, vous pouvez signaler toute anomalie lors d'une réception, ...@@ -109,3 +109,6 @@ RECEPTION_PB = "Ici, vous pouvez signaler toute anomalie lors d'une réception,
# display or not column "Autres" in reception process # display or not column "Autres" in reception process
DISPLAY_COL_AUTRES = False DISPLAY_COL_AUTRES = False
# URL to the metabase dashboard for orders helper
ORDERS_HELPER_METABASE_URL = "https://metabase.lacagette-coop.fr/dashboard/16"
...@@ -258,6 +258,11 @@ class Order(models.Model): ...@@ -258,6 +258,11 @@ class Order(models.Model):
} }
for line in order_lines: for line in order_lines:
product_line_name = line["name"]
if "product_code" in line and line["product_code"] is not False:
product_code = str(line["product_code"])
product_line_name = "[" + product_code + "] " + product_line_name
order_data["order_line"].append( order_data["order_line"].append(
[ [
0, 0,
...@@ -267,7 +272,7 @@ class Order(models.Model): ...@@ -267,7 +272,7 @@ class Order(models.Model):
"price_policy": "uom", "price_policy": "uom",
"indicative_package": True, "indicative_package": True,
"product_id": line["product_variant_ids"][0], "product_id": line["product_variant_ids"][0],
"name": line["name"], "name": product_line_name,
"date_planned": date_planned, "date_planned": date_planned,
"account_analytic_id": False, "account_analytic_id": False,
"product_qty_package":line["product_qty_package"], "product_qty_package":line["product_qty_package"],
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 5px 30px 5px 30px; padding: 7px 30px 7px 30px;
margin: 0 10px 5px 10px; margin: 0 10px 5px 10px;
} }
...@@ -31,6 +31,26 @@ ...@@ -31,6 +31,26 @@
background-color: #a1a2a3; background-color: #a1a2a3;
} }
.link_as_button:hover {
text-decoration: none;
color: white;
}
.link_as_button:active {
text-decoration: none;
color: white;
}
.link_as_button:focus {
text-decoration: none;
color: white;
}
.remove_order_modal_text {
font-size: 2rem;
}
.remove_order_name {
font-weight: bold;
}
/* - Order selection screen */ /* - Order selection screen */
#new_order_area { #new_order_area {
margin-bottom: 40px; margin-bottom: 40px;
...@@ -50,6 +70,25 @@ ...@@ -50,6 +70,25 @@
padding-top: 15px; padding-top: 15px;
} }
.order_pill {
flex-direction: row;
}
.pill_order_name {
flex: 3 0 auto;
}
.remove_order_icon {
flex: 0 1 auto;
color: #912930;
margin-left: 5px;
cursor: pointer;
z-index: 2;
transform: scale(1.2);
}
.remove_order_icon:hover {
color: #e62720;
}
.order_last_update { .order_last_update {
font-weight: bold; font-weight: bold;
} }
...@@ -82,6 +121,40 @@ ...@@ -82,6 +121,40 @@
justify-content: flex-start; justify-content: flex-start;
} }
.right_action_buttons {
display: flex;
}
#actions_buttons_wrapper {
position: relative;
margin-right: 5px;
}
#toggle_action_buttons {
width: 250px;
position: relative;
}
.toggle_action_buttons_icon {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 15px;
}
#actions_buttons_container {
position: absolute;
display: flex;
flex-direction: column;
width: 250px;
display: none;
}
.action_button {
width: 100%;
min-height: 45px;
}
/* -- Order data */ /* -- Order data */
#order_data_container { #order_data_container {
font-size: 1.8rem; font-size: 1.8rem;
...@@ -92,17 +165,27 @@ ...@@ -92,17 +165,27 @@
} }
#order_forms_container { #order_forms_container {
margin-top: 30px; margin-top: 20px;
display: flex; display: flex;
flex-wrap: wrap;
justify-content: space-evenly; justify-content: space-evenly;
} }
.order_form_item {
margin-top: 10px;
}
#supplier_input { #supplier_input {
width: 350px; width: 350px;
border-radius: 3px; border-radius: 3px;
} }
#date_planned_input, #coverage_days_input { #stats_date_period_select {
margin-left: 5px;
min-width: 200px;
}
#date_planned_input, #coverage_days_input, #stats_date_period_select {
border-radius: 3px; border-radius: 3px;
} }
...@@ -144,18 +227,27 @@ ...@@ -144,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: #e7e9ed; background-color: #e8ebf0;
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 {
...@@ -166,6 +258,10 @@ ...@@ -166,6 +258,10 @@
cursor: pointer; cursor: pointer;
} }
.focused_line {
background-color: #76cf71 !important;
}
/* -- Footer */ /* -- Footer */
#main_content_footer { #main_content_footer {
...@@ -185,19 +281,24 @@ ...@@ -185,19 +281,24 @@
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
margin: 30px 0 20px 0; margin: 30px 0 20px 0;
position: -webkit-sticky;
position: sticky;
top: 20px;
z-index: 3;
} }
.supplier_pill { .supplier_pill {
background-color: #e7e9edc5; background-color: #a0daff;
border: 1px solid black; border: 1px solid #6ea8cc;
} }
.pill_supplier_name { .pill_supplier_name {
font-weight: bold; font-weight: bold;
} }
.supplier_total_value_container { .supplier_data {
font-size: 1.5rem; font-size: 1.5rem;
display: flex;
} }
.remove_supplier_icon { .remove_supplier_icon {
...@@ -253,19 +354,6 @@ ...@@ -253,19 +354,6 @@
margin-top: 10px; margin-top: 10px;
} }
.download_order_file_button:hover {
text-decoration: none;
color: white;
}
.download_order_file_button:active {
text-decoration: none;
color: white;
}
.download_order_file_button:focus {
text-decoration: none;
color: white;
}
#recap_delivery_date { #recap_delivery_date {
font-weight: bold; font-weight: bold;
} }
......
...@@ -13,6 +13,7 @@ urlpatterns = [ ...@@ -13,6 +13,7 @@ urlpatterns = [
url(r'^get_suppliers$', views.get_suppliers), url(r'^get_suppliers$', views.get_suppliers),
url(r'^get_supplier_products$', views.get_supplier_products), url(r'^get_supplier_products$', views.get_supplier_products),
url(r'^associate_supplier_to_product$', views.associate_supplier_to_product), url(r'^associate_supplier_to_product$', views.associate_supplier_to_product),
url(r'^end_supplier_product_association$', views.end_supplier_product_association),
url(r'^create_orders$', views.create_orders), url(r'^create_orders$', views.create_orders),
url(r'^get_orders_attachment$', views.get_orders_attachment), url(r'^get_orders_attachment$', views.get_orders_attachment),
] ]
...@@ -19,7 +19,8 @@ def helper(request): ...@@ -19,7 +19,8 @@ def helper(request):
'title': 'Aide à la commande', 'title': 'Aide à la commande',
'couchdb_server': settings.COUCHDB['url'], 'couchdb_server': settings.COUCHDB['url'],
'db': settings.COUCHDB['dbs']['orders'], 'db': settings.COUCHDB['dbs']['orders'],
'odoo_server': settings.ODOO['url'] 'odoo_server': settings.ODOO['url'],
'metabase_url': getattr(settings, 'ORDERS_HELPER_METABASE_URL', '')
} }
template = loader.get_template('orders/helper.html') template = loader.get_template('orders/helper.html')
...@@ -42,7 +43,8 @@ def get_supplier_products(request): ...@@ -42,7 +43,8 @@ def get_supplier_products(request):
""" Get supplier products """ """ Get supplier products """
suppliers_id = request.GET.getlist('sids', '') suppliers_id = request.GET.getlist('sids', '')
res = CagetteProducts.get_products_for_order_helper(suppliers_id) stats_from = request.GET.get('stats_from')
res = CagetteProducts.get_products_for_order_helper(suppliers_id, [], stats_from)
if 'error' in res: if 'error' in res:
return JsonResponse(res, status=500) return JsonResponse(res, status=500)
...@@ -52,15 +54,29 @@ def get_supplier_products(request): ...@@ -52,15 +54,29 @@ def get_supplier_products(request):
def associate_supplier_to_product(request): def associate_supplier_to_product(request):
""" This product is now supplied by this supplier """ """ This product is now supplied by this supplier """
res = {} res = {}
try:
data = json.loads(request.body.decode()) data = json.loads(request.body.decode())
res = CagetteProduct.associate_supplier_to_product(data) res = CagetteProduct.associate_supplier_to_product(data)
except Exception as e:
res["error"] = str(e) if 'error' in res:
return JsonResponse(res, status=500) return JsonResponse(res, status=500)
else:
return JsonResponse({'res': res})
return JsonResponse({'res': res}) return JsonResponse({'res': res})
def end_supplier_product_association(request):
""" This product is now unavailable from this supplier """
res = {}
data = json.loads(request.body.decode())
res = CagetteProduct.end_supplier_product_association(data)
if 'error' in res:
return JsonResponse(res, status=500)
else:
return JsonResponse({'res': res})
def create_orders(request): def create_orders(request):
""" Create products orders """ """ Create products orders """
res = { "created": [] } res = { "created": [] }
......
...@@ -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"]
...@@ -140,6 +141,8 @@ class CagetteProduct(models.Model): ...@@ -140,6 +141,8 @@ class CagetteProduct(models.Model):
c = [['product_tmpl_id', '=', product_tmpl_id]] c = [['product_tmpl_id', '=', product_tmpl_id]]
res_products = api.search_read('product.product', c, f) res_products = api.search_read('product.product', c, f)
product = res_products[0] product = res_products[0]
today = datetime.date.today().strftime("%Y-%m-%d")
f = { f = {
'product_tmpl_id' : product_tmpl_id, 'product_tmpl_id' : product_tmpl_id,
...@@ -149,9 +152,40 @@ class CagetteProduct(models.Model): ...@@ -149,9 +152,40 @@ class CagetteProduct(models.Model):
'price': price, 'price': price,
'base_price': price, 'base_price': price,
'package_qty': package_qty, 'package_qty': package_qty,
'date_start': today,
'sequence': 1000 # lowest priority for the new suppliers 'sequence': 1000 # lowest priority for the new suppliers
} }
res = api.create('product.supplierinfo', f)
try:
res['create'] = api.create('product.supplierinfo', f)
except Exception as e:
res['error'] = str(e)
return res
@staticmethod
def end_supplier_product_association(data):
api = OdooAPI()
res = {}
product_tmpl_id = data["product_tmpl_id"]
partner_id = data["supplier_id"]
f = ["id"]
c = [['product_tmpl_id', '=', product_tmpl_id], ['name', '=', partner_id], ['date_end', '=', False]]
res_supplierinfo = api.search_read('product.supplierinfo', c, f)
psi_id = res_supplierinfo[0]['id']
today = datetime.date.today().strftime("%Y-%m-%d")
f = {
'date_end': today
}
try:
res["update"] = api.update('product.supplierinfo', psi_id, f)
except Exception as e:
res['error'] = str(e)
return res return res
...@@ -172,6 +206,23 @@ class CagetteProduct(models.Model): ...@@ -172,6 +206,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."""
...@@ -456,31 +507,32 @@ class CagetteProducts(models.Model): ...@@ -456,31 +507,32 @@ class CagetteProducts(models.Model):
return res return res
@staticmethod @staticmethod
def get_products_for_order_helper(supplier_ids, pids = []): def get_products_for_order_helper(supplier_ids, pids = [], stats_from = None):
""" """
One of the two parameters must be not empty. supplier_ids: Get products by supplier if one or more supplier id is set. If set, pids is ignored.
Get products by supplier if one or more supplier_id is set. pids: If set & supplier_ids is None/empty, get products specified in pids. In this case, suppliers info won't be fetched.
If supplier_ids is empty, get products specified in pids. In this case, suppliers info won't be fetched. stats_from: date from which we should calculate sells stats.
""" """
api = OdooAPI() api = OdooAPI()
res = {} res = {}
# todo : try with no result
try: try:
today = datetime.date.today().strftime("%Y-%m-%d") today = datetime.date.today().strftime("%Y-%m-%d")
if supplier_ids is not None and len(supplier_ids) > 0: if supplier_ids is not None and len(supplier_ids) > 0:
# Get products/supplier relation # Get products/supplier relation
f = ["product_tmpl_id", 'date_start', 'date_end', 'package_qty', 'price', 'name'] f = ["product_tmpl_id", 'date_start', 'date_end', 'package_qty', 'price', 'name', 'product_code']
c = [['name', 'in', [ int(x) for x in supplier_ids]]] c = [['name', 'in', [ int(x) for x in supplier_ids]]]
psi = api.search_read('product.supplierinfo', c, f) psi = api.search_read('product.supplierinfo', c, f)
# Filter valid data # Filter valid data
ptids = [] ptids = []
valid_psi = []
for p in psi: for p in psi:
if (p["product_tmpl_id"] is not False 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_start"] is False or p["date_start"] 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)): and (p["date_end"] is False or p["date_end"] is not False and p["date_end"] > today)):
valid_psi.append(p)
ptids.append(p["product_tmpl_id"][0]) ptids.append(p["product_tmpl_id"][0])
else: else:
ptids = [ int(x) for x in pids ] ptids = [ int(x) for x in pids ]
...@@ -507,6 +559,10 @@ class CagetteProducts(models.Model): ...@@ -507,6 +559,10 @@ class CagetteProducts(models.Model):
# 'from': '2019-04-10', # 'from': '2019-04-10',
# 'to': '2019-08-10', # 'to': '2019-08-10',
} }
if stats_from is not None and stats_from != '':
sales_average_params['from'] = stats_from
sales = CagetteProducts.get_template_products_sales_average(sales_average_params) sales = CagetteProducts.get_template_products_sales_average(sales_average_params)
if 'list' in sales and len(sales['list']) > 0: if 'list' in sales and len(sales['list']) > 0:
...@@ -517,12 +573,16 @@ class CagetteProducts(models.Model): ...@@ -517,12 +573,16 @@ class CagetteProducts(models.Model):
# Add supplier data to product data # Add supplier data to product data
for i, fp in enumerate(filtered_products_t): for i, fp in enumerate(filtered_products_t):
if supplier_ids is not None and len(supplier_ids) > 0: if supplier_ids is not None and len(supplier_ids) > 0:
psi_item = next(item for item in psi if item["product_tmpl_id"] is not False and item["product_tmpl_id"][0] == fp["id"]) # Add all the product suppliersinfo (products from multiple suppliers into the suppliers list provided)
filtered_products_t[i]['suppliersinfo'] = [{ filtered_products_t[i]['suppliersinfo'] = []
'supplier_id': int(psi_item["name"][0]), for psi_item in valid_psi:
'package_qty': psi_item["package_qty"], if psi_item["product_tmpl_id"] is not False and psi_item ["product_tmpl_id"][0] == fp["id"]:
'price': psi_item["price"] filtered_products_t[i]['suppliersinfo'].append({
}] 'supplier_id': int(psi_item["name"][0]),
'package_qty': psi_item["package_qty"],
'price': psi_item["price"],
'product_code': psi_item["product_code"]
})
for s in sales: for s in sales:
if s["id"] == fp["id"]: if s["id"] == fp["id"]:
......
...@@ -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
......
...@@ -42,8 +42,10 @@ def get_simple_list(request): ...@@ -42,8 +42,10 @@ def get_simple_list(request):
def get_product_for_order_helper(request): def get_product_for_order_helper(request):
res = {} res = {}
try: try:
pids = json.loads(request.body.decode()) data = json.loads(request.body.decode())
res = CagetteProducts.get_products_for_order_helper(None, pids) pids = data['pids']
stats_from = data['stats_from']
res = CagetteProducts.get_products_for_order_helper(None, pids, stats_from)
except Exception as e: except Exception as e:
coop_logger.error("get_product_for_help_order_line : %s", str(e)) coop_logger.error("get_product_for_help_order_line : %s", str(e))
res['error'] = str(e) res['error'] = str(e)
...@@ -112,6 +114,17 @@ def update_product_purchase_ok(request): ...@@ -112,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
......
...@@ -366,7 +366,7 @@ function display_orders_table() { ...@@ -366,7 +366,7 @@ function display_orders_table() {
$('#orders').empty(); $('#orders').empty();
} }
for (let j in orders) { for (let j in orders) {
console.log(orders[j].id) console.log(orders[j].id);
} }
table_orders = $('#orders').DataTable({ table_orders = $('#orders').DataTable({
data: orders, data: orders,
......
...@@ -166,6 +166,7 @@ function init_datatable() { ...@@ -166,6 +166,7 @@ function init_datatable() {
let data = row.data(); let data = row.data();
let validated_data = qty_validation(qty, data.uom.id); let validated_data = qty_validation(qty, data.uom.id);
if (validated_data >= 0) { if (validated_data >= 0) {
data.qty = validated_data; data.qty = validated_data;
row.remove().draw(); row.remove().draw();
...@@ -423,28 +424,33 @@ var update_existing_product = function(product, added_qty, undo_option = false) ...@@ -423,28 +424,33 @@ var update_existing_product = function(product, added_qty, undo_option = false)
function qty_validation(qty, uom_id) { function qty_validation(qty, uom_id) {
if (qty == null || qty == '') { if (qty == null || qty == '') {
$.notify("Il n'y a pas de quantité indiquée, ou ce n'est pas un nombre", { $.notify("Il n'y a pas de quantité indiquée, ou ce n'est pas un nombre", {
globalPosition:"top right", globalPosition:"top right",
className: "error"}); className: "error"});
return -1; return -1;
} }
if (uom_id == 1) { if (uom_id == 1) {
if (qty/parseInt(qty) != 1 && qty != 0){ if (qty/parseInt(qty) != 1 && qty != 0) {
$.notify("Une quantité avec décimale est indiquée alors que c'est un article à l'unité", { $.notify("Une quantité avec décimale est indiquée alors que c'est un article à l'unité", {
globalPosition:"top right", globalPosition:"top right",
className: "error"}); className: "error"});
return -2;}
return -2;
}
qty = parseInt(qty); // product by unit qty = parseInt(qty); // product by unit
} else { } else {
qty = parseFloat(qty).toFixed(2); qty = parseFloat(qty).toFixed(2);
} }
if (isNaN(qty)){ if (isNaN(qty)) {
$.notify("Une quantité n'est pas un nombre", { $.notify("Une quantité n'est pas un nombre", {
globalPosition:"top right", globalPosition:"top right",
className: "error"}); className: "error"});
return -3;}
return -3;
}
return qty; return qty;
} }
......
...@@ -40,10 +40,29 @@ ...@@ -40,10 +40,29 @@
<button type="button" class="btn--danger" id="back_to_order_selection_from_main"> <button type="button" class="btn--danger" id="back_to_order_selection_from_main">
<i class="fas fa-arrow-left"></i>&nbsp; Retour <i class="fas fa-arrow-left"></i>&nbsp; Retour
</button> </button>
<div class="rights_buttons"> <div class="right_action_buttons">
<button type="button" class='btn--primary' id="do_inventory" style="display:none;">
Faire un inventaire <div id="actions_buttons_wrapper">
</button> <button type="button" class='btn--primary' id="toggle_action_buttons">
<span class="button_content">
Actions
</span>
<span class="toggle_action_buttons_icon">
<i class="fas fa-chevron-down"></i>
</span>
</button>
<div id="actions_buttons_container">
<button type="button" class='btn--primary action_button' id="do_inventory" style="display:none;">
Faire un inventaire
</button>
<button type="button" class='btn--danger action_button' id="delete_order_button">
Supprimer la commande
</button>
</div>
</div>
<a class='btn--warning link_as_button' id="access_metabase" style="display:none;" href="{{metabase_url}}" target="_blank">
Stats Métabase
</a>
</div> </div>
</div> </div>
...@@ -57,14 +76,23 @@ ...@@ -57,14 +76,23 @@
</div> </div>
<div class="txtcenter" id="order_forms_container"> <div class="txtcenter" id="order_forms_container">
<form action="javascript:;" id="coverage_form"> <form action="javascript:;" id="supplier_form" class="order_form_item">
<input type="number" name="coverage_days" id="coverage_days_input" placeholder="Nb jours de couverture" min="1">
<button type="submit" class='btn--primary'>Calculer les besoins</button>
</form>
<form action="javascript:;" id="supplier_form">
<input type="text" name="supplier" id="supplier_input" placeholder="Rechercher un fournisseur par son nom"> <input type="text" name="supplier" id="supplier_input" placeholder="Rechercher un fournisseur par son nom">
<button type="submit" class='btn--primary'>Ajouter le fournisseur</button> <button type="submit" class='btn--primary'>Ajouter le fournisseur</button>
</form> </form>
<form action="javascript:;" id="stats_date_from_form" class="order_form_item">
<label for="stats_date_period_select">Période de calcul de la conso moyenne </label>
<select name="stats_date_period_select" id="stats_date_period_select">
<option value="">Par défaut</option>
<option value="1week">1 semaine</option>
<option value="2weeks">2 semaines</option>
</select>
</form>
<form action="javascript:;" id="coverage_form" class="order_form_item">
<input type="number" name="coverage_days" id="coverage_days_input" placeholder="Nb jours de couverture" min="1">
<button type="submit" class='btn--primary'>Calculer les besoins</button>
</form>
</div> </div>
<div id="suppliers_container"></div> <div id="suppliers_container"></div>
...@@ -125,8 +153,14 @@ ...@@ -125,8 +153,14 @@
<span class="pill_supplier_name"></span> <span class="pill_supplier_name"></span>
<i class="fas fa-times remove_supplier_icon"></i> <i class="fas fa-times remove_supplier_icon"></i>
</div> </div>
<div class="supplier_total_value_container"> <div class="supplier_data">
Total: <span class="supplier_total_value">0</span> <div class="supplier_total_value_container">
Total : <span class="supplier_total_value">0</span>
</div>
&nbsp;&nbsp;|&nbsp;&nbsp;
<div class="supplier_total_packages_container">
Nb colis : <span class="supplier_total_packages">0</span>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -134,6 +168,7 @@ ...@@ -134,6 +168,7 @@
<div id="order_pill_template"> <div id="order_pill_template">
<div class="pill order_pill btn btn--primary"> <div class="pill order_pill btn btn--primary">
<span class="pill_order_name"></span> <span class="pill_order_name"></span>
<i class="fas fa-times remove_order_icon"></i>
</div> </div>
</div> </div>
...@@ -144,7 +179,7 @@ ...@@ -144,7 +179,7 @@
<h4 class="new_order_date_planned"></h4> <h4 class="new_order_date_planned"></h4>
<div class='download_order_file'> <div class='download_order_file'>
<i class="fas fa-spinner fa-spin download_order_file_loading"></i> <i class="fas fa-spinner fa-spin download_order_file_loading"></i>
<a class='btn--success download_order_file_button' style="display:none;" href="#"> <a class='btn--success download_order_file_button link_as_button' style="display:none;" href="#">
Télécharger le fichier de commande Télécharger le fichier de commande
</a> </a>
</div> </div>
...@@ -164,6 +199,15 @@ ...@@ -164,6 +199,15 @@
<p>Voulez-vous quand même y accéder ?</p> <p>Voulez-vous quand même y accéder ?</p>
<hr/> <hr/>
</div> </div>
<div id="modal_remove_order">
<h3>Attention !</h3>
<p class="remove_order_modal_text">
Vous vous apprêtez à <b style="color: #d9534f;">supprimer</b> cette commande en cours : <span class="remove_order_name"></span>.<br/>
</p>
<p>Êtez-vous sûr ?</p>
<hr/>
</div>
<div id="modal_remove_supplier"> <div id="modal_remove_supplier">
<h3>Attention !</h3> <h3>Attention !</h3>
...@@ -201,6 +245,19 @@ ...@@ -201,6 +245,19 @@
<p>Êtez-vous sûr ?</p> <p>Êtez-vous sûr ?</p>
<hr/> <hr/>
</div> </div>
<div id="modal_end_supplier_product_association">
<h3>Attention !</h3>
<p>
Vous vous apprêtez à rendre le produit <span class="product_name"></span>
indisponible chez le fournisseur <span class="supplier_name"></span>.
</p>
<p>
L'association sera supprimée dès que vous aurez cliqué sur "Valider".<br/>
</p>
<p>Êtez-vous sûr ?</p>
<hr/>
</div>
<div id="modal_create_inventory"> <div id="modal_create_inventory">
<p> <p>
...@@ -252,6 +309,7 @@ ...@@ -252,6 +309,7 @@
var couchdb_dbname = '{{db}}'; var couchdb_dbname = '{{db}}';
var couchdb_server = '{{couchdb_server}}' + couchdb_dbname; var couchdb_server = '{{couchdb_server}}' + couchdb_dbname;
var odoo_server = '{{odoo_server}}'; var odoo_server = '{{odoo_server}}';
var metabase_url = '{{metabase_url}}';
</script> </script>
<script src="{% static "js/all_common.js" %}?v="></script> <script src="{% static "js/all_common.js" %}?v="></script>
<script type="text/javascript" src="{% static 'js/orders_helper.js' %}?v="></script> <script type="text/javascript" src="{% static 'js/orders_helper.js' %}?v="></script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment