action_split has obvious bug and behavior not as expected

Bug #926541 reported by Jeroen Vet
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Fix Committed
OpenERP Publisher's Warranty Team

Bug Description

The expected behavior of action_split on stock.stock_move imho would be that the original move quantity is reduced by quantity if quantity < move.quantity and there are split off moves for as many as quantity allows, each of the split off moves having a a quantity equal (or less for the last split off move if any remainder) to the split_by_quantity.

However the actual behavior is that:
if quantity >= move.qty
- the original move is set to split_by_qty and its is returned as res[0]
- there are additional new split of moves for as many as quantity - split_by_qty (for the original move) allows and for the remainder. Their these ids are also returned.

if quantity < move.qty
- the system splits of moves and returns their ids but NEVER TOUCHES THE ORIGINAL MOVE. The original move is also not returned and remains having the old quantity.

There is also an obvious bug in that the uos_qty is not set correctly for the remainder.

I would suggest suggest the following changes in the code (indicated by the remarsk):

    def action_split(self, cr, uid, ids, quantity, split_by_qty=1, prefix=False, with_lot=True, context=None):
        """ Split Stock Move lines into production lot which specified split by quantity.
        @param cr: the database cursor
        @param uid: the user id
        @param ids: ids of stock move object to be splited
        @param split_by_qty : specify split by qty
        @param prefix : specify prefix of production lot
        @param with_lot : if true, prodcution lot will assign for split line otherwise not.
        @param context: context arguments
        @return: Splited move lines

        if context is None:
            context = {}
        if quantity <= 0:
            raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))

        res = []

        for move in self.browse(cr, uid, ids, context=context):
            if split_by_qty <= 0 or quantity == 0:
                return res

            uos_qty = split_by_qty / move.product_qty * move.product_uos_qty

            quantity_rest = quantity % split_by_qty
            #uos_qty_rest = split_by_qty / move.product_qty * move.product_uos_qty
            uos_qty_rest = quantity_rest / move.product_qty * move.product_uos_qty

            update_val = {
                'product_qty': split_by_qty,
                'product_uos_qty': uos_qty,
            for idx in range(int(quantity//split_by_qty)):
                if not idx and move.product_qty<=quantity:
                    current_move =
                    current_move = self.copy(cr, uid,, {'state': move.state})
                if with_lot:
                    update_val['prodlot_id'] = self._create_lot(cr, uid, [current_move],

                self.write(cr, uid, [current_move], update_val)

            if quantity_rest > 0:
                idx = int(quantity//split_by_qty)
                update_val['product_qty'] = quantity_rest
                update_val['product_uos_qty'] = uos_qty_rest
                if not idx and move.product_qty<=quantity:
                    current_move =
                    current_move = self.copy(cr, uid,, {'state': move.state})


                if with_lot:
                    update_val['prodlot_id'] = self._create_lot(cr, uid, [current_move],

                self.write(cr, uid, [current_move], update_val)

            # added to modify behavior to always update original move by reducing it with quantity if quantity < move qty
            if quantity < move.product_qty:
                update_val['product_qty'] = move.product_qty - quantity
                update_val['product_uos_qty'] = (move.product_qty - quantity)/move.product_qty * move.product_uos_qty

        return res

Tags: maintenance

Related branches

Revision history for this message
Amit Bhavsar (Open ERP) (amb-openerp) wrote :

Hello Jeroen Vet,

I have checked your Issue with latest revision and also with stable. But at my end it's running fine as expected. That's why I have attached the video. Would you please check it And notify us where you have faced the problem.

Correct me If I am wrong!

Thank you and waiting for your reply!

Changed in openobject-addons:
status: New → Incomplete
Revision history for this message
Jeroen Vet (jeroen-vet) wrote :

Hi Amit,
Thanks for your feedback. Stock splitting works fine if you use the stock split wizard, this is because the wizard doesn't actually use the action_split method on stock.move but uses the split_move_line method on stock.move.line.split (an osv.memory object).
I don't think action_split is used anywhere in the code so that is probably why the incorrect code went unnoticed. I came across the bug when I tried to use action_split in one of my own customisations. Although action_split is not used in the system I still think that, since the method is available, it should either work correctly or be removed altogether.
BR Jeroen

Revision history for this message
Amit Bhavsar (Open ERP) (amb-openerp) wrote :

Hello Jeroen Vet,

Yes you are right, "action_split" function is not used anywhere. we have set this in revision number 5860.2.1.would you please check it.

But Currently we can not remove this. So We have set this Issue in future That's why we are considering it as a "Wishlist".


Changed in openobject-addons:
assignee: nobody → OpenERP R&D Addons Team 2 (openerp-dev-addons2)
importance: Undecided → Wishlist
status: Incomplete → Confirmed
Changed in openobject-addons:
assignee: OpenERP R&D Addons Team 2 (openerp-dev-addons2) → OpenERP Publisher's Warranty Team (openerp-opw)
tags: added: maintenance
Changed in openobject-addons:
status: Confirmed → Fix Committed
Changed in openobject-addons:
status: Fix Committed → New
status: New → Fix Committed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers