Skip to Content
Menu
This question has been flagged
1 Reply
6489 Views


I have records in the stock.move table that has One2many relation to stock.move.reconcile with column move_to_id which is the ID of another record in stock.move table. So this chain can be thousands of records.

As you can see in my example I loop trough all records and go down tier by tier, but as I said before there could be thousands of linked records so my approach will not work here.

I do know that probably I need to use a while loop here, something like while there is move_to_ids, then I should loop through records and keep adding IDs to list, but I just can't figure it out how to do it.

  • move1(stock.move ID = 10) record that has One2many relation with 2 records inside: move_to_ids (stock.move.reconcile)

  • each of move_to_ids has move_to_id(many2one, 'stock.move' ID = 11)

  • each of this move_to_id(stock.move, ID=11) records have again any number of move_to_ids (stock.move.reconcile) and each of thismove_to_idsrecords havemove_to_id('stock.move', ID=12)` and so on.

So basically I want to add to list all move_to_id IDs 10, 11, 12, etc. to list for all related move_to_ids.

moves_to_recalculate = [10,11,12] and so on until when there is 0 move_to_ids to get move_to_id from.

class StockMove(models.Model):
_name = 'stock.move'

move_to_ids = fields.One2many(
    'stock.move.reconcile', 'move_from_id', string='Move to')

 move_from_ids = fields.One2many(
    'stock.move.reconcile', 'move_to_id', string='Move From'
)
class StockMoveReconcile(models.Model):
    _name = 'stock.move.reconcile'
    _description = 'Stock Move Reconcile'

    move_to_id = fields.Many2one('stock.move', string='Move To')
    move_from_id = fields.Many2one('stock.move', string='Move From')

def recalculate(self):
    moves = self.browse(('active_ids'))
    moves_to_recalculate = []
    for move1 in moves:
        #I add my first move in chain to list
        moves_to_recalculate.append(move1.id)
        #First move have 2 moves_to_ids so i make another loop to add it ID to list
        for second_tier_move in move.move_to_ids:
            moves_to_recalculate.appen(second_tier_move.move_to_id.id)
            # secont tier move has 1 move_to_ids so i do another loop, and add it's ID to list.
            for third_tier_move in second_tier_move.move_to_ids:
                moves_to_recalculate.appen(third_tier_move.move_to_id.id)
                #third_tier_move has another move_to_ids , and so on.


Avatar
Discard
Best Answer
Hello,
​​

I've cleaned up the approach to be only a few lines long. By keeping a record set of the newly explored records, we can keep mapping their move_to_ids, making them the newly explored, and keep going until there are no more newly explored. Just watch out, currently the moves_to_recalculate is a recordset, not a list of ids, so if you need ids, just use moves_to_recalculate.ids

def recalculate(self):
moves = self.browse(('active_ids'))
moves_to_recalculate = moves
current_moves = moves
while current_moves:
# For the current moves, find their all of their move_to_ids
current_moves = current_moves.mapped('move_to_ids')
# Remove duplicates, so we're only left with new moves. If there were no unique current_moves, the loop will end on this pass.
current_moves -= moves_to_recalculate
# Add the new ids to your moves_to_recalculate, ensuring the same record isn't added twice
moves_to_recalculate |= current_moves


Avatar
Discard
Author

Thank you for this answer, really simple but effective approach

Related Posts Replies Views Activity
1
Nov 19
3430
4
Mar 20
36045
2
Dec 15
3761
1
Mar 15
8477
2
Mar 15
6676