inventree / InvenTree

Open Source Inventory Management System
https://docs.inventree.org
MIT License
4.1k stars 731 forks source link

[FR] Make Price Range for Bill of Materials sum/multiply the Price range for components that are also assemblies and have components with part data #7955

Closed realstudent01 closed 2 days ago

realstudent01 commented 3 weeks ago

Please verify that this feature request has NOT been suggested before.

Problem statement

When building assemblies out of assemblies, the price data does not propagate up the levels.

Suggested solution

When an assembly is added as a component to another assembly, multiply the total price of the assembly's BOM by the quantity of that assembly being used in the higher assembly.

Describe alternatives you've considered

Another solution would be to not allow assemblies to be components of other assemblies, but that seems opposed to the purpose of inventree

Examples of other systems

No response

Do you want to develop this?

SchrodingersGat commented 3 weeks ago

@realstudent01 you will have to provide an example here, but I think that the code is doing what it should be doing...

https://github.com/inventree/InvenTree/blob/58f60d18b6944934ec5db09f6fe0f68280a96a07/src/backend/InvenTree/part/models.py#L2044

    def get_bom_price_range(self, quantity=1, internal=False, purchase=False):
        """Return the price range of the BOM for this part.

        Adds the minimum price for all components in the BOM.
        Note: If the BOM contains items without pricing information,
        these items cannot be included in the BOM!
        """
        min_price = None
        max_price = None

        for item in self.get_bom_items().select_related('sub_part'):
            if item.sub_part.pk == self.pk:
                logger.warning('WARNING: BomItem ID %s contains itself in BOM', item.pk)
                continue

            q = decimal.Decimal(quantity)
            i = decimal.Decimal(item.quantity)

            prices = item.sub_part.get_price_range(
                q * i, internal=internal, purchase=purchase
            )

            if prices is None:
                continue

            low, high = prices

            if min_price is None:
                min_price = 0

            if max_price is None:
                max_price = 0

            min_price += low
            max_price += high

        if min_price is None or max_price is None:
            return None

        min_price = normalize(min_price)
        max_price = normalize(max_price)

        return (min_price, max_price)

The BOM pricing uses the quantity of the BOM line item to determine pricing. Is this not what you are asking for?

realstudent01 commented 3 weeks ago

Say I have an assembly A made up of x, y, and z, where x, y, and z are each $5. So the BOM total of assembly A is $15.

Now if I make an assembly B that is made up of 2 of assembly A, the BOM total of assembly B should be $30... however currently the BOM total of B is showing as %0. I believe this is because A doesn't have a price specifically for it, but it is made up of things that do have prices.

realstudent01 commented 3 weeks ago

Sorry, it appears that the issue is that you have to go into each layer of the nested BOMs, go to pricing, and click "Refresh". Is there a similar function to "Refresh" in the API so this can be sped up?

SchrodingersGat commented 3 weeks ago

Updating the pricing for a part should automatically cause any assemblies that use that part to be updated too. Are you saying that this is not occuring?

realstudent01 commented 3 weeks ago

Sort of. In order for the prices to propagate up through the nested BOMs I have I am having to go to the lowest level BOM (leaf node), click "Refresh" in the pricing tab, then go to the next lowest level BOM and hit "Refresh" in the pricing tab to have the data fill in.

jesseyu1984918 commented 3 weeks ago

Updating the pricing for a part should automatically cause any assemblies that use that part to be updated too. Are you saying that this is not occuring?

It occurs to me that the BOM list price is updated, but the part's overall pricing doesn't get updated automatically and need to fresh to get updated and thus it kind of breaks the link if the part is used as the BOM of another part

realstudent01 commented 3 weeks ago

Yes, thank you @jesseyu1984918. Is there a way to force part overall price to update? Or make it so that overall pricing syncs with BOM list price (which would make sense that an assembly of x parts should be at least as expensive as those x parts by themselves).

SchrodingersGat commented 2 weeks ago

@realstudent01 that should be happening automatically - I will need to look into why the pricing data is not flowing upstream properly.

Any further details you can provide would be helpful here!

motusRP commented 1 week ago

Came here looking for this issue, it appears to be present in my Inventree install as well. We have put together a multiple-level BOM, where each level consists of parts and assemblies down about 5 or 6 levels. In order for the Pricing tab on the top-level part to show the correct price, we need to drill down to each sublevel and each subassembly and update it manually, they aren't rolling up automatically.

image

SchrodingersGat commented 5 days ago

@realstudent01 what version of InvenTree are you running?

SchrodingersGat commented 5 days ago

Ok, I think I have worked out what is going on - fix incoming in https://github.com/inventree/InvenTree/pull/8090

motusRP commented 4 days ago

Will that fix get rolled into the next 15.x release or will we need to upgrade to 16.x to see it?

matmair commented 4 days ago

fixes are only released for the current version so you will have to upgrade to 0.16.1

motusRP commented 4 days ago

Good to know, thanks. I'll watch for it to be implemented before we look into that.