'If no pack operation, we do simple action_done of the picking.
Otherwise, do the pack operations.'

@api.multi
def do_transfer(self):

    self._create_lots_for_picking()
    no_pack_op_pickings = self.filtered((lambda picking: (not picking.pack_operation_ids)))
    no_pack_op_pickings.action_done()
    other_pickings = (self - no_pack_op_pickings)
    for picking in other_pickings:
        (need_rereserve, all_op_processed) = picking.picking_recompute_remaining_quantities()
        todo_moves = self.env['stock.move']
        toassign_moves = self.env['stock.move']
        if (not all_op_processed):
            todo_moves |= picking._create_extra_moves()
        if (need_rereserve or (not all_op_processed)):
            moves_reassign = any(((x.origin_returned_move_id or x.move_orig_ids) for x in picking.move_lines if (x.state not in ['done', 'cancel'])))
            if (moves_reassign and (picking.location_id.usage not in ('supplier', 'production', 'inventory'))):
                picking.with_context(reserve_only_ops=True, no_state_change=True).rereserve_quants(move_ids=picking.move_lines.ids)
            picking.do_recompute_remaining_quantities()
        for move in picking.move_lines:
            rounding = move.product_id.uom_id.rounding
            remaining_qty = move.remaining_qty
            if (move.state in ('done', 'cancel')):
                continue
            elif (move.state == 'draft'):
                toassign_moves |= move
            if (float_compare(remaining_qty, 0, precision_rounding=rounding) == 0):
                if (move.state in ('draft', 'assigned', 'confirmed')):
                    todo_moves |= move
            elif ((float_compare(remaining_qty, 0, precision_rounding=rounding) > 0) and (float_compare(remaining_qty, move.product_qty, precision_rounding=rounding) < 0)):
                new_move_id = move.split(remaining_qty)
                new_move = self.env['stock.move'].with_context(mail_notrack=True).browse(new_move_id)
                todo_moves |= move
                toassign_moves |= new_move
        if (todo_moves and (not self.env.context.get('do_only_split'))):
            todo_moves.action_done()
        elif self.env.context.get('do_only_split'):
            picking = picking.with_context(split=todo_moves.ids)
        picking._create_backorder()
    return True
