Commit 5a937781 by François C.

Merge branch '2470-alc-update-price-and-stock' into 'dev_cooperatic'

2470 alc update price and stock

See merge request !156
parents 1e561340 cb2d1c59
Pipeline #2119 passed with stage
in 1 minute 30 seconds
...@@ -368,10 +368,10 @@ class CagetteInventory(models.Model): ...@@ -368,10 +368,10 @@ class CagetteInventory(models.Model):
return {'missed': missed, 'unchanged': unchanged, 'done': done} return {'missed': missed, 'unchanged': unchanged, 'done': done}
@staticmethod @staticmethod
def update_products_stock(inventory_data): def update_products_stock(inventory_data, precision=2):
""" Updates Odoo stock after a shelf inventory or another action""" """ Updates Odoo stock after a shelf inventory or another action"""
TWOPLACES = Decimal(10) ** -2 TWOPLACES = Decimal(10) ** -precision
api = OdooAPI() api = OdooAPI()
missed = [] missed = []
unchanged = [] unchanged = []
......
...@@ -264,7 +264,8 @@ ...@@ -264,7 +264,8 @@
padding: .5rem .5rem; padding: .5rem .5rem;
} }
.supplier_package_qty { .supplier_package_qty,
.supplier_price {
font-style: italic; font-style: italic;
font-size: 1.3rem; font-size: 1.3rem;
} }
...@@ -381,14 +382,46 @@ ...@@ -381,14 +382,46 @@
display: block; display: block;
} }
.modal_product_actions_section { .product_actions_container {
display: flex;
flex-direction: column;
}
.product_actions_section {
width: 100%;
display: flex;
margin: 1em 0; margin: 1em 0;
} }
.modal_product_actions_section .tooltip { .product_actions_column {
width: 50%;
}
.product_actions_full_column {
width: 100%;
}
.product_actions_column .tooltip {
margin-left: 5px; margin-left: 5px;
} }
.product_prices_title {
margin-bottom: 0 !important;
}
.product_prices_area {
margin: 20px 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.product_price_action {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
.modal_product_actions_title { .modal_product_actions_title {
font-weight: bold; font-weight: bold;
font-size: 2.2rem; font-size: 2.2rem;
......
...@@ -160,6 +160,7 @@ class CagetteProduct(models.Model): ...@@ -160,6 +160,7 @@ class CagetteProduct(models.Model):
try: try:
res["update"] = api.update('product.supplierinfo', psi_id, f) res["update"] = api.update('product.supplierinfo', psi_id, f)
res["psi_id"] = psi_id
except Exception as e: except Exception as e:
res['error'] = str(e) res['error'] = str(e)
else: else:
...@@ -185,6 +186,7 @@ class CagetteProduct(models.Model): ...@@ -185,6 +186,7 @@ class CagetteProduct(models.Model):
try: try:
res['create'] = api.create('product.supplierinfo', f) res['create'] = api.create('product.supplierinfo', f)
res['psi_id'] = res['create'] # consistency between update & create res
except Exception as e: except Exception as e:
res['error'] = str(e) res['error'] = str(e)
...@@ -259,13 +261,17 @@ class CagetteProduct(models.Model): ...@@ -259,13 +261,17 @@ class CagetteProduct(models.Model):
- NPA (ne pas acheter) - NPA (ne pas acheter)
- Product is active - Product is active
- Minimal stock - Minimal stock
- price /supplier
""" """
res = {} res = {}
try: try:
api = OdooAPI() api = OdooAPI()
# Minimal stock # Minimal & Actual stock, Active
f = {'minimal_stock': data['minimal_stock']} f = {
'minimal_stock': float(data['minimal_stock']),
'active': not data['to_archive']
}
# NPA # NPA
if 'simple-npa' in data['npa']: if 'simple-npa' in data['npa']:
...@@ -287,13 +293,19 @@ class CagetteProduct(models.Model): ...@@ -287,13 +293,19 @@ class CagetteProduct(models.Model):
if len(data['npa']) == 0: if len(data['npa']) == 0:
f['purchase_ok'] = 1 f['purchase_ok'] = 1
# Active res["update"] = api.update('product.template', int(data['id']), f)
f["active"] = not data['to_archive']
# Update suppliers info
res["update_supplierinfo"] = []
for supplierinfo in data["suppliersinfo"]:
f= {'price': supplierinfo["price"]}
res_update_si = api.update('product.supplierinfo', int(supplierinfo['supplierinfo_id']), f)
res["update_supplierinfo"].append(res_update_si)
res["update"] = api.update('product.template', data['id'], f)
except Exception as e: except Exception as e:
res["error"] = str(e) res["error"] = str(e)
coop_logger.error("update_npa_and_minimal_stock : %s %s", str(e), str(data)) coop_logger.error("commit_actions_on_product : %s %s", str(e), str(data))
return res return res
class CagetteProducts(models.Model): class CagetteProducts(models.Model):
"""Initially used to make massive barcode update.""" """Initially used to make massive barcode update."""
...@@ -593,7 +605,7 @@ class CagetteProducts(models.Model): ...@@ -593,7 +605,7 @@ class CagetteProducts(models.Model):
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', 'product_code'] f = ["id", "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)
...@@ -651,6 +663,7 @@ class CagetteProducts(models.Model): ...@@ -651,6 +663,7 @@ class CagetteProducts(models.Model):
for psi_item in valid_psi: for psi_item in valid_psi:
if psi_item["product_tmpl_id"] is not False and psi_item ["product_tmpl_id"][0] == fp["id"]: if psi_item["product_tmpl_id"] is not False and psi_item ["product_tmpl_id"][0] == fp["id"]:
filtered_products_t[i]['suppliersinfo'].append({ filtered_products_t[i]['suppliersinfo'].append({
'id': int(psi_item["id"]),
'supplier_id': int(psi_item["name"][0]), 'supplier_id': int(psi_item["name"][0]),
'package_qty': psi_item["package_qty"], 'package_qty': psi_item["package_qty"],
'price': psi_item["price"], 'price': psi_item["price"],
......
...@@ -149,13 +149,13 @@ def commit_actions_on_product(request): ...@@ -149,13 +149,13 @@ def commit_actions_on_product(request):
res = CagetteProduct.commit_actions_on_product(data) res = CagetteProduct.commit_actions_on_product(data)
# If stock > 0: do inventory to set stock to 0 do_stock_update = False
# If product to archive and stock > 0: do inventory to set stock to 0
if data["to_archive"] is True and product_data["qty_available"] != 0: if data["to_archive"] is True and product_data["qty_available"] != 0:
try:
p = { p = {
'id': product_data['product_variant_ids'][0], # Need product id 'id': product_data['product_variant_ids'][0], # Need product id
'uom_id': product_data['uom_id'], 'uom_id': product_data['uom_id'],
'qty': -product_data["qty_available"] 'qty': 0
} }
inventory_data = { inventory_data = {
...@@ -163,15 +163,34 @@ def commit_actions_on_product(request): ...@@ -163,15 +163,34 @@ def commit_actions_on_product(request):
'products': [p] 'products': [p]
} }
res_inventory = CagetteInventory.update_products_stock(inventory_data) do_stock_update = True
# Else update actual stock if changed
elif data["qty_available"] != product_data["qty_available"]:
p = {
'id': product_data['product_variant_ids'][0], # Need product id
'uom_id': product_data['uom_id'],
'qty': data["qty_available"]
}
inventory_data = {
'name': 'MAJ stock depuis Aide à la Commande - ' + product_data['name'],
'products': [p]
}
do_stock_update = True
if do_stock_update is True:
try:
res_inventory = CagetteInventory.update_products_stock(inventory_data, 3)
if res_inventory['errors'] or res_inventory['missed']: if res_inventory['errors'] or res_inventory['missed']:
res["code"] = "error_stock_update" res["code"] = "error_stock_update"
res["error"] = res_inventory['errors'] res["error"] = res_inventory['errors']
return JsonResponse(res, status=500) return JsonResponse(res, status=500)
except Exception as e: except Exception as e:
res["code"] = "error_stock_update" res["code"] = "error_stock_update"
return JsonResponse(res, status=500) return JsonResponse(res, status=500)
except Exception as e: except Exception as e:
res['error'] = str(e) res['error'] = str(e)
coop_logger.error("Update npa and minimal stock : %s", res['error']) coop_logger.error("Update npa and minimal stock : %s", res['error'])
......
...@@ -276,9 +276,18 @@ ...@@ -276,9 +276,18 @@
<hr/> <hr/>
</div> </div>
<div id="product_price_action_template">
<div class="product_price_action">
<span class="supplier_name"></span>
<input type="number" class="product_supplier_price" name="" value="" />
</div>
</div>
<div id="modal_product_actions"> <div id="modal_product_actions">
Actions sur <h3><span class="product_name"></span></h3> Actions sur <h3><span class="product_name"></span></h3>
<div class="modal_product_actions_section"> <div class="product_actions_container">
<div class="product_actions_section">
<div class="product_actions_column">
<h4 class="modal_product_actions_title">NPA</h4> <h4 class="modal_product_actions_title">NPA</h4>
<div class="npa-options"> <div class="npa-options">
<label><input type="checkbox" name="npa-actions" value="simple-npa" /> Mettre le produit en NPA </label> <label><input type="checkbox" name="npa-actions" value="simple-npa" /> Mettre le produit en NPA </label>
...@@ -286,7 +295,7 @@ ...@@ -286,7 +295,7 @@
<label><input type="checkbox" name="npa-actions" value="fds-in-name" /> Mettre le produit en NPA et afficher FDS</label> <label><input type="checkbox" name="npa-actions" value="fds-in-name" /> Mettre le produit en NPA et afficher FDS</label>
</div> </div>
</div> </div>
<div class="modal_product_actions_section"> <div class="product_actions_column">
<h4 class="modal_product_actions_title">Archiver le produit</h4> <h4 class="modal_product_actions_title">Archiver le produit</h4>
<label class="checkbox_action_disabled"><input type="checkbox" name="archive-action" value="archive" disabled /> Archiver </label> <label class="checkbox_action_disabled"><input type="checkbox" name="archive-action" value="archive" disabled /> Archiver </label>
<div class="tooltip"> <div class="tooltip">
...@@ -296,10 +305,25 @@ ...@@ -296,10 +305,25 @@
</span> </span>
</div> </div>
</div> </div>
<div class="modal_product_actions_section"> </div>
<div class="product_actions_section">
<div class="product_actions_column">
<h4 class="modal_product_actions_title">Stock minimum</h4> <h4 class="modal_product_actions_title">Stock minimum</h4>
<input type="number" name="minimal_stock" value="" /> <input type="number" name="minimal_stock" value="" />
</div> </div>
<div class="product_actions_column">
<h4 class="modal_product_actions_title">Stock réel</h4>
<input type="number" name="actual_stock" value="" />
</div>
</div>
<div class="product_actions_section">
<div class="product_actions_full_column">
<h4 class="modal_product_actions_title product_prices_title">Prix</h4>
<i class="product_prices_title_label">(par fournisseur dans cette commande)</i>
<div class="product_prices_area"></div>
</div>
</div>
</div>
</div> </div>
<div id="modal_create_order"> <div id="modal_create_order">
......
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