Thanks all for your suggestions, I’ve gone with @pokoli solution which seams to me the most easy and generic one.
I leave you here the modification, so you can review, I think it’s an optimization without too much complexity of the current generate_request
that can be contributed to core modules, but I’m sure it can be improved, so any comment is welcome.
@classmethod
def generate_requests(cls, clean=True, warehouses=None):
requests = super().generate_requests(clean=clean, warehouses=warehouses)
# Do not waste extra materials when productions have multiple outputs
# https://discuss.tryton.org/t/extra-productions-on-multiple-production-outputs/6675
requests_by_product = defaultdict(list)
for request in requests:
key = ','.join([str(o.product.id) for o in request.outputs])
requests_by_product[key].append(request)
max_requests = []
for products, requests in requests_by_product.items():
max_requests.append(max(requests, key= lambda r: r.quantity))
if len(max_requests) < len(requests):
cls.delete(list(set(requests) - set(max_requests)))
max_requests.extend(
super().generate_requests(clean=False, warehouses=warehouses))
return max_requests
When this is applied to my examples, if bom1 is the first on both products, the result is the following productions:
- bom1 production.quantity = 10, production.product = part A
- bom1 production.quantity = 1, production.product = part B
Which will only produce all the saled parts + 1unit of extra part A.