Commit 8534ca7e authored by Titouan Soulard's avatar Titouan Soulard

erp5_trade: FIXUP script to compute offset

parent 6780bdf2
Pipeline #37921 running with stage
in 0 seconds
......@@ -4,29 +4,28 @@ inventory_calculation_dict = {
"inventory_kw": {
"group_by_resource": 1,
"group_by_variation": 1,
"group_by_sub_variation": 1,
#"group_by_sub_variation": 1,
"resourceType": portal.getPortalProductTypeList(),
},
"group_by": [
{
"getter": "getResource",
"key": "resource_relative_url",
"getter": "getResource",
"property": "resource",
"portal_type": "Inventory Offset Line"
},
{
"key": "variation_text",
"getter": "getVariationCategoryList",
# Without the lambda expression, one gets the following error:
# > You are not allowed to access 'join' in this context.
# pylint: disable=unnecessary-lambda
"post_getter": lambda variation_list: "\n".join(variation_list),
"key": "variation_text",
"property": "variation",
"portal_type": "Inventory Offset Cell"
}
]
}
# Create first dictionary of what is currently in the stock
section_uid = context.getDestinationSectionUid()
node_uid = context.getDestinationUid()
......@@ -38,7 +37,6 @@ inventory_list = portal.portal_simulation.getCurrentInventoryList(
)
inventory_dict = {}
browsed_keys = []
for inventory in inventory_list:
total_quantity = inventory.total_quantity
......@@ -53,18 +51,12 @@ for inventory in inventory_list:
if partial_key:
key.append(partial_key)
key = tuple(key)
if key in inventory_dict:
total_quantity += inventory_dict[key]["quantity"]
total_price += inventory_dict[key]["price"]
inventory_dict[key] = {
"quantity": total_quantity,
"price": total_price
}
# Xavier's magic method: traverse dictionnary and assign to last
inventory_element = reduce(lambda t, x: t.setdefault(x, {}), key, inventory_dict)
inventory_element["quantity"] = total_quantity
inventory_element["price"] = total_price
print(inventory_dict)
# Collect pseudo-movements (lines and cells that might create movements)
# Create second dictionary of what is reported on inventory
movement_generator_list = []
for inventory_line in context.objectValues(portal_type="Inventory Line"):
if inventory_line.hasCellContent():
......@@ -72,6 +64,7 @@ for inventory_line in context.objectValues(portal_type="Inventory Line"):
else:
movement_generator_list.append(inventory_line)
report_dict = {}
for movement_generator in movement_generator_list:
# Browse dictionnary by creating a key for each pseudo-movement
key = []
......@@ -84,39 +77,62 @@ for movement_generator in movement_generator_list:
partial_key = group_dict["post_getter"](partial_key)
key.append(partial_key)
key = tuple(key)
# Case 1 (below): object in inventory API and in Inventory
# Case 2 (XXX) : object in inventory API but not in Inventory -> only full
# Case 3 (XXX) : object not in inventory API but in Inventory -> else clause
if key in inventory_dict:
browsed_keys.append(key)
# If missing quantity is negative, then there is extra quantity
missing_quantity = movement_generator.getQuantity() - inventory_dict[key]["quantity"]
report_element = reduce(lambda t, x: t.setdefault(x, {}), key, report_dict)
report_element["quantity"] = movement_generator.getInventory()
report_element["price"] = movement_generator.getTotalPrice()
# Normal case: iterate over report dictionary and compare with inventory
# When full inventory, take into account all objects in inventory and compare with report
base_dict = inventory_dict if context.isFullInventory() else report_dict
compare_dict = report_dict if context.isFullInventory() else inventory_dict
def compareDict(base, compare, path):
# Traverse dictionary to return item or None
base_element = reduce(lambda d, x: d[x] if d and x in d else None, path, base)
compare_element = reduce(lambda d, x: d[x] if d and x in d else None, path, compare)
if base_element is None:
raise AssertionError("Since iterating on `base_dict` gives the key, element is expected to exist in `base_dict`")
if compare_element is None:
# Case (normal): object not in inventory API but in Inventory
return base_element["quantity"]
# Case (normal): object in inventory API and in Inventory
return base_element["quantity"] - compare_element["quantity"]
for product_relative_url, base_product_content in base_dict.items():
if not "price" in base_product_content:
offset_line = None
variation_list = []
for variation_partial_text, base_variation_content in base_product_content.items():
missing_quantity = compareDict(base_dict, compare_dict, [product_relative_url, variation_partial_text])
if missing_quantity != 0.0:
if offset_line is None:
offset_line = context.newContent(
portal_type="Inventory Offset Line",
resource=product_relative_url,
)
variation = variation_partial_text.split("/", 1)[1]
offset_line.newContent(
portal_type="Inventory Offset Cell",
quantity=missing_quantity,
variation=variation,
price=base_variation_content["price"],
)
variation_list.append(variation)
if offset_line is not None:
offset_line.setVariationList(variation_list)
else:
missing_quantity = compareDict(base_dict, compare_dict, [product_relative_url])
if missing_quantity != 0.0:
last_object = context
# Create lines and eventually cells depending on the key
for (key_index, group_dict) in enumerate(inventory_calculation_dict["group_by"]):
if key_index > len(key) - 1:
break
object_properties = {
"portal_type": group_dict["portal_type"],
}
object_properties[group_dict["property"]] = key[key_index]
last_object = last_object.newContent(**object_properties)
print(object_properties)
last_object.edit(
context.newContent(
portal_type="Inventory Offset Line",
quantity=missing_quantity,
quantity_unit=movement_generator.getQuantityUnit(),
# XXX-Titouan: is this correct? Maybe we should not have
# any price on lines overall.
price=movement_generator.getPrice()
resource=product_relative_url,
price=base_product_content["price"],
)
print((missing_quantity, movement_generator.getPrice()))
return printed
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