Не получается решить задачу на комбинаторику, не знаю даже как называется данная проблема, но наверняка есть готовые библиотеки/функции/скрипты по ее решению.
Есть товары и опции которые лежат на складах. Товар или опция может иметь фиксированное кол-во или быть бесконечной(вместо кол-ва указано None). При заказе можно скомбинировать один товар с несколькими опциями, соответственно нужно распределить заказанные товары с опциями по складам в заказы. Если товары в заказе можно отправить с нескольких складов, то нужно выбрать все их, если нельзя, то разбить на несколько заказов по складам. Есть ли у кого решение или хотя бы название данной проблемы?
Для наглядности(синтаксис Python'a). ID опций, товаров, складов взяты наобум, можно вставить свои.
Словарь со всеми имеющимися товарами, складами на которых он имеется и количеством(None - бесконечный) на этих складах {product_id: {warehouse_id: quantity}, ...}:
{1: {2: 7, 4: 3}, 13: {2: 7, 4: 3}, 21: {2: None, 4: None}}
Аналогично опции(None - бесконечная) {option_id: {warehouse_id: quantity}, ...}:
{3: {2: None, 4: None}, 10: {2: 10}, 9: {2: 10, 4: 10}, 8: {4: 2}}
Заказ, кол-во в данном случае определяет кол-во данного товара и кол-во каждой опции в данной комплектации, т.е. при количестве 2шт нужно взять 2шт товара и по 2шт каждой опции. Один и тот же товар с разными комбинациями опций рассматривается как отдельный:
[{'product_id': 1, 'quantity': 2, 'options': [3, 10, 9]}, {'product_id': 1, 'quantity': 1, 'options': [3, 9]}, {'product_id': 13, 'quantity': 5, 'options': [10, 9]}]
На выходе хотелось бы получить что-то такое. order_products - ключ из массива заказа.
При невозможности отправки с одного склада:
[{'warehouses': [4], order_products: [0, 1]}, {'warehouses': [2], order_products: [2, 3]}]
При возможности отправки с нескольких складов:
[{'warehouses': [2, 4], order_products: [0, 1, 2, 3]}]
При возможности отправки с нескольких складов и только с одного склада:
[{'warehouses': [2, 4], order_products: [0, 1]}, {'warehouses': [6], order_products: [3]}]
Товары в заказе(order_products) которых нет или не хватает на складе(учитывая опции) запихнуть в отдельный массив с максимальным кол-вом, например:
limit_exceeded = [{'order_product': 1, 'max_quantity': 2}, ...]