Commit c6b43c9e authored by Titouan Soulard's avatar Titouan Soulard

erp5_trade: properly support full inventories

parent 5d71f735
...@@ -29,7 +29,7 @@ inventory_calculation_dict = { ...@@ -29,7 +29,7 @@ inventory_calculation_dict = {
section_uid = context.getDestinationSectionUid() section_uid = context.getDestinationSectionUid()
node_uid = context.getDestinationUid() node_uid = context.getDestinationUid()
inventory_list = portal.portal_simulation.getCurrentInventoryList( inventory_list = portal.portal_simulation.getInventoryList(
section_uid=section_uid, section_uid=section_uid,
node_uid=node_uid, node_uid=node_uid,
at_date=context.getStartDate(), at_date=context.getStartDate(),
...@@ -39,7 +39,7 @@ inventory_list = portal.portal_simulation.getCurrentInventoryList( ...@@ -39,7 +39,7 @@ inventory_list = portal.portal_simulation.getCurrentInventoryList(
inventory_dict = {} inventory_dict = {}
for inventory in inventory_list: for inventory in inventory_list:
total_quantity = inventory.total_quantity total_quantity = inventory.quantity
total_price = inventory.total_price total_price = inventory.total_price
# Build a key, usually by going from most general (product) to most specific (sub-variation) # Build a key, usually by going from most general (product) to most specific (sub-variation)
...@@ -79,13 +79,25 @@ for movement_generator in movement_generator_list: ...@@ -79,13 +79,25 @@ for movement_generator in movement_generator_list:
report_element = reduce(lambda t, x: t.setdefault(x, {}), key, report_dict) report_element = reduce(lambda t, x: t.setdefault(x, {}), key, report_dict)
report_element["quantity"] = movement_generator.getInventory() report_element["quantity"] = movement_generator.getInventory()
# XXX: is that expected? We have two diverging dictionaries: one with total prices and the other with unit prices. # XXX-Titouan: is that expected? We have two diverging dictionaries: one with total prices and the other with unit prices.
report_element["price"] = movement_generator.getPrice() report_element["price"] = movement_generator.getPrice()
# Normal case: iterate over report dictionary and compare with inventory # When doing full inventory, add all elements in inventory dictionary to report dictionary with zero quantity
# When full inventory, take into account all objects in inventory and compare with report if context.isFullInventory():
base_dict = inventory_dict if context.isFullInventory() else report_dict for product_relative_url, product_content in inventory_dict.items():
compare_dict = report_dict if context.isFullInventory() else inventory_dict if product_relative_url not in report_dict:
report_dict[product_relative_url] = {}
# XXX-Titouan: seems suboptimal to check for price every time
if "price" in product_content:
report_dict[product_relative_url]["price"] = 0.0
report_dict[product_relative_url]["quantity"] = 0.0
else:
for variation_text in product_content.keys():
report_dict[product_relative_url][variation_text] = {
"price": 0.0,
"quantity": 0.0,
}
def compareDict(base, compare, path): def compareDict(base, compare, path):
# Traverse dictionary to return item or None # Traverse dictionary to return item or None
...@@ -93,7 +105,7 @@ def compareDict(base, compare, path): ...@@ -93,7 +105,7 @@ def compareDict(base, compare, path):
compare_element = reduce(lambda d, x: d[x] if d and x in d else None, path, compare) compare_element = reduce(lambda d, x: d[x] if d and x in d else None, path, compare)
if base_element is None: if base_element is None:
raise AssertionError("Since iterating on `base_dict` gives the key, element is expected to exist in `base_dict`") raise AssertionError("Since iterating on base dictionary gives the key, element is expected to exist in base dictionary")
if compare_element is None: if compare_element is None:
# Case (normal): object not in inventory API but in Inventory # Case (normal): object not in inventory API but in Inventory
return base_element["quantity"] return base_element["quantity"]
...@@ -101,14 +113,24 @@ def compareDict(base, compare, path): ...@@ -101,14 +113,24 @@ def compareDict(base, compare, path):
# Case (normal): object in inventory API and in Inventory # Case (normal): object in inventory API and in Inventory
return base_element["quantity"] - compare_element["quantity"] return base_element["quantity"] - compare_element["quantity"]
for product_relative_url, base_product_content in base_dict.items(): for product_relative_url, base_product_content in report_dict.items():
if not "price" in base_product_content: if "price" in base_product_content:
missing_quantity = compareDict(report_dict, inventory_dict, [product_relative_url])
if missing_quantity != 0.0:
context.newContent(
portal_type="Inventory Offset Line",
quantity=missing_quantity,
resource=product_relative_url,
price=base_product_content["price"],
)
else:
# Cannot create cells upfront because it is first needed to # Cannot create cells upfront because it is first needed to
# know the cell range. First iteration prepares all objects # know the cell range. First iteration prepares all objects
# which will be created after. # which will be created after.
cell_dict = {} cell_dict = {}
for variation_text, base_variation_content in base_product_content.items(): for variation_text, base_variation_content in base_product_content.items():
missing_quantity = compareDict(base_dict, compare_dict, [product_relative_url, variation_text]) missing_quantity = compareDict(report_dict, inventory_dict, [product_relative_url, variation_text])
if missing_quantity != 0.0: if missing_quantity != 0.0:
cell_dict[variation_text] = { cell_dict[variation_text] = {
...@@ -133,13 +155,3 @@ for product_relative_url, base_product_content in base_dict.items(): ...@@ -133,13 +155,3 @@ for product_relative_url, base_product_content in base_dict.items():
variation_text, variation_text,
**cell_kw **cell_kw
) )
else:
missing_quantity = compareDict(base_dict, compare_dict, [product_relative_url])
if missing_quantity != 0.0:
context.newContent(
portal_type="Inventory Offset Line",
quantity=missing_quantity,
resource=product_relative_url,
price=base_product_content["price"],
)
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