Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[17.0][FW] stock_helper: multiple ports from 14.0 #2176

Closed

Conversation

On a multi warehouse configuration
where a warehouse view_location is parent of an other warehouse's view_location
this will return the closest warehouse of a location

Not like the get_warehouse method (odoo core code)
which returns from all parent warehouses found
the first one ordered by the sequence
@henrybackman
Copy link
Author

The tests fail but I don't see how the failure is related to the changes done here

@rousseldenis
Copy link
Contributor

The tests fail but I don't see how the failure is related to the changes done here

@henrybackman That's because in Odoo stock module, get_warehousehas been replaced by warehouse_idfield.

Comment on lines 56 to 74
res = {}
for location in self:
wh = False
if location.parent_path:
for warehouse in warehouses:
if location.parent_path.startswith(
warehouse.view_location_id.parent_path
):
wh = warehouse
break
res[location.id] = wh
return res

def get_closest_warehouse(self):
"""Returns closest warehouse for current location."""
self.ensure_one()
location_and_warehouse = self._get_closest_warehouse()
warehouse = location_and_warehouse[self.id]
return warehouse or self.env["stock.warehouse"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
res = {}
for location in self:
wh = False
if location.parent_path:
for warehouse in warehouses:
if location.parent_path.startswith(
warehouse.view_location_id.parent_path
):
wh = warehouse
break
res[location.id] = wh
return res
def get_closest_warehouse(self):
"""Returns closest warehouse for current location."""
self.ensure_one()
location_and_warehouse = self._get_closest_warehouse()
warehouse = location_and_warehouse[self.id]
return warehouse or self.env["stock.warehouse"]
res = defaultdict(self.env["stock.warehouse"])
for location in self.filtered("parent_path"):
for warehouse in warehouses:
if location.parent_path.startswith(
warehouse.view_location_id.parent_path
):
res[location.id] = warehouse
break
return res
def get_closest_warehouse(self):
"""Returns closest warehouse for current location."""
self.ensure_one()
return self._get_closest_warehouse()[self.id]

Also, I kinda feel we can improve _get_closest_warehouse and drop the nested loop here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied the recommended change, but didn't want to mess about with the function more as I would first need to get more familiar with the context

test_warehouse.view_location_id.location_id = self.wh.lot_stock_id.id
location = test_warehouse.lot_stock_id

self.assertEqual(location.warehouse_id, self.wh)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails but I don't have enough context knowledge to say what it is testing and how to fix it.

When running the tests locally the location.warehouse_id ID increased after each run, so this way of testing doesn't seem stable.

First run: AssertionError: stock.warehouse(4,) != stock.warehouse(1,)
Second run: AssertionError: stock.warehouse(5,) != stock.warehouse(1,)
etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's normal. The warehouse(1) is the one defined in demo data (from stock module). The warehouse test_warehouse is the one created in tests (and so the id is incrementing at each run).

That said, your test will never succeed as your structure looks like :

 [WAREHOUSE(1)]
              ||
 [TEST WAREHOUSE]

As the parent of your view location of test warehouse is the stock location of the warehouse 1

@henrybackman
Copy link
Author

After looking into this more, it seems that the closest warehouse search has been implemented already in the stock_location _compute_warehouse_id. Would this make these PRs not worth porting? @mt-software-de @jbaudoux

https://github.com/odoo/odoo/blob/17.0/addons/stock/models/stock_location.py#L140

    @api.depends('warehouse_view_ids', 'location_id')
    def _compute_warehouse_id(self):
        warehouses = self.env['stock.warehouse'].search([('view_location_id', 'parent_of', self.ids)])
        warehouses = warehouses.sorted(lambda w: w.view_location_id.parent_path, reverse=True)
        view_by_wh = OrderedDict((wh.view_location_id.id, wh.id) for wh in warehouses)
        self.warehouse_id = False
        for loc in self:
            if not loc.parent_path:
                continue
            path = set(int(loc_id) for loc_id in loc.parent_path.split('/')[:-1])
            for view_location_id in view_by_wh:
                if view_location_id in path:
                    loc.warehouse_id = view_by_wh[view_location_id]
                    break

@mt-software-de
Copy link
Contributor

After looking into this more, it seems that the closest warehouse search has been implemented already in the stock_location _compute_warehouse_id. Would this make these PRs not worth porting? @mt-software-de @jbaudoux

https://github.com/odoo/odoo/blob/17.0/addons/stock/models/stock_location.py#L140

    @api.depends('warehouse_view_ids', 'location_id')
    def _compute_warehouse_id(self):
        warehouses = self.env['stock.warehouse'].search([('view_location_id', 'parent_of', self.ids)])
        warehouses = warehouses.sorted(lambda w: w.view_location_id.parent_path, reverse=True)
        view_by_wh = OrderedDict((wh.view_location_id.id, wh.id) for wh in warehouses)
        self.warehouse_id = False
        for loc in self:
            if not loc.parent_path:
                continue
            path = set(int(loc_id) for loc_id in loc.parent_path.split('/')[:-1])
            for view_location_id in view_by_wh:
                if view_location_id in path:
                    loc.warehouse_id = view_by_wh[view_location_id]
                    break

The PRs don't need a porting. It was fixed by this Odoo PR odoo/odoo#118128

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants