Changing UoM on products should be forbidden

Bug #707287 reported by Kyle Waid
42
This bug affects 8 people
Affects Status Importance Assigned to Milestone
Odoo Addons (MOVED TO GITHUB)
Fix Released
Medium
OpenERP R&D Addons Team 2

Bug Description

Note:
  it should be impossible to have several stock moves with the same product but with incompatible unit of measures (=UoM from different
   categories). See comment 25 for the fix to do: https://bugs.launchpad.net/openobject-addons/+bug/707287/comments/25

We have around 5,000 products. We have custom UOM like ft, OZ and Pound. On certain products we cannot make manufacturing orders with this error

Conversion from Product UoM m to Default UoM PCE is not possible as they both belong to different Category!.

It is extremely frustrating because it doesnt make sense. We do not have a single product with UoM 'm'. The error only happens with certain products, not in any specific instance except that mabe the category UoM but not every item in that category. If we created new products then we dont have the issue.

I discovered many of the products were having problems base on an inventory we did with the stock_move table. Deleting entries fixed many of the issues but we still have this problem and it makes no sense to us.

https://bugs.launchpad.net/openobject-addons/+bug/707287/comments/25

Related branches

Revision history for this message
Amit Parik (amit-parik) wrote :

Hello Kyle,

Have you faced the problem in stale 6.0 or later version ?
Would you please attached the screen-shot of product form view in which you have faced the problem.

Thanks

Changed in openobject-addons:
status: New → Incomplete
Revision history for this message
Kyle Waid (midwest) wrote :

Hi, This problem is with the current trunk. I can explain in more detail. Say I have a few products. Natively, the UOM is PCE. So say I add 500 quantity for each of these products. But later I change the UOM to FT. When I try to do a manufacturing order later it cant because there is a past stock move for the product in PCE even though the current value of the product is in FT. I believe what happens is before the scheduler creates the manufacturing order it scans the stock_move table and if it finds non-matching entries it will return the error. The program should read only the current unit of measure not what is in past stock moves as it is not possible to change or remove a stock move.

I noticed that the error is triggered especially when using the magento connector.

There is also another piece to this. Say again I have a few products that are all in FT. I can create a BOM for each component in PCE. I can successfully produce a manufacturing order this way even though the components are not configured correctly. I believe all of these things combined adds corruption to the database.

So in the future even if the product is configured correctly, with the correct uom, it cant create a manufacturing order because there is a past stock move with an incompatible UOM. It took me many hours to diagnose the problem, and if you can reproduce it, I would say it is a critical bug because its like a plague,

you cant process the schuduler it will stop and not bypass it, halting the entire procurement and manufacturing process. The only solution is to put the product as consumable which is no solution at all.

Revision history for this message
Amit Parik (amit-parik) wrote :

Hello Kyle,

Thanks for the reply.

Have you change the "BOM" 's UOM to related product?
If you change the product 's UOM then you must change the BOM's UOM to realted product, then you can easily make the MO for this product.

Thanks

Revision history for this message
Kyle Waid (midwest) wrote :

Yes of course you are right. At first you can actually produce manufacturing orders even if the UOM in the BOM do not match. Try this on a clean database. This is not a noob bug report. At first this bug does not show itself, I am trying to figure out the exact trigger. As I said before I believe the magento connector exploits the bug, but I am not sure yet exactly when it starts. This is a bug, I will do more testing and show proof eventually.

In my case, even if the BOM is configured perfectly, and the UOM matches, it will still return the error because there is a past stock move for that product in a different UOM that is not compatible. I stated this clearly above.

Revision history for this message
Amit Parik (amit-parik) wrote :

Hello Kyle,

Form your scenario it is working as expected in trunk 6.0.

Follow this steps.

1) create a three different product A,B,C Set UOM as a PCE and create a minimum stock rule then create a BOM like
    A (UOM-PCE)
        ->B (UOM-PCE)
        ->C (UOM-PCE)
2) Create a sale order of A.
3) Run the scheduler. Now you have a real stock available of product A and stock moves also.
4) Go to product view and change the UOM (FT).
5) Create a MO and you Got this Error:
         "Conversion from Product UoM m to Default UoM PCE is not possible as they both belong to different Category!."
      which is proper because you can not create a MO if BOM and product's UOM is not same.
6) Now go to product A 's BOM and change the UOM (Same as product's UOM)
   Now BOM like
       A (UOM-FT)
        ->B (UOM-PCE)
        ->C (UOM-PCE)
7) Create MO , it will successfully created. So Stock moves are not affect it.

Now the all are working as expected. So, would you check it again and tell me where you face the problem.

Thanks

Revision history for this message
Amit Parik (amit-parik) wrote :

Hello Kyle,

Would you please give me the information from your side in the context
of this bug. So we can proceed further for qualification of this bug.

Waiting for your reply.

Thanks.

Revision history for this message
Amit Parik (amit-parik) wrote :

Hello Kyle,

Regarding the comment#5's scenario all are working as expected.
So there is not a bug and I am closing this issue if you still faced the problem then you can reopen this.

Thanks.

Changed in openobject-addons:
status: Incomplete → Invalid
Revision history for this message
Kyle Waid (midwest) wrote :

I have photographic proof and stack trace.

Changed in openobject-addons:
status: Invalid → New
Revision history for this message
Kyle Waid (midwest) wrote :
Revision history for this message
Kyle Waid (midwest) wrote :

As you can see in the product page the products UoM is clearly defined as LB. We generate manufacturing orders from LB. So everything is perfectly configured in our BOM. Now if you look at the second image it shows all of the stock moves for this particular product. Everything looks the same except the last line which is a much older stock move. It is registered as a purchase order in PCE. So a long time ago someone made a mistake, either the product really had the UoM as PCE or they made a mistake during the order process.

SO, Now even if the product is perfectly properly configured, when the scheduler runs and it comes to this product in the stock_move table for future moves it will halt the entire scheduling process and return the stack trace below. The only way that I can ever run the scheduler again is if I manually go to my database and make all entries of a compatible conversion type. This would indicate that we could NEVER change the UoM because we could have mass errors.

This doesnt just happen out of the box, something triggers it, but I assure you this is a bug, a serious bug. Besides the scheduler, in this scenario I could go to manufacturing and try to make a manufacturing order where a BOM had this product in it, and it would return the same error, making it impossible to use the product unless it was set to consumable or we did the database mod.

I even modified with help, my stock.py code so I could see the stock moves happening while the scheduler was running, so when it gets to this type scenario I can go to the stock_move for the product in question and this result is accurate 100% of the time. Extremely frustrating.

Revision history for this message
Kyle Waid (midwest) wrote :
Download full text (10.6 KiB)

   Move:264984, Prod:Glacier Pellet Hops -Per LB(5168)
Exception in thread Thread-27:
Traceback (most recent call last):
  File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.6/threading.py", line 484, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/opt/openerp/addons/procurement/wizard/schedulers_all.py", line 49, in _procure_calculation_all
    context=context)
  File "/opt/openerp/addons/procurement/procurement.py", line 469, in run_scheduler
    use_new_cursor=use_new_cursor, context=context)
  File "/opt/openerp/addons/procurement/schedulers.py", line 218, in _procure_orderpoint_confirm
    self.create_automatic_op(cr, uid, context=context)
  File "/opt/openerp/addons/procurement/schedulers.py", line 188, in create_automatic_op
    wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
  File "/opt/openerp/server/bin/workflow/wkf_service.py", line 80, in trg_validate
    res2 = instance.validate(cr, id, ident, signal)
  File "/opt/openerp/server/bin/workflow/instance.py", line 48, in validate
    workitem.process(cr, witem, ident, signal, force_running, stack=stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 61, in process
    ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 174, in _split_test
    _join_test(cr, t[0], t[1], ident, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 182, in _join_test
    create(cr,[activity], inst_id, ident, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 41, in create
    process(cr, res, ident, stack=stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 61, in process
    ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 174, in _split_test
    _join_test(cr, t[0], t[1], ident, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 182, in _join_test
    create(cr,[activity], inst_id, ident, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 41, in create
    process(cr, res, ident, stack=stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 61, in process
    ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 174, in _split_test
    _join_test(cr, t[0], t[1], ident, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 182, in _join_test
    create(cr,[activity], inst_id, ident, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 41, in create
    process(cr, res, ident, stack=stack) File "/opt/openerp/server/bin/workflow/workitem.py", line 61, in process
    ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 174, in _split_test
    _join_test(cr, t[0], t[1], ident, stack)
  File "/opt/openerp/server/bin/workflow/workitem.py", line 182, in _join_test
    create(cr,[activity], inst_id, ident, stack)
  File "/opt/openerp/server/bi...

Revision history for this message
Kyle Waid (midwest) wrote :

When you run the scheduler to see the output I did this

print "Move ID:%s, Product ID:%s(%s)" % (move.id, move.product_id.name, move.product_id.id) in stock.py in the check_assign method

Revision history for this message
Kyle Waid (midwest) wrote :

I think the issue is that when a manufacturing order with said product comes up, it reads all of the past entries in the stock_move table for that product and that is when it comes across this problem. An obvious fix would be to instead tell the program to read only the current value of the UoM because it is not doing this now.

Revision history for this message
Amit Parik (amit-parik) wrote :

Hello Kyle,

Would you please provide me your dump database because this type of traceback did not produce at my end.
So we need to check your configuration.

Thanks.

Changed in openobject-addons:
status: New → Incomplete
Revision history for this message
Kyle Waid (midwest) wrote :

I noticed it happen while using magentoerpconnect. Setup a fresh database with current sources, setup a magento site with demo data. Create an order in magento and download it. Change the UoM and then do a Manufaturing order with a bom after you changed the products default uom to an incompatible conversion. It will then return the error.

Amit Parik (amit-parik)
Changed in openobject-addons:
status: Incomplete → Triaged
Revision history for this message
jobiols (jorge-obiols) wrote :

hi all
I have the same problem that Kyle,

1. a product had a bad UOM
2. an inventory adjustment
3. mrp run into exception "UoM Conversion Product from m to Default UoM PCE is Not possible As They Both Belong to Different Category!."

Then our first problem was to figure out what was the product that raises this exception. because m and PCE are harcoded in the string. I added the following code on product.py line 144 before the raise statement, to get more information:

sys.stderr.write('conversion desde %s hasta %s no es posible cantidad %s' % (from_unit.name, to_unit.name, qty))
sys.stderr.flush()

After much research we discovered the product that generated the problem and correct the UOM on the product but the exception did not disappear.

when I read your comments I discover that the inventory adjustment was the blame, then I removed the product from BOM recreate it with the correct UOM and after that adjust the inventory, then put the corrected product in the BOM. This NOT solved the problem. Just moved the error to the next product.
The only difference with Kyle's scenario is that I've never had installed magento

I am in full agreement with what was said by Kile, the bug is very serious.
please see also Bug #716705 Product UoM conversion error needs definition

I hope this helps

Revision history for this message
Hans Decker (decker84) wrote :

hello,

I too have the same problem like jobiols.
Figured out the product with the wrong UoM, deleted and recreated it, but this bug still appears.
And I too don't have magento installed.

Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote :

Hello guys,

the good news is I HAVE A PATCH FOR THIS!

So: that bug occurs when you enter bad data in OpenERP: when the default purchase UOM, at the bottom of the product form doesn't belongs to a different UOM category than the procurement UOM (probably because you sold in a bad unit).

You can detect all the procurements that have such an issue with the following SQL query:

select procurement_order.id, procurement_order.state, product_uom, product_uom.category_id as product_uom_categ_id, product_template.uom_po_id, t.category_id as proc_uom_categ_id
from procurement_order
join product_template on product_id=product_template.id
join product_uom on product_template.uom_po_id=product_uom.id
join product_uom as t on procurement_order.product_uom=t.id
where t.category_id != product_uom.category_id;

That might help you to spot the problem and fix your data.

Now, I think OpenERP should apply my attached patch: it will test the UOM category right at the before trying to run the procurement and if there is some UOM miss match, then it will let the procurement in an "exception" state with a specific message: "Procurement UOM and product purchase UOM categories mismatch!"
so you can find those errors and fix them. It's exactly the same error management as when the product has no supplier for instance so I believe this is correct.

We have been working for Kyle (bug reporter) lately and I can assure this patch fixes the bug at their installation.

Changed in openobject-addons:
status: Triaged → Confirmed
Revision history for this message
Kyle Waid (midwest) wrote :

Thank you for the patch. However while your statement is true, it is proven that this happens even if the product is configured correctly. You can see proof in my screen shots and by reviewing the data I have provided above.

Revision history for this message
Amit Parik (amit-parik) wrote :
Download full text (5.6 KiB)

Hello Kyle,

I have have the same traceback at my end without magento connect with latest trunk So I am confirming this issue.

Traceback (most recent call last):
  File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.6/threading.py", line 484, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/home/tiny/workspace/openobject-addons/procurement/wizard/schedulers_all.py", line 49, in _procure_calculation_all
    context=context)
  File "/home/tiny/workspace/openobject-addons/procurement/procurement.py", line 473, in run_scheduler
    self._procure_confirm(cr, uid, use_new_cursor=use_new_cursor, context=context)
  File "/home/tiny/workspace/openobject-addons/procurement/schedulers.py", line 74, in _procure_confirm
    wf_service.trg_validate(uid, 'procurement.order', proc.id, 'button_check', cr)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/wkf_service.py", line 80, in trg_validate
    res2 = instance.validate(cr, id, ident, signal)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/instance.py", line 48, in validate
    workitem.process(cr, witem, ident, signal, force_running, stack=stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 61, in process
    ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 174, in _split_test
    _join_test(cr, t[0], t[1], ident, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 182, in _join_test
    create(cr,[activity], inst_id, ident, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 41, in create
    process(cr, res, ident, stack=stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 61, in process
    ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 174, in _split_test
    _join_test(cr, t[0], t[1], ident, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 182, in _join_test
    create(cr,[activity], inst_id, ident, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 41, in create
    process(cr, res, ident, stack=stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 61, in process
    ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 174, in _split_test
    _join_test(cr, t[0], t[1], ident, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 182, in _join_test
    create(cr,[activity], inst_id, ident, stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 41, in create
    process(cr, res, ident, stack=stack)
  File "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line 61, in process
    ok = _split_test(cr, workitem, activity['s...

Read more...

Changed in openobject-addons:
assignee: nobody → OpenERP R&D Addons Team 2 (openerp-dev-addons2)
importance: Undecided → Medium
Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote : Re: [Bug 707287] Re: Manufacturing orders broken UOM
Download full text (8.0 KiB)

Hello Amit and all, so how does it behave if you apply my patch and restart
the scheduler? I could reproduce the bug without magentoerpconnect and my
patch fixed it (well it detected the offending procurements and put them in
error so you can fix them).

If I understand right Kyle right, he said that if you change a product
purchase UOM after some usage, then even if you sale in MTO with the same
unit, you can have such an MRP UOM bug. In that case that would be worth a
check: does he UOM exception shows up only if you have open procurements in
both units? Then does my patch catch he offending procurement properly (I
expect so). If yes, that would be just about updating the unit of the
offending open procurement again (the old ones then). What do you think
Kyle? Any better suggestion?

On Wed, Jun 1, 2011 at 2:35 AM, Amit Parik (OpenERP) <email address hidden>wrote:

> Hello Kyle,
>
> I have have the same traceback at my end without magento connect with
> latest trunk So I am confirming this issue.
>
> Traceback (most recent call last):
> File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
> self.run()
> File "/usr/lib/python2.6/threading.py", line 484, in run
> self.__target(*self.__args, **self.__kwargs)
> File
> "/home/tiny/workspace/openobject-addons/procurement/wizard/schedulers_all.py",
> line 49, in _procure_calculation_all
> context=context)
> File "/home/tiny/workspace/openobject-addons/procurement/procurement.py",
> line 473, in run_scheduler
> self._procure_confirm(cr, uid, use_new_cursor=use_new_cursor,
> context=context)
> File "/home/tiny/workspace/openobject-addons/procurement/schedulers.py",
> line 74, in _procure_confirm
> wf_service.trg_validate(uid, 'procurement.order', proc.id,
> 'button_check', cr)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/wkf_service.py",
> line 80, in trg_validate
> res2 = instance.validate(cr, id, ident, signal)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/instance.py", line
> 48, in validate
> workitem.process(cr, witem, ident, signal, force_running, stack=stack)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line
> 61, in process
> ok = _split_test(cr, workitem, activity['split_mode'], ident, signal,
> stack)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line
> 174, in _split_test
> _join_test(cr, t[0], t[1], ident, stack)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line
> 182, in _join_test
> create(cr,[activity], inst_id, ident, stack)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line
> 41, in create
> process(cr, res, ident, stack=stack)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line
> 61, in process
> ok = _split_test(cr, workitem, activity['split_mode'], ident, signal,
> stack)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/workitem.py", line
> 174, in _split_test
> _join_test(cr, t[0], t[1], ident, stack)
> File
> "/home/tiny/workspace/openobject-server/openerp/workflow/work...

Read more...

Revision history for this message
Kyle Waid (midwest) wrote : Re: Manufacturing orders broken UOM

I have to test that theory, but that makes absolute sense!

Revision history for this message
Amit Parik (amit-parik) wrote :

Hello Raphael Valyi,

I have applied a patch at my end and then tested it but I have still faced the problem.
So the patch is not working properly.

Thanks.

Changed in openobject-addons:
status: Confirmed → In Progress
Revision history for this message
Mayur Maheshwari(OpenERP) (mma-openerp) wrote :

Hello,

Thanks for Reporting.
It has been fixed in lp:~openerp-dev/openobject-addons/trunk-bug-707287-mma
Revision ID: <email address hidden>
Revision num:4765.

It will be available in trunk soon.

Changed in openobject-addons:
status: In Progress → Fix Committed
Revision history for this message
Fabien (Open ERP) (fp-tinyerp) wrote :

Hello,

Thanks for the patch, but it does not fix the problem. It's like putting a try/except when something crash instead of fixing the real issue. As an example, the problem reappear if you click "assign products" manually on a picking.

The real problem is why do we have several stock.move for the same product with non compatible UoM in the inventory ? What kind of manual operations allows this ?

This means we must add constraints. I propose this:
  - You can never change the category of an existing UoM
  - You can never change the UoM/Purchase UoM category of a product (you can change the UoM if it's in the same UoM than
    before)

I am not sure, but these two constraints should be enough. I propose that the one who work on this bug tries a lot of scenario by changing/forcing the categories manually:
  - change the UoM (another category) during inventory, pickings, stock.move, sale, purchase..

I reopen the bug and reject the merge proposal.

description: updated
Changed in openobject-addons:
status: Fix Committed → Confirmed
Changed in openobject-addons:
status: Confirmed → In Progress
Revision history for this message
Atik Agewan(OpenERP) (aag-openerp) wrote :

Hello,

It has been fixed in lp:~openerp-dev/openobject-addons/trunk-bug-707287-aag
Revision ID: <email address hidden>
Revision num: 5446.
It will be available in trunk soon,

Thanks,
Atik Agewan

Changed in openobject-addons:
status: In Progress → Fix Committed
Revision history for this message
Raphael Collet (OpenERP) (rco-openerp) wrote :

landed in trunk
revno: 5620
revid: <email address hidden>

Changed in openobject-addons:
status: Fix Committed → Fix Released
Revision history for this message
Wided Kéfi (wided) wrote :

Hello,

Thanks for your work, but I applied the patch and it's not working, I still have the same error when trying to confirm a manufacturing order.

Revision history for this message
saiful fariz (fariz-saiful) wrote :

hello wided
I also have the same problem in OpenERP 6.1, until now

summary: - Manufacturing orders broken UOM
+ Changing UoM on products should be forbidden
tags: added: data-integrity
Revision history for this message
Numérigraphe (numerigraphe) wrote :

I have consulted with the maintenance team, who refused to patch the stable 6.0 release for fear of breaking instances in production.
However the patch that was merged into the trunk applies cleanly to v6.0 so I've uploaded a backport branch for those interested.
Lionel.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.