From ba251eb05a955584803e0f445d4fa90c3c6c20fc Mon Sep 17 00:00:00 2001 From: Jordi Ballester Alomar Date: Wed, 28 Oct 2020 06:17:14 +0100 Subject: [PATCH] [IMP] : black, isort, prettier --- stock_pull_list/__manifest__.py | 14 +-- stock_pull_list/tests/common.py | 64 +++++----- stock_pull_list/tests/test_stock_pull_list.py | 11 +- .../wizards/stock_pull_list_wizard.py | 114 ++++++++---------- .../wizards/stock_pull_list_wizard.xml | 103 ++++++++++------ 5 files changed, 156 insertions(+), 150 deletions(-) diff --git a/stock_pull_list/__manifest__.py b/stock_pull_list/__manifest__.py index c03860f7d..0de3020bb 100644 --- a/stock_pull_list/__manifest__.py +++ b/stock_pull_list/__manifest__.py @@ -4,21 +4,15 @@ { "name": "Stock Pull List", "summary": "The pull list checks the stock situation and calculates " - "needed quantities.", + "needed quantities.", "version": "12.0.1.0.1", "license": "LGPL-3", "website": "https://github.com/OCA/stock-logistics-warehouse", - "author": "ForgeFlow, " - "Odoo Community Association (OCA)", + "author": "ForgeFlow, " "Odoo Community Association (OCA)", "maintainers": ["LoisRForgeFlow"], "development_status": "Alpha", "category": "Warehouse Management", - "depends": [ - "stock", - "stock_available_unreserved", - ], - "data": [ - "wizards/stock_pull_list_wizard.xml", - ], + "depends": ["stock", "stock_available_unreserved",], + "data": ["wizards/stock_pull_list_wizard.xml",], "installable": True, } diff --git a/stock_pull_list/tests/common.py b/stock_pull_list/tests/common.py index 7a43a09fb..21f954c24 100644 --- a/stock_pull_list/tests/common.py +++ b/stock_pull_list/tests/common.py @@ -1,14 +1,13 @@ # Copyright 2020 ForgeFlow, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo.tests.common import TransactionCase -from odoo import fields - from datetime import timedelta as td +from odoo import fields +from odoo.tests.common import TransactionCase + class TestPullListCommon(TransactionCase): - def setUp(self): super().setUp() self.wh_obj = self.env["stock.warehouse"] @@ -20,21 +19,17 @@ class TestPullListCommon(TransactionCase): self.warehouse = self.env.ref("stock.warehouse0") self.customer_loc = self.env.ref("stock.stock_location_customers") - self.warehouse_2 = self.wh_obj.create({ - "code": "WH-T", - "name": "Warehouse Test", - }) - self.product_a = self.env["product.product"].create({ - "name": "test product A", - "default_code": "TEST-A", - "type": "product", - }) + self.warehouse_2 = self.wh_obj.create( + {"code": "WH-T", "name": "Warehouse Test",} + ) + self.product_a = self.env["product.product"].create( + {"name": "test product A", "default_code": "TEST-A", "type": "product",} + ) route_vals = { "name": "WH2 -> WH", } - self.transfer_route = self.env["stock.location.route"].create( - route_vals) + self.transfer_route = self.env["stock.location.route"].create(route_vals) rule_vals = { "location_id": self.warehouse.lot_stock_id.id, "location_src_id": self.warehouse_2.lot_stock_id.id, @@ -59,21 +54,28 @@ class TestPullListCommon(TransactionCase): self.create_picking_out_a(self.date_3, 70) def create_picking_out_a(self, date_move, qty): - picking = self.picking_obj.create({ - "picking_type_id": self.ref("stock.picking_type_out"), - "location_id": self.warehouse.lot_stock_id.id, - "location_dest_id": self.customer_loc.id, - "move_lines": [ - (0, 0, { - "name": "Test move", - "product_id": self.product_a.id, - "date_expected": date_move, - "date": date_move, - "product_uom": self.product_a.uom_id.id, - "product_uom_qty": qty, - "location_id": self.warehouse.lot_stock_id.id, - "location_dest_id": self.customer_loc.id, - })] - }) + picking = self.picking_obj.create( + { + "picking_type_id": self.ref("stock.picking_type_out"), + "location_id": self.warehouse.lot_stock_id.id, + "location_dest_id": self.customer_loc.id, + "move_lines": [ + ( + 0, + 0, + { + "name": "Test move", + "product_id": self.product_a.id, + "date_expected": date_move, + "date": date_move, + "product_uom": self.product_a.uom_id.id, + "product_uom_qty": qty, + "location_id": self.warehouse.lot_stock_id.id, + "location_dest_id": self.customer_loc.id, + }, + ) + ], + } + ) picking.action_confirm() return picking diff --git a/stock_pull_list/tests/test_stock_pull_list.py b/stock_pull_list/tests/test_stock_pull_list.py index efb4b9a24..69a8d225a 100644 --- a/stock_pull_list/tests/test_stock_pull_list.py +++ b/stock_pull_list/tests/test_stock_pull_list.py @@ -5,29 +5,24 @@ from .common import TestPullListCommon class TestStockPullList(TestPullListCommon): - def test_01_default_options(self): self._generate_moves() wiz = self.wiz_obj.create({}) wiz.action_prepare() lines = wiz.line_ids.filtered(lambda l: l.product_id == self.product_a) self.assertEqual(len(lines), 2) - line_1 = lines.filtered( - lambda l: l.date_expected == self.yesterday.date()) + line_1 = lines.filtered(lambda l: l.date_expected == self.yesterday.date()) self.assertEqual(line_1.raw_demand_qty, 50) self.assertEqual(line_1.needed_qty, 50) self.assertEqual(line_1.stock_rule_id, self.transfer_rule) - line_2 = lines.filtered( - lambda l: l.date_expected == self.date_3.date()) + line_2 = lines.filtered(lambda l: l.date_expected == self.date_3.date()) self.assertEqual(line_2.raw_demand_qty, 70) self.assertEqual(line_2.needed_qty, 70) def test_02_consolidate(self): self._generate_moves() - wiz = self.wiz_obj.create({ - "consolidate_by_product": True, - }) + wiz = self.wiz_obj.create({"consolidate_by_product": True,}) wiz.action_prepare() line = wiz.line_ids.filtered(lambda l: l.product_id == self.product_a) self.assertEqual(len(line), 1) diff --git a/stock_pull_list/wizards/stock_pull_list_wizard.py b/stock_pull_list/wizards/stock_pull_list_wizard.py index a1ff9636c..d34c3c2a0 100644 --- a/stock_pull_list/wizards/stock_pull_list_wizard.py +++ b/stock_pull_list/wizards/stock_pull_list_wizard.py @@ -1,11 +1,11 @@ # Copyright 2020 ForgeFlow, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +import itertools + from odoo import _, api, fields, models from odoo.exceptions import UserError -import itertools - class PullListWizard(models.TransientModel): _name = "stock.pull.list.wizard" @@ -16,20 +16,15 @@ class PullListWizard(models.TransientModel): res = super().default_get(fields) company = self.env.user.company_id wh = self.env["stock.warehouse"].search( - [("company_id", "=", company.id)], limit=1) - res.update({ - "warehouse_id": wh.id, - "location_id": wh.lot_stock_id.id, - }) + [("company_id", "=", company.id)], limit=1 + ) + res.update( + {"warehouse_id": wh.id, "location_id": wh.lot_stock_id.id,} + ) return res - location_id = fields.Many2one( - comodel_name="stock.location", - required=True, - ) - warehouse_id = fields.Many2one( - comodel_name="stock.warehouse", - ) + location_id = fields.Many2one(comodel_name="stock.location", required=True,) + warehouse_id = fields.Many2one(comodel_name="stock.warehouse",) line_ids = fields.One2many( comodel_name="stock.pull.list.wizard.line", inverse_name="wizard_id", @@ -38,17 +33,14 @@ class PullListWizard(models.TransientModel): # Step 1 - filtering options. exclude_reserved = fields.Boolean() location_dest_id = fields.Many2one( - string="Destination Location", - comodel_name="stock.location", + string="Destination Location", comodel_name="stock.location", ) date_to = fields.Date() consolidate_by_product = fields.Boolean( help="All needs for each product will be grouped in one line, " - "disregarding date.", - ) - procurement_group_ids = fields.Many2many( - comodel_name="procurement.group" + "disregarding date.", ) + procurement_group_ids = fields.Many2many(comodel_name="procurement.group") # Step 2 - filtering options. select_all = fields.Boolean(default=True) rule_action = fields.Selection( @@ -56,7 +48,7 @@ class PullListWizard(models.TransientModel): ) available_in_source_location = fields.Boolean( help="Select only rules with enough available stock in source " - "location. Applies for rules with a source location.", + "location. Applies for rules with a source location.", ) # Step 2 - grouping options. max_lines = fields.Integer() @@ -112,8 +104,9 @@ class PullListWizard(models.TransientModel): def _get_available_qty(self, product, location): product_obj = self.env["product.product"] - product_l = product_obj.with_context( - {"location": location.id}).browse(product.id) + product_l = product_obj.with_context({"location": location.id}).browse( + product.id + ) if self.exclude_reserved: return product_l.qty_available_not_res return product_l.qty_available @@ -125,23 +118,24 @@ class PullListWizard(models.TransientModel): "company_id": self.env.user.company_id, } stock_rule_id = self.env["procurement.group"]._get_rule( - product_id, location_id, values) + product_id, location_id, values + ) return stock_rule_id def action_prepare(self): domain = self._get_moves_demand_domain() # `read_group` is not possible here because of the date format the # method returns. - demand_moves = self.env["stock.move"].search( - domain, order="date_expected asc") + demand_moves = self.env["stock.move"].search(domain, order="date_expected asc") demand_dict = {} - force_date = fields.Date.today() if self.consolidate_by_product \ - else False + force_date = fields.Date.today() if self.consolidate_by_product else False for demand in demand_moves: key = ( - demand.product_id, demand.location_id, + demand.product_id, + demand.location_id, fields.Date.to_date(demand.date_expected) - if not force_date else force_date, + if not force_date + else force_date, ) prev = demand_dict.setdefault(key, 0.0) # TODO: when exclude_reserved is selected, handle partially avail. @@ -149,20 +143,24 @@ class PullListWizard(models.TransientModel): domain = self._get_moves_incoming_domain() incoming_moves = self.env["stock.move"].search( - domain, order="date_expected asc") + domain, order="date_expected asc" + ) incoming_dict = {} for supply in incoming_moves: move_for_date = demand_moves.filtered( - lambda m: m.product_id == supply.product_id and - m.date_expected >= supply.date_expected) + lambda m: m.product_id == supply.product_id + and m.date_expected >= supply.date_expected + ) if move_for_date: - date_selected = move_for_date[0].date_expected \ - if not force_date else force_date + date_selected = ( + move_for_date[0].date_expected if not force_date else force_date + ) else: # Supply is later than last demand -> ignore it. continue key = ( - supply.product_id, supply.location_dest_id, + supply.product_id, + supply.location_dest_id, fields.Date.to_date(date_selected), ) prev = incoming_dict.setdefault(key, 0.0) @@ -173,17 +171,17 @@ class PullListWizard(models.TransientModel): qty_assigned = {} for key, demand_qty in demand_dict.items(): supply_qty = incoming_dict.get(key, 0.0) - lines.append((0, 0, self._prepare_line_values( - key, demand_qty, supply_qty))) - self.update({ - "line_ids": lines, - }) + lines.append((0, 0, self._prepare_line_values(key, demand_qty, supply_qty))) + self.update( + {"line_ids": lines,} + ) res = self._act_window_pull_list_step_2() return res def _act_window_pull_list_step_2(self): view_id = self.env.ref( - "stock_pull_list.view_run_stock_pull_list_wizard_wizard_step_2").id + "stock_pull_list.view_run_stock_pull_list_wizard_wizard_step_2" + ).id res = { "name": _("Pull List"), "src_model": "stock.pull.list.wizard", @@ -202,8 +200,9 @@ class PullListWizard(models.TransientModel): if self.select_all: line.selected = True continue - rule_invalid = self.rule_action and \ - self.rule_action != line.stock_rule_id.action + rule_invalid = ( + self.rule_action and self.rule_action != line.stock_rule_id.action + ) if self.available_in_source_location: available = line._is_available_in_source_location() else: @@ -254,8 +253,7 @@ class PullListWizard(models.TransientModel): # User requesting the procurement is passed by context to be able to # update final MO, PO or trasfer with that information. # TODO: migration to v13: requested_uid is not needed. - pg_obj = self.env["procurement.group"].with_context( - requested_uid=self.env.user) + pg_obj = self.env["procurement.group"].with_context(requested_uid=self.env.user) grouping_keys = self._get_procurement_group_keys() fields = self._get_fields_for_keys() for gk in grouping_keys: @@ -275,8 +273,7 @@ class PullListWizard(models.TransientModel): group = pg_obj.create(self._prepare_proc_group_values()) proc_groups.append(group.id) - values = self._prepare_procurement_values( - line.date_expected, group) + values = self._prepare_procurement_values(line.date_expected, group) try: pg_obj.run( line.product_id, @@ -285,7 +282,7 @@ class PullListWizard(models.TransientModel): line.location_id, "Pull List %s" % self.id, "Pull List %s" % self.id, - values + values, ) except UserError as error: errors.append(error.name) @@ -307,28 +304,21 @@ class PullListWizardLine(models.TransientModel): _name = "stock.pull.list.wizard.line" _description = "Stock Pull List Wizard Line" - wizard_id = fields.Many2one( - comodel_name="stock.pull.list.wizard", - ) - product_id = fields.Many2one( - comodel_name="product.product", - ) - location_id = fields.Many2one( - comodel_name="stock.location", - ) + wizard_id = fields.Many2one(comodel_name="stock.pull.list.wizard",) + product_id = fields.Many2one(comodel_name="product.product",) + location_id = fields.Many2one(comodel_name="stock.location",) date_expected = fields.Date() available_qty = fields.Float() incoming_qty = fields.Float() raw_demand_qty = fields.Float() needed_qty = fields.Float() - stock_rule_id = fields.Many2one( - comodel_name="stock.rule", - ) + stock_rule_id = fields.Many2one(comodel_name="stock.rule",) selected = fields.Boolean(default=True) def _is_available_in_source_location(self): if not self.stock_rule_id.location_src_id: return False qty_avail = self.wizard_id._get_available_qty( - self.product_id, self.stock_rule_id.location_src_id) + self.product_id, self.stock_rule_id.location_src_id + ) return qty_avail > self.needed_qty diff --git a/stock_pull_list/wizards/stock_pull_list_wizard.xml b/stock_pull_list/wizards/stock_pull_list_wizard.xml index 75b9e872a..d1bfaa745 100644 --- a/stock_pull_list/wizards/stock_pull_list_wizard.xml +++ b/stock_pull_list/wizards/stock_pull_list_wizard.xml @@ -1,41 +1,50 @@ - + - stock.pull.list.wizard.form stock.pull.list.wizard
-

The pull list checks the stock situation at the given location and calculates +

The pull list checks the stock situation at the given location and calculates the shortfall quantities (quantity needed to cover all needs) for products.

- - + + -

All existing Stock moves moving outside of the location specified will be considered demand. +

All existing Stock moves moving outside of the location specified will be considered demand. You can filter these moves in the section below.

- - - + + + - - + +
-
- stock.pull.list.wizard.form.2 stock.pull.list.wizard @@ -44,51 +53,68 @@ - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + -