From c0665332c37c09ecd163d351e2b6d64373051db6 Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Sun, 15 Jul 2018 12:38:25 +0200 Subject: [PATCH 1/5] [FIX][9.0] pylint warning and errors --- account_move_line_stock_info/README.rst | 6 +- stock_cycle_count/models/stock_cycle_count.py | 26 +++++---- .../models/stock_cycle_count_rule.py | 33 +++++------ stock_cycle_count/models/stock_location.py | 57 ++++++++++--------- stock_cycle_count/models/stock_warehouse.py | 9 ++- .../wizards/stock_demand_estimate_wizard.py | 8 +-- stock_inventory_chatter/README.rst | 2 +- .../models/stock_inventory.py | 27 ++++----- .../models/stock_inventory_line.py | 37 ++++++------ .../models/stock_inventory.py | 3 + .../models/stock_slot_verification_request.py | 31 +++++----- stock_location_area_data/README.rst | 2 +- .../tests/test_mto_mts_route.py | 1 + .../views/stock_move_view.xml | 2 +- .../wizard/assign_manual_quants_view.xml | 2 +- 15 files changed, 135 insertions(+), 111 deletions(-) diff --git a/account_move_line_stock_info/README.rst b/account_move_line_stock_info/README.rst index b0021ad3f..cc71283c4 100644 --- a/account_move_line_stock_info/README.rst +++ b/account_move_line_stock_info/README.rst @@ -13,11 +13,11 @@ Usage ===== * The stock manager can check the journal items by accessing to 'Inventory > -Reports > Stock moves'. + Reports > Stock moves'. * A user belonging to the group 'Accounting & Finance/Adviser' can review the - details of a move that is associated to a journal item through - 'Invoicing > Adviser > Journal Entries (or Journal items)'. + details of a move that is associated to a journal item through + 'Invoicing > Adviser > Journal Entries (or Journal items)'. .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot diff --git a/stock_cycle_count/models/stock_cycle_count.py b/stock_cycle_count/models/stock_cycle_count.py index ebd8f86d0..c545f5e2d 100644 --- a/stock_cycle_count/models/stock_cycle_count.py +++ b/stock_cycle_count/models/stock_cycle_count.py @@ -12,9 +12,10 @@ class StockCycleCount(models.Model): _description = "Stock Cycle Counts" _inherit = 'mail.thread' - @api.one + @api.depends('stock_adjustment_ids') def _count_inventory_adj(self): - self.inventory_adj_count = len(self.stock_adjustment_ids) + for rec in self: + rec.inventory_adj_count = len(rec.stock_adjustment_ids) @api.model def create(self, vals): @@ -57,9 +58,9 @@ class StockCycleCount(models.Model): comodel_name='res.company', string='Company', required=True, default=_company_get, readonly=True) - @api.one + @api.multi def do_cancel(self): - self.state = 'cancelled' + self.write({'state': 'cancelled'}) @api.model def _prepare_inventory_adjustment(self): @@ -70,15 +71,16 @@ class StockCycleCount(models.Model): 'exclude_sublocation': True } - @api.one + @api.multi def action_create_inventory_adjustment(self): - if self.state != 'draft': - raise UserError(_( - "You can only confirm cycle counts in state 'Planned'." - )) - data = self._prepare_inventory_adjustment() - self.env['stock.inventory'].create(data) - self.state = 'open' + for rec in self: + if rec.state != 'draft': + raise UserError(_( + "You can only confirm cycle counts in state 'Planned'." + )) + data = rec._prepare_inventory_adjustment() + rec.env['stock.inventory'].create(data) + rec.state = 'open' return True @api.multi diff --git a/stock_cycle_count/models/stock_cycle_count_rule.py b/stock_cycle_count/models/stock_cycle_count_rule.py index 6a952ce8c..7af288ca6 100644 --- a/stock_cycle_count/models/stock_cycle_count_rule.py +++ b/stock_cycle_count/models/stock_cycle_count_rule.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# coding: utf-8 # Copyright 2017 Eficent Business and IT Consulting Services S.L. # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). @@ -13,9 +13,10 @@ class StockCycleCountRule(models.Model): _name = 'stock.cycle.count.rule' _description = "Stock Cycle Counts Rules" - @api.one + @api.multi def _compute_currency(self): - self.currency_id = self.env.user.company_id.currency_id + for rec in self: + rec.currency_id = self.env.user.company_id.currency_id @api.model def _selection_rule_types(self): @@ -25,23 +26,23 @@ class StockCycleCountRule(models.Model): ('accuracy', _('Minimum Accuracy')), ('zero', _('Zero Confirmation'))] - @api.one @api.constrains('rule_type', 'warehouse_ids') def _check_zero_rule(self): - if self.rule_type == 'zero' and len(self.warehouse_ids) > 1: - raise UserError( - _('Zero confirmation rules can only have one warehouse ' - 'assigned.') - ) - if self.rule_type == 'zero': - zero_rule = self.search([ - ('rule_type', '=', 'zero'), - ('warehouse_ids', '=', self.warehouse_ids.id)]) - if len(zero_rule) > 1: + for rec in self: + if rec.rule_type == 'zero' and len(rec.warehouse_ids) > 1: raise UserError( - _('You can only have one zero confirmation rule per ' - 'warehouse.') + _('Zero confirmation rules can only have one warehouse ' + 'assigned.') ) + if rec.rule_type == 'zero': + zero_rule = self.search([ + ('rule_type', '=', 'zero'), + ('warehouse_ids', '=', rec.warehouse_ids.id)]) + if len(zero_rule) > 1: + err = _( + 'Warehouses can only have one zero-confirmation rule.' + ) + raise UserError(err) @api.onchange('rule_type') def _get_rule_description(self): diff --git a/stock_cycle_count/models/stock_location.py b/stock_cycle_count/models/stock_location.py index bf040984a..2dc9c94d0 100644 --- a/stock_cycle_count/models/stock_location.py +++ b/stock_cycle_count/models/stock_location.py @@ -20,19 +20,23 @@ except (ImportError, IOError) as err: class StockLocation(models.Model): _inherit = 'stock.location' - @api.one + @api.multi def _compute_loc_accuracy(self): - history = self.env['stock.inventory'].search([ - ('location_id', '=', self.id), ('state', '=', 'done')]) - history = history.sorted(key=lambda r: r.write_date, reverse=True) - if history: - wh_id = self.get_warehouse(self) - wh = self.env['stock.warehouse'].browse(wh_id) - if len(history) > wh.counts_for_accuracy_qty: - self.loc_accuracy = mean(history[:wh.counts_for_accuracy_qty]. - mapped('inventory_accuracy')) - else: - self.loc_accuracy = mean(history.mapped('inventory_accuracy')) + for rec in self: + history = self.env['stock.inventory'].search([ + ('location_id', '=', rec.id), ('state', '=', 'done')]) + history = history.sorted(key=lambda r: r.write_date, reverse=True) + if history: + wh_id = rec.get_warehouse(rec) + wh = self.env['stock.warehouse'].browse(wh_id) + if len(history) > wh.counts_for_accuracy_qty: + rec.loc_accuracy = mean( + history[:wh.counts_for_accuracy_qty]. + mapped('inventory_accuracy')) + else: + rec.loc_accuracy = mean( + history.mapped('inventory_accuracy') + ) zero_confirmation_disabled = fields.Boolean( string='Disable Zero Confirmations', @@ -56,26 +60,27 @@ class StockLocation(models.Model): domain = [('location_id', '=', self.id)] return domain - @api.one + @api.multi def check_zero_confirmation(self): - if not self.zero_confirmation_disabled: - wh_id = self.get_warehouse(self) - wh = self.env['stock.warehouse'].browse(wh_id) - rule_model = self.env['stock.cycle.count.rule'] - zero_rule = rule_model.search([ - ('rule_type', '=', 'zero'), - ('warehouse_ids', '=', wh.id)]) - if zero_rule: - quants = self.env['stock.quant'].search( - self._get_zero_confirmation_domain()) - if not quants: - self.create_zero_confirmation_cycle_count() + rule_model = self.env['stock.cycle.count.rule'] + for rec in self: + if not rec.zero_confirmation_disabled: + wh_id = rec.get_warehouse(rec) + wh = self.env['stock.warehouse'].browse(wh_id) + zero_rule = rule_model.search([ + ('rule_type', '=', 'zero'), + ('warehouse_ids', '=', wh.id)]) + if zero_rule: + quants = self.env['stock.quant'].search( + rec._get_zero_confirmation_domain()) + if not quants: + rec.create_zero_confirmation_cycle_count() def create_zero_confirmation_cycle_count(self): date = datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT) wh_id = self.get_warehouse(self) date_horizon = self.env['stock.warehouse'].browse( - wh_id).get_horizon_date()[0].strftime( + wh_id).get_horizon_date().strftime( DEFAULT_SERVER_DATETIME_FORMAT) counts_planned = self.env['stock.cycle.count'].search([ ('date_deadline', '<', date_horizon), ('state', '=', 'draft'), diff --git a/stock_cycle_count/models/stock_warehouse.py b/stock_cycle_count/models/stock_warehouse.py index 453045b29..d31efa1b4 100644 --- a/stock_cycle_count/models/stock_warehouse.py +++ b/stock_cycle_count/models/stock_warehouse.py @@ -28,8 +28,9 @@ class StockWarehouse(models.Model): help='Number of latest inventories used to calculate location ' 'accuracy') - @api.one + @api.multi def get_horizon_date(self): + self.ensure_one() date = datetime.today() delta = timedelta(self.cycle_count_planning_horizon) date_horizon = date + delta @@ -62,11 +63,15 @@ class StockWarehouse(models.Model): ('rule_type', '!=', 'zero'), ('warehouse_ids', '=', self.id)]) return rules - @api.one + @api.multi def action_compute_cycle_count_rules(self): ''' Apply the rule in all the sublocations of a given warehouse(s) and returns a list with required dates for the cycle count of each location ''' + for rec in self: + rec._do_compute_cycle_count_rules() + + def _do_compute_cycle_count_rules(self): proposed_cycle_counts = [] rules = self._cycle_count_rules_to_compute() for rule in rules: diff --git a/stock_demand_estimate/wizards/stock_demand_estimate_wizard.py b/stock_demand_estimate/wizards/stock_demand_estimate_wizard.py index ebab92e02..7c3b2eb82 100644 --- a/stock_demand_estimate/wizards/stock_demand_estimate_wizard.py +++ b/stock_demand_estimate/wizards/stock_demand_estimate_wizard.py @@ -150,12 +150,12 @@ class DemandEstimateWizard(models.TransientModel): comodel_name="product.product", string="Products") - @api.one @api.constrains('date_start', 'date_end') def _check_start_end_dates(self): - if self.date_start > self.date_end: - raise ValidationError(_( - 'The start date cannot be later than the end date.')) + for rec in self: + if rec.date_start > rec.date_end: + raise ValidationError(_( + 'The start date cannot be later than the end date.')) @api.multi def _prepare_demand_estimate_sheet(self): diff --git a/stock_inventory_chatter/README.rst b/stock_inventory_chatter/README.rst index 0b94573b9..fb221f9c3 100644 --- a/stock_inventory_chatter/README.rst +++ b/stock_inventory_chatter/README.rst @@ -49,4 +49,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. \ No newline at end of file +To contribute to this module, please visit https://odoo-community.org. diff --git a/stock_inventory_discrepancy/models/stock_inventory.py b/stock_inventory_discrepancy/models/stock_inventory.py index 28af0aea9..3addaec0c 100644 --- a/stock_inventory_discrepancy/models/stock_inventory.py +++ b/stock_inventory_discrepancy/models/stock_inventory.py @@ -17,13 +17,13 @@ class StockInventory(models.Model): ('pending', 'Pending to Approve'), ('done', 'Validated')] - @api.one @api.depends('line_ids.product_qty', 'line_ids.theoretical_qty') def _compute_over_discrepancy_line_count(self): - lines = self.line_ids - self.over_discrepancy_line_count = sum( - d.discrepancy_percent > d.discrepancy_threshold - for d in lines) + for rec in self: + lines = rec.line_ids + rec.over_discrepancy_line_count = sum( + d.discrepancy_percent > d.discrepancy_threshold + for d in lines) state = fields.Selection( selection=INVENTORY_STATE_SELECTION, @@ -57,15 +57,16 @@ class StockInventory(models.Model): 'this action.') ) - @api.one + @api.multi def action_done(self): - if self.over_discrepancy_line_count and self.line_ids.filtered( - lambda t: t.discrepancy_threshold > 0.0): - if self.env.context.get('normal_view', False): - self.action_over_discrepancies() - return True - else: - self._check_group_inventory_validation_always() + for rec in self: + if rec.over_discrepancy_line_count and rec.line_ids.filtered( + lambda t: t.discrepancy_threshold > 0.0): + if self.env.context.get('normal_view', False): + rec.action_over_discrepancies() + return True + else: + rec._check_group_inventory_validation_always() return super(StockInventory, self).action_done() @api.multi diff --git a/stock_inventory_discrepancy/models/stock_inventory_line.py b/stock_inventory_discrepancy/models/stock_inventory_line.py index b13e99d43..a57e28e70 100644 --- a/stock_inventory_discrepancy/models/stock_inventory_line.py +++ b/stock_inventory_discrepancy/models/stock_inventory_line.py @@ -9,26 +9,29 @@ from openerp import api, fields, models class StockInventoryLine(models.Model): _inherit = 'stock.inventory.line' - @api.one + @api.depends('product_qty', 'theoretical_qty') def _compute_discrepancy(self): - self.discrepancy_qty = self.product_qty - self.theoretical_qty - if self.theoretical_qty: - self.discrepancy_percent = 100 * abs( - (self.product_qty - self.theoretical_qty) / - self.theoretical_qty) - elif not self.theoretical_qty and self.product_qty: - self.discrepancy_percent = 100.0 + for rec in self: + rec.discrepancy_qty = rec.product_qty - rec.theoretical_qty + if rec.theoretical_qty: + rec.discrepancy_percent = 100 * abs( + (rec.product_qty - rec.theoretical_qty) / + rec.theoretical_qty) + elif not rec.theoretical_qty and rec.product_qty: + rec.discrepancy_percent = 100.0 - @api.one + @api.multi def _get_discrepancy_threshold(self): - wh_id = self.location_id.get_warehouse(self.location_id) - wh = self.env['stock.warehouse'].browse(wh_id) - if self.location_id.discrepancy_threshold > 0.0: - self.discrepancy_threshold = self.location_id.discrepancy_threshold - elif wh.discrepancy_threshold > 0.0: - self.discrepancy_threshold = wh.discrepancy_threshold - else: - self.discrepancy_threshold = False + for rec in self: + wh_id = rec.location_id.get_warehouse(rec.location_id) + wh = self.env['stock.warehouse'].browse(wh_id) + if rec.location_id.discrepancy_threshold > 0.0: + rec.discrepancy_threshold = \ + rec.location_id.discrepancy_threshold + elif wh.discrepancy_threshold > 0.0: + rec.discrepancy_threshold = wh.discrepancy_threshold + else: + rec.discrepancy_threshold = False discrepancy_qty = fields.Float( string='Discrepancy', diff --git a/stock_inventory_exclude_sublocation/models/stock_inventory.py b/stock_inventory_exclude_sublocation/models/stock_inventory.py index af4299dc8..6bdf89789 100644 --- a/stock_inventory_exclude_sublocation/models/stock_inventory.py +++ b/stock_inventory_exclude_sublocation/models/stock_inventory.py @@ -35,6 +35,9 @@ class StockInventory(models.Model): domain += ' and package_id = %s' args += (inventory.package_id.id,) + # disable error about SQL injection as the code here is generating + # a vulnerability + # pylint: disable = E8103 self.env.cr.execute(''' SELECT product_id, sum(qty) as product_qty, location_id, lot_id as prod_lot_id, package_id, owner_id as partner_id diff --git a/stock_inventory_verification_request/models/stock_slot_verification_request.py b/stock_inventory_verification_request/models/stock_slot_verification_request.py index a200494d7..cf7910034 100644 --- a/stock_inventory_verification_request/models/stock_slot_verification_request.py +++ b/stock_inventory_verification_request/models/stock_slot_verification_request.py @@ -16,13 +16,15 @@ class SlotVerificationRequest(models.Model): 'stock.slot.verification.request') or '' return super(SlotVerificationRequest, self).create(vals) - @api.one + @api.depends('involved_move_ids') def _count_involved_moves(self): - self.involved_move_count = len(self.involved_move_ids) + for rec in self: + rec.involved_move_count = len(rec.involved_move_ids) - @api.one + @api.depends('involved_inv_line_ids') def _count_involved_inv_lines(self): - self.involved_inv_line_count = len(self.involved_inv_line_ids) + for rec in self: + rec.involved_inv_line_count = len(rec.involved_inv_line_ids) name = fields.Char(string='Name', readonly=True) inventory_id = fields.Many2one(comodel_name='stock.inventory', @@ -81,23 +83,24 @@ class SlotVerificationRequest(models.Model): self._get_involved_lines_domain()) return involved_moves, involved_lines - @api.one + @api.multi def action_confirm(self): - self.state = 'open' - involved_moves, involved_lines = \ - self._get_involved_lines_and_locations() - self.involved_move_ids = involved_moves - self.involved_inv_line_ids = involved_lines + for rec in self: + rec.state = 'open' + involved_moves, involved_lines = \ + rec._get_involved_lines_and_locations() + rec.involved_move_ids = involved_moves + rec.involved_inv_line_ids = involved_lines return True - @api.one + @api.multi def action_cancel(self): - self.state = 'cancelled' + self.write({'state': 'cancelled'}) return True - @api.one + @api.multi def action_solved(self): - self.state = 'done' + self.write({'state': 'done'}) return True @api.multi diff --git a/stock_location_area_data/README.rst b/stock_location_area_data/README.rst index 9d6249f8a..be6819a9c 100644 --- a/stock_location_area_data/README.rst +++ b/stock_location_area_data/README.rst @@ -52,4 +52,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. \ No newline at end of file +To contribute to this module, please visit https://odoo-community.org. diff --git a/stock_mts_mto_rule/tests/test_mto_mts_route.py b/stock_mts_mto_rule/tests/test_mto_mts_route.py index f603b74c3..d54343b81 100644 --- a/stock_mts_mto_rule/tests/test_mto_mts_route.py +++ b/stock_mts_mto_rule/tests/test_mto_mts_route.py @@ -1,3 +1,4 @@ +# coding: utf-8 # Author: Florian da Costa # Copyright 2015 Akretion # diff --git a/stock_quant_manual_assign/views/stock_move_view.xml b/stock_quant_manual_assign/views/stock_move_view.xml index c015de1aa..873802d2e 100644 --- a/stock_quant_manual_assign/views/stock_move_view.xml +++ b/stock_quant_manual_assign/views/stock_move_view.xml @@ -31,4 +31,4 @@ - \ No newline at end of file + diff --git a/stock_quant_manual_assign/wizard/assign_manual_quants_view.xml b/stock_quant_manual_assign/wizard/assign_manual_quants_view.xml index df8288b0e..cd5c28c80 100644 --- a/stock_quant_manual_assign/wizard/assign_manual_quants_view.xml +++ b/stock_quant_manual_assign/wizard/assign_manual_quants_view.xml @@ -33,4 +33,4 @@ - \ No newline at end of file + From f48d02764f729a01f7e4d1eaab8050933e765feb Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Sun, 15 Jul 2018 13:57:36 +0200 Subject: [PATCH 2/5] [FIX] bad inheritance declaration --- .../views/stock_inventory_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_inventory_verification_request/views/stock_inventory_view.xml b/stock_inventory_verification_request/views/stock_inventory_view.xml index f8ccffdcc..2f007a93b 100644 --- a/stock_inventory_verification_request/views/stock_inventory_view.xml +++ b/stock_inventory_verification_request/views/stock_inventory_view.xml @@ -7,7 +7,7 @@ Inventory form view - SVR extension stock.inventory - + From 7ffd86c0a9491fa5214f4a2d840ea93035a622dc Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Tue, 17 Jul 2018 08:05:59 +0200 Subject: [PATCH 3/5] remove bad use of api.model the body of the methods depend on self containing exactly one record --- .../models/stock_slot_verification_request.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/stock_inventory_verification_request/models/stock_slot_verification_request.py b/stock_inventory_verification_request/models/stock_slot_verification_request.py index cf7910034..316615566 100644 --- a/stock_inventory_verification_request/models/stock_slot_verification_request.py +++ b/stock_inventory_verification_request/models/stock_slot_verification_request.py @@ -62,20 +62,17 @@ class SlotVerificationRequest(models.Model): string='Involved Inventory Lines') involved_inv_line_count = fields.Integer(compute=_count_involved_inv_lines) - @api.model def _get_involved_moves_domain(self): domain = [('product_id', '=', self.product_id.id), '|', ('location_id', '=', self.location_id.id), ('location_dest_id', '=', self.location_id.id)] return domain - @api.model def _get_involved_lines_domain(self): domain = [('product_id', '=', self.product_id.id), ('location_id', '=', self.location_id.id)] return domain - @api.model def _get_involved_lines_and_locations(self): involved_moves = self.env['stock.move'].search( self._get_involved_moves_domain()) From 04ee39f3e5da53a54d482e189852cd3744161c5a Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Tue, 17 Jul 2018 08:09:03 +0200 Subject: [PATCH 4/5] [IMP] replace python sort with SQL --- stock_cycle_count/models/stock_location.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/stock_cycle_count/models/stock_location.py b/stock_cycle_count/models/stock_location.py index 2dc9c94d0..93886b082 100644 --- a/stock_cycle_count/models/stock_location.py +++ b/stock_cycle_count/models/stock_location.py @@ -23,9 +23,12 @@ class StockLocation(models.Model): @api.multi def _compute_loc_accuracy(self): for rec in self: - history = self.env['stock.inventory'].search([ - ('location_id', '=', rec.id), ('state', '=', 'done')]) - history = history.sorted(key=lambda r: r.write_date, reverse=True) + history = self.env['stock.inventory'].search( + [('location_id', '=', rec.id), + ('state', '=', 'done'), + ], + order='write_date DESC' + ) if history: wh_id = rec.get_warehouse(rec) wh = self.env['stock.warehouse'].browse(wh_id) From d78e0a8efdae4601fbeb07bcf2b183cabb947d68 Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Tue, 17 Jul 2018 08:48:34 +0200 Subject: [PATCH 5/5] [REF] don't rely on being able to sum booleans --- stock_inventory_discrepancy/models/stock_inventory.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/stock_inventory_discrepancy/models/stock_inventory.py b/stock_inventory_discrepancy/models/stock_inventory.py index 3addaec0c..897754c53 100644 --- a/stock_inventory_discrepancy/models/stock_inventory.py +++ b/stock_inventory_discrepancy/models/stock_inventory.py @@ -20,10 +20,11 @@ class StockInventory(models.Model): @api.depends('line_ids.product_qty', 'line_ids.theoretical_qty') def _compute_over_discrepancy_line_count(self): for rec in self: - lines = rec.line_ids - rec.over_discrepancy_line_count = sum( - d.discrepancy_percent > d.discrepancy_threshold - for d in lines) + lines = rec.line_ids.filtered( + lambda line: + line.discrepancy_percent > line.discrepancy_threshold + ) + rec.over_discrepancy_line_count = len(lines) state = fields.Selection( selection=INVENTORY_STATE_SELECTION,