From 854bbe132d4b4672075a2477f49c96a0c60e2a63 Mon Sep 17 00:00:00 2001 From: hveficent Date: Tue, 28 Jan 2020 16:53:34 +0100 Subject: [PATCH] [IMP] stock_request: black, isort --- stock_request/__init__.py | 1 - stock_request/__manifest__.py | 7 +- stock_request/models/procurement_group.py | 17 +- stock_request/models/res_company.py | 4 +- stock_request/models/res_config_settings.py | 23 +- stock_request/models/stock_location.py | 49 +- stock_request/models/stock_location_route.py | 26 +- stock_request/models/stock_move.py | 51 +- stock_request/models/stock_move_line.py | 63 +- stock_request/models/stock_picking.py | 34 +- stock_request/models/stock_request.py | 319 ++--- .../models/stock_request_abstract.py | 246 ++-- .../models/stock_request_allocation.py | 107 +- stock_request/models/stock_request_order.py | 343 +++--- stock_request/models/stock_rule.py | 42 +- stock_request/models/stock_warehouse.py | 52 +- .../security/stock_request_security.xml | 6 +- stock_request/tests/__init__.py | 1 - stock_request/tests/test_stock_request.py | 1079 +++++++++-------- 19 files changed, 1375 insertions(+), 1095 deletions(-) diff --git a/stock_request/__init__.py b/stock_request/__init__.py index a9e337226..0650744f6 100644 --- a/stock_request/__init__.py +++ b/stock_request/__init__.py @@ -1,2 +1 @@ - from . import models diff --git a/stock_request/__manifest__.py b/stock_request/__manifest__.py index 1ca0ec1b5..983f42864 100644 --- a/stock_request/__manifest__.py +++ b/stock_request/__manifest__.py @@ -7,12 +7,9 @@ "version": "12.0.1.1.6", "license": "LGPL-3", "website": "https://github.com/stock-logistics-warehouse", - "author": "Eficent, " - "Odoo Community Association (OCA)", + "author": "Eficent, " "Odoo Community Association (OCA)", "category": "Warehouse Management", - "depends": [ - "stock", - ], + "depends": ["stock"], "data": [ "security/stock_request_security.xml", "security/ir.model.access.csv", diff --git a/stock_request/models/procurement_group.py b/stock_request/models/procurement_group.py index 9f697189f..c0730f15d 100644 --- a/stock_request/models/procurement_group.py +++ b/stock_request/models/procurement_group.py @@ -5,15 +5,16 @@ from odoo import api, models class ProcurementGroup(models.Model): - _inherit = 'procurement.group' + _inherit = "procurement.group" @api.model - def run(self, product_id, product_qty, product_uom, location_id, name, - origin, values): - if 'stock_request_id' in values and values.get('stock_request_id'): - req = self.env['stock.request'].browse( - values.get('stock_request_id')) + def run( + self, product_id, product_qty, product_uom, location_id, name, origin, values + ): + if "stock_request_id" in values and values.get("stock_request_id"): + req = self.env["stock.request"].browse(values.get("stock_request_id")) if req.order_id: origin = req.order_id.name - return super().run(product_id, product_qty, product_uom, location_id, - name, origin, values) + return super().run( + product_id, product_qty, product_uom, location_id, name, origin, values + ) diff --git a/stock_request/models/res_company.py b/stock_request/models/res_company.py index 998edf78f..de5589a16 100644 --- a/stock_request/models/res_company.py +++ b/stock_request/models/res_company.py @@ -7,8 +7,8 @@ from odoo import fields, models class ResCompany(models.Model): - _inherit = 'res.company' + _inherit = "res.company" stock_request_allow_virtual_loc = fields.Boolean( - string='Allow Virtual locations on Stock Requests', + string="Allow Virtual locations on Stock Requests" ) diff --git a/stock_request/models/res_config_settings.py b/stock_request/models/res_config_settings.py index 63231a8c4..7e60ed634 100644 --- a/stock_request/models/res_config_settings.py +++ b/stock_request/models/res_config_settings.py @@ -5,29 +5,34 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): - _inherit = 'res.config.settings' + _inherit = "res.config.settings" group_stock_request_order = fields.Boolean( - implied_group='stock_request.group_stock_request_order') + implied_group="stock_request.group_stock_request_order" + ) module_stock_request_purchase = fields.Boolean( - string='Stock Requests for Purchases') + string="Stock Requests for Purchases" + ) module_stock_request_kanban = fields.Boolean( - string='Stock Requests Kanban integration') + string="Stock Requests Kanban integration" + ) stock_request_allow_virtual_loc = fields.Boolean( - related='company_id.stock_request_allow_virtual_loc', - readonly=False) + related="company_id.stock_request_allow_virtual_loc", readonly=False + ) module_stock_request_analytic = fields.Boolean( - string='Stock Requests Analytic integration') + string="Stock Requests Analytic integration" + ) module_stock_request_submit = fields.Boolean( - string='Submitted state in Stock Requests') + string="Submitted state in Stock Requests" + ) # Dependencies - @api.onchange('stock_request_allow_virtual_loc') + @api.onchange("stock_request_allow_virtual_loc") def _onchange_stock_request_allow_virtual_loc(self): if self.stock_request_allow_virtual_loc: self.group_stock_multi_locations = True diff --git a/stock_request/models/stock_location.py b/stock_request/models/stock_location.py index 2981c03e3..ec05272a1 100644 --- a/stock_request/models/stock_location.py +++ b/stock_request/models/stock_location.py @@ -1,26 +1,45 @@ # Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, models, _ +from odoo import _, api, models from odoo.exceptions import ValidationError class StockLocation(models.Model): - _inherit = 'stock.location' + _inherit = "stock.location" - @api.constrains('company_id') + @api.constrains("company_id") def _check_company_stock_request(self): - if any(rec.company_id and self.env['stock.request'].search( - [('company_id', '!=', rec.company_id.id), - ('location_id', '=', rec.id)], limit=1) for rec in self): + if any( + rec.company_id + and self.env["stock.request"].search( + [("company_id", "!=", rec.company_id.id), ("location_id", "=", rec.id)], + limit=1, + ) + for rec in self + ): raise ValidationError( - _('You cannot change the company of the location, as it is ' - 'already assigned to stock requests that belong to ' - 'another company.')) - if any(rec.company_id and self.env['stock.request.order'].search( - [('company_id', '!=', rec.company_id.id), - ('warehouse_id', '=', rec.id)], limit=1) for rec in self): + _( + "You cannot change the company of the location, as it is " + "already assigned to stock requests that belong to " + "another company." + ) + ) + if any( + rec.company_id + and self.env["stock.request.order"].search( + [ + ("company_id", "!=", rec.company_id.id), + ("warehouse_id", "=", rec.id), + ], + limit=1, + ) + for rec in self + ): raise ValidationError( - _('You cannot change the company of the location, as it is ' - 'already assigned to stock request orders that belong to ' - 'another company.')) + _( + "You cannot change the company of the location, as it is " + "already assigned to stock request orders that belong to " + "another company." + ) + ) diff --git a/stock_request/models/stock_location_route.py b/stock_request/models/stock_location_route.py index b3506fc85..53bef4b6f 100644 --- a/stock_request/models/stock_location_route.py +++ b/stock_request/models/stock_location_route.py @@ -1,19 +1,27 @@ # Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, models, _ +from odoo import _, api, models from odoo.exceptions import ValidationError class StockLocationRoute(models.Model): - _inherit = 'stock.location.route' + _inherit = "stock.location.route" - @api.constrains('company_id') + @api.constrains("company_id") def _check_company_stock_request(self): - if any(rec.company_id and self.env['stock.request'].search( - [('company_id', '!=', rec.company_id.id), - ('route_id', '=', rec.id)], limit=1) for rec in self): + if any( + rec.company_id + and self.env["stock.request"].search( + [("company_id", "!=", rec.company_id.id), ("route_id", "=", rec.id)], + limit=1, + ) + for rec in self + ): raise ValidationError( - _('You cannot change the company of the route, as it is ' - 'already assigned to stock requests that belong to ' - 'another company.')) + _( + "You cannot change the company of the route, as it is " + "already assigned to stock requests that belong to " + "another company." + ) + ) diff --git a/stock_request/models/stock_move.py b/stock_request/models/stock_move.py index eec5e0312..a756e339e 100644 --- a/stock_request/models/stock_move.py +++ b/stock_request/models/stock_move.py @@ -1,39 +1,50 @@ # Copyright 2017 Eficent Business and IT Consulting Services, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, fields, models, _ +from odoo import _, api, fields, models from odoo.exceptions import ValidationError class StockMove(models.Model): - _inherit = 'stock.move' + _inherit = "stock.move" - allocation_ids = fields.One2many(comodel_name='stock.request.allocation', - inverse_name='stock_move_id', - string='Stock Request Allocation') + allocation_ids = fields.One2many( + comodel_name="stock.request.allocation", + inverse_name="stock_move_id", + string="Stock Request Allocation", + ) - stock_request_ids = fields.One2many(comodel_name='stock.request', - string='Stock Requests', - compute='_compute_stock_request_ids') + stock_request_ids = fields.One2many( + comodel_name="stock.request", + string="Stock Requests", + compute="_compute_stock_request_ids", + ) - @api.depends('allocation_ids') + @api.depends("allocation_ids") def _compute_stock_request_ids(self): for rec in self: - rec.stock_request_ids = rec.allocation_ids.mapped( - 'stock_request_id') + rec.stock_request_ids = rec.allocation_ids.mapped("stock_request_id") def _merge_moves_fields(self): res = super(StockMove, self)._merge_moves_fields() - res['allocation_ids'] = [(4, m.id) for m in - self.mapped('allocation_ids')] + res["allocation_ids"] = [(4, m.id) for m in self.mapped("allocation_ids")] return res - @api.constrains('company_id') + @api.constrains("company_id") def _check_company_stock_request(self): - if any(self.env['stock.request.allocation'].search( - [('company_id', '!=', rec.company_id.id), - ('stock_move_id', '=', rec.id)], limit=1) - for rec in self): + if any( + self.env["stock.request.allocation"].search( + [ + ("company_id", "!=", rec.company_id.id), + ("stock_move_id", "=", rec.id), + ], + limit=1, + ) + for rec in self + ): raise ValidationError( - _('The company of the stock request must match with ' - 'that of the location.')) + _( + "The company of the stock request must match with " + "that of the location." + ) + ) diff --git a/stock_request/models/stock_move_line.py b/stock_request/models/stock_move_line.py index 76a842084..1b90ac07f 100644 --- a/stock_request/models/stock_move_line.py +++ b/stock_request/models/stock_move_line.py @@ -9,39 +9,44 @@ class StockMoveLine(models.Model): @api.model def _stock_request_confirm_done_message_content(self, message_data): - title = _('Receipt confirmation %s for your Request %s') % ( - message_data['picking_name'], message_data['request_name']) - message = '

%s

' % title - message += _('The following requested items from Stock Request %s ' - 'have now been received in %s using Picking %s:') % ( - message_data['request_name'], message_data['location_name'], - message_data['picking_name']) - message += '' + "The following requested items from Stock Request %s " + "have now been received in %s using Picking %s:" + ) % ( + message_data["request_name"], + message_data["location_name"], + message_data["picking_name"], + ) + message += "" return message def _prepare_message_data(self, ml, request, allocated_qty): return { - 'request_name': request.name, - 'picking_name': ml.picking_id.name, - 'product_name': ml.product_id.name_get()[0][1], - 'product_qty': allocated_qty, - 'product_uom': ml.product_uom_id.name, - 'location_name': ml.location_dest_id.name_get()[0][1], + "request_name": request.name, + "picking_name": ml.picking_id.name, + "product_name": ml.product_id.name_get()[0][1], + "product_qty": allocated_qty, + "product_uom": ml.product_uom_id.name, + "location_name": ml.location_dest_id.name_get()[0][1], } def _action_done(self): res = super(StockMoveLine, self)._action_done() - for ml in self.filtered( - lambda m: m.exists() and m.move_id.allocation_ids): + for ml in self.filtered(lambda m: m.exists() and m.move_id.allocation_ids): qty_done = ml.product_uom_id._compute_quantity( - ml.qty_done, ml.product_id.uom_id) + ml.qty_done, ml.product_id.uom_id + ) # We do sudo because potentially the user that completes the move # may not have permissions for stock.request. @@ -49,16 +54,12 @@ class StockMoveLine(models.Model): for allocation in ml.move_id.allocation_ids.sudo(): allocated_qty = 0.0 if allocation.open_product_qty: - allocated_qty = min( - allocation.open_product_qty, qty_done) + allocated_qty = min(allocation.open_product_qty, qty_done) allocation.allocated_product_qty += allocated_qty to_allocate_qty -= allocated_qty request = allocation.stock_request_id - message_data = self._prepare_message_data(ml, request, - allocated_qty) - message = \ - self._stock_request_confirm_done_message_content( - message_data) - request.message_post(body=message, subtype='mail.mt_comment') + message_data = self._prepare_message_data(ml, request, allocated_qty) + message = self._stock_request_confirm_done_message_content(message_data) + request.message_post(body=message, subtype="mail.mt_comment") request.check_done() return res diff --git a/stock_request/models/stock_picking.py b/stock_request/models/stock_picking.py index 6f6e77b33..5e7aca501 100644 --- a/stock_request/models/stock_picking.py +++ b/stock_request/models/stock_picking.py @@ -5,33 +5,35 @@ from odoo import api, fields, models class StockPicking(models.Model): - _inherit = 'stock.picking' + _inherit = "stock.picking" - stock_request_ids = fields.One2many(comodel_name='stock.request', - string='Stock Requests', - compute='_compute_stock_request_ids') - stock_request_count = fields.Integer('Stock Request #', - compute='_compute_stock_request_ids') + stock_request_ids = fields.One2many( + comodel_name="stock.request", + string="Stock Requests", + compute="_compute_stock_request_ids", + ) + stock_request_count = fields.Integer( + "Stock Request #", compute="_compute_stock_request_ids" + ) - @api.depends('move_lines') + @api.depends("move_lines") def _compute_stock_request_ids(self): for rec in self: - rec.stock_request_ids = rec.move_lines.mapped('stock_request_ids') + rec.stock_request_ids = rec.move_lines.mapped("stock_request_ids") rec.stock_request_count = len(rec.stock_request_ids) def action_view_stock_request(self): """ :return dict: dictionary value for created view """ - action = self.env.ref( - 'stock_request.action_stock_request_form').read()[0] + action = self.env.ref("stock_request.action_stock_request_form").read()[0] - requests = self.mapped('stock_request_ids') + requests = self.mapped("stock_request_ids") if len(requests) > 1: - action['domain'] = [('id', 'in', requests.ids)] + action["domain"] = [("id", "in", requests.ids)] elif requests: - action['views'] = [ - (self.env.ref('stock_request.view_stock_request_form').id, - 'form')] - action['res_id'] = requests.id + action["views"] = [ + (self.env.ref("stock_request.view_stock_request_form").id, "form") + ] + action["res_id"] = requests.id return action diff --git a/stock_request/models/stock_request.py b/stock_request/models/stock_request.py index 73be05788..3e5b4acec 100644 --- a/stock_request/models/stock_request.py +++ b/stock_request/models/stock_request.py @@ -1,23 +1,25 @@ # Copyright 2017 Eficent Business and IT Consulting Services, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, fields, models, _ +from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError -from odoo.addons import decimal_precision as dp from odoo.tools import float_compare +from odoo.addons import decimal_precision as dp + REQUEST_STATES = [ - ('draft', 'Draft'), - ('open', 'In progress'), - ('done', 'Done'), - ('cancel', 'Cancelled')] + ("draft", "Draft"), + ("open", "In progress"), + ("done", "Done"), + ("cancel", "Cancelled"), +] class StockRequest(models.Model): _name = "stock.request" _description = "Stock Request" - _inherit = 'stock.request.abstract' - _order = 'id desc' + _inherit = "stock.request.abstract" + _order = "id desc" def __get_request_states(self): return REQUEST_STATES @@ -26,7 +28,7 @@ class StockRequest(models.Model): return self.__get_request_states() def _get_default_requested_by(self): - return self.env['res.users'].browse(self.env.uid) + return self.env["res.users"].browse(self.env.uid) @staticmethod def _get_expected_date(): @@ -39,178 +41,177 @@ class StockRequest(models.Model): res = self._get_expected_date() return res - name = fields.Char( - states={'draft': [('readonly', False)]} - ) + name = fields.Char(states={"draft": [("readonly", False)]}) state = fields.Selection( - selection=_get_request_states, string='Status', - copy=False, default='draft', index=True, - readonly=True, track_visibility='onchange', + selection=_get_request_states, + string="Status", + copy=False, + default="draft", + index=True, + readonly=True, + track_visibility="onchange", ) requested_by = fields.Many2one( - 'res.users', 'Requested by', required=True, - track_visibility='onchange', + "res.users", + "Requested by", + required=True, + track_visibility="onchange", default=lambda s: s._get_default_requested_by(), ) expected_date = fields.Datetime( - 'Expected Date', default=lambda s: s._get_default_expected_date(), - index=True, required=True, readonly=True, - states={'draft': [('readonly', False)]}, + "Expected Date", + default=lambda s: s._get_default_expected_date(), + index=True, + required=True, + readonly=True, + states={"draft": [("readonly", False)]}, help="Date when you expect to receive the goods.", ) - picking_policy = fields.Selection([ - ('direct', 'Receive each product when available'), - ('one', 'Receive all products at once')], - string='Shipping Policy', required=True, readonly=True, - states={'draft': [('readonly', False)]}, - default='direct', + picking_policy = fields.Selection( + [ + ("direct", "Receive each product when available"), + ("one", "Receive all products at once"), + ], + string="Shipping Policy", + required=True, + readonly=True, + states={"draft": [("readonly", False)]}, + default="direct", + ) + move_ids = fields.One2many( + comodel_name="stock.move", + compute="_compute_move_ids", + string="Stock Moves", + readonly=True, + ) + picking_ids = fields.One2many( + "stock.picking", + compute="_compute_picking_ids", + string="Pickings", + readonly=True, ) - move_ids = fields.One2many(comodel_name='stock.move', - compute='_compute_move_ids', - string='Stock Moves', readonly=True, - ) - picking_ids = fields.One2many('stock.picking', - compute='_compute_picking_ids', - string='Pickings', readonly=True, - ) qty_in_progress = fields.Float( - 'Qty In Progress', digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty', store=True, + "Qty In Progress", + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty", + store=True, help="Quantity in progress.", ) qty_done = fields.Float( - 'Qty Done', digits=dp.get_precision('Product Unit of Measure'), - readonly=True, compute='_compute_qty', store=True, + "Qty Done", + digits=dp.get_precision("Product Unit of Measure"), + readonly=True, + compute="_compute_qty", + store=True, help="Quantity completed", ) - picking_count = fields.Integer(string='Delivery Orders', - compute='_compute_picking_ids', - readonly=True, - ) - allocation_ids = fields.One2many(comodel_name='stock.request.allocation', - inverse_name='stock_request_id', - string='Stock Request Allocation') - order_id = fields.Many2one( - 'stock.request.order', - readonly=True, + picking_count = fields.Integer( + string="Delivery Orders", compute="_compute_picking_ids", readonly=True ) + allocation_ids = fields.One2many( + comodel_name="stock.request.allocation", + inverse_name="stock_request_id", + string="Stock Request Allocation", + ) + order_id = fields.Many2one("stock.request.order", readonly=True) warehouse_id = fields.Many2one( - states={'draft': [('readonly', False)]}, readonly=True + states={"draft": [("readonly", False)]}, readonly=True ) location_id = fields.Many2one( - states={'draft': [('readonly', False)]}, readonly=True - ) - product_id = fields.Many2one( - states={'draft': [('readonly', False)]}, readonly=True + states={"draft": [("readonly", False)]}, readonly=True ) + product_id = fields.Many2one(states={"draft": [("readonly", False)]}, readonly=True) product_uom_id = fields.Many2one( - states={'draft': [('readonly', False)]}, readonly=True + states={"draft": [("readonly", False)]}, readonly=True ) product_uom_qty = fields.Float( - states={'draft': [('readonly', False)]}, readonly=True + states={"draft": [("readonly", False)]}, readonly=True ) procurement_group_id = fields.Many2one( - states={'draft': [('readonly', False)]}, readonly=True - ) - company_id = fields.Many2one( - states={'draft': [('readonly', False)]}, readonly=True - ) - route_id = fields.Many2one( - states={'draft': [('readonly', False)]}, readonly=True + states={"draft": [("readonly", False)]}, readonly=True ) + company_id = fields.Many2one(states={"draft": [("readonly", False)]}, readonly=True) + route_id = fields.Many2one(states={"draft": [("readonly", False)]}, readonly=True) _sql_constraints = [ - ('name_uniq', 'unique(name, company_id)', - 'Stock Request name must be unique'), + ("name_uniq", "unique(name, company_id)", "Stock Request name must be unique") ] - @api.depends('allocation_ids') + @api.depends("allocation_ids") def _compute_move_ids(self): for request in self: - request.move_ids = request.allocation_ids.mapped('stock_move_id') + request.move_ids = request.allocation_ids.mapped("stock_move_id") - @api.depends('allocation_ids') + @api.depends("allocation_ids") def _compute_picking_ids(self): for request in self: request.picking_count = 0 - request.picking_ids = self.env['stock.picking'] + request.picking_ids = self.env["stock.picking"] request.picking_ids = request.move_ids.filtered( - lambda m: m.state != 'cancel').mapped('picking_id') + lambda m: m.state != "cancel" + ).mapped("picking_id") request.picking_count = len(request.picking_ids) - @api.depends('allocation_ids', 'allocation_ids.stock_move_id.state', - 'allocation_ids.stock_move_id.move_line_ids', - 'allocation_ids.stock_move_id.move_line_ids.qty_done') + @api.depends( + "allocation_ids", + "allocation_ids.stock_move_id.state", + "allocation_ids.stock_move_id.move_line_ids", + "allocation_ids.stock_move_id.move_line_ids.qty_done", + ) def _compute_qty(self): for request in self: - done_qty = sum(request.allocation_ids.mapped( - 'allocated_product_qty')) - open_qty = sum(request.allocation_ids.mapped('open_product_qty')) + done_qty = sum(request.allocation_ids.mapped("allocated_product_qty")) + open_qty = sum(request.allocation_ids.mapped("open_product_qty")) request.qty_done = request.product_id.uom_id._compute_quantity( - done_qty, request.product_uom_id) - request.qty_in_progress = \ - request.product_id.uom_id._compute_quantity( - open_qty, request.product_uom_id) + done_qty, request.product_uom_id + ) + request.qty_in_progress = request.product_id.uom_id._compute_quantity( + open_qty, request.product_uom_id + ) - @api.constrains('order_id', 'requested_by') + @api.constrains("order_id", "requested_by") def check_order_requested_by(self): if self.order_id and self.order_id.requested_by != self.requested_by: - raise ValidationError(_( - 'Requested by must be equal to the order' - )) + raise ValidationError(_("Requested by must be equal to the order")) - @api.constrains('order_id', 'warehouse_id') + @api.constrains("order_id", "warehouse_id") def check_order_warehouse_id(self): if self.order_id and self.order_id.warehouse_id != self.warehouse_id: - raise ValidationError(_( - 'Warehouse must be equal to the order' - )) + raise ValidationError(_("Warehouse must be equal to the order")) - @api.constrains('order_id', 'location_id') + @api.constrains("order_id", "location_id") def check_order_location(self): if self.order_id and self.order_id.location_id != self.location_id: - raise ValidationError(_( - 'Location must be equal to the order' - )) + raise ValidationError(_("Location must be equal to the order")) - @api.constrains('order_id', 'procurement_group_id') + @api.constrains("order_id", "procurement_group_id") def check_order_procurement_group(self): if ( - self.order_id and - self.order_id.procurement_group_id != self.procurement_group_id + self.order_id + and self.order_id.procurement_group_id != self.procurement_group_id ): - raise ValidationError(_( - 'Procurement group must be equal to the order' - )) + raise ValidationError(_("Procurement group must be equal to the order")) - @api.constrains('order_id', 'company_id') + @api.constrains("order_id", "company_id") def check_order_company(self): if self.order_id and self.order_id.company_id != self.company_id: - raise ValidationError(_( - 'Company must be equal to the order' - )) + raise ValidationError(_("Company must be equal to the order")) - @api.constrains('order_id', 'expected_date') + @api.constrains("order_id", "expected_date") def check_order_expected_date(self): if self.order_id and self.order_id.expected_date != self.expected_date: - raise ValidationError(_( - 'Expected date must be equal to the order' - )) + raise ValidationError(_("Expected date must be equal to the order")) - @api.constrains('order_id', 'picking_policy') + @api.constrains("order_id", "picking_policy") def check_order_picking_policy(self): - if ( - self.order_id and - self.order_id.picking_policy != self.picking_policy - ): - raise ValidationError(_( - 'The picking policy must be equal to the order' - )) + if self.order_id and self.order_id.picking_policy != self.picking_policy: + raise ValidationError(_("The picking policy must be equal to the order")) @api.multi def _action_confirm(self): self._action_launch_procurement_rule() - self.state = 'open' + self.state = "open" @api.multi def action_confirm(self): @@ -218,30 +219,35 @@ class StockRequest(models.Model): return True def action_draft(self): - self.write({'state': 'draft'}) + self.write({"state": "draft"}) return True def action_cancel(self): - self.sudo().mapped('move_ids')._action_cancel() - self.state = 'cancel' + self.sudo().mapped("move_ids")._action_cancel() + self.state = "cancel" return True def action_done(self): - self.state = 'done' + self.state = "done" if self.order_id: self.order_id.check_done() return True def check_done(self): - precision = self.env['decimal.precision'].precision_get( - 'Product Unit of Measure') + precision = self.env["decimal.precision"].precision_get( + "Product Unit of Measure" + ) for request in self: - allocated_qty = sum(request.allocation_ids.mapped( - 'allocated_product_qty')) + allocated_qty = sum(request.allocation_ids.mapped("allocated_product_qty")) qty_done = request.product_id.uom_id._compute_quantity( - allocated_qty, request.product_uom_id) - if float_compare(qty_done, request.product_uom_qty, - precision_digits=precision) >= 0: + allocated_qty, request.product_uom_id + ) + if ( + float_compare( + qty_done, request.product_uom_qty, precision_digits=precision + ) + >= 0 + ): request.action_done() return True @@ -254,17 +260,16 @@ class StockRequest(models.Model): move/po creation. """ return { - 'date_planned': self.expected_date, - 'warehouse_id': self.warehouse_id, - 'stock_request_allocation_ids': self.id, - 'group_id': group_id or self.procurement_group_id.id or False, - 'route_ids': self.route_id, - 'stock_request_id': self.id, + "date_planned": self.expected_date, + "warehouse_id": self.warehouse_id, + "stock_request_allocation_ids": self.id, + "group_id": group_id or self.procurement_group_id.id or False, + "route_ids": self.route_id, + "stock_request_id": self.id, } def _skip_procurement(self): - return self.state != 'draft' or \ - self.product_id.type not in ('consu', 'product') + return self.state != "draft" or self.product_id.type not in ("consu", "product") @api.multi def _action_launch_procurement_rule(self): @@ -275,61 +280,63 @@ class StockRequest(models.Model): '_run_buy' or '_run_manufacture' depending on the stock request product rule. """ - precision = self.env['decimal.precision'].precision_get( - 'Product Unit of Measure') + precision = self.env["decimal.precision"].precision_get( + "Product Unit of Measure" + ) errors = [] for request in self: if request._skip_procurement(): continue qty = 0.0 - for move in request.move_ids.filtered( - lambda r: r.state != 'cancel'): + for move in request.move_ids.filtered(lambda r: r.state != "cancel"): qty += move.product_qty - if float_compare(qty, request.product_qty, - precision_digits=precision) >= 0: + if float_compare(qty, request.product_qty, precision_digits=precision) >= 0: continue values = request._prepare_procurement_values( - group_id=request.procurement_group_id) + group_id=request.procurement_group_id + ) try: # We launch with sudo because potentially we could create # objects that the user is not authorized to create, such # as PO. - self.env['procurement.group'].sudo().run( - request.product_id, request.product_uom_qty, + self.env["procurement.group"].sudo().run( + request.product_id, + request.product_uom_qty, request.product_uom_id, - request.location_id, request.name, - request.name, values) + request.location_id, + request.name, + request.name, + values, + ) except UserError as error: errors.append(error.name) if errors: - raise UserError('\n'.join(errors)) + raise UserError("\n".join(errors)) return True @api.multi def action_view_transfer(self): - action = self.env.ref('stock.action_picking_tree_all').read()[0] + action = self.env.ref("stock.action_picking_tree_all").read()[0] - pickings = self.mapped('picking_ids') + pickings = self.mapped("picking_ids") if len(pickings) > 1: - action['domain'] = [('id', 'in', pickings.ids)] + action["domain"] = [("id", "in", pickings.ids)] elif pickings: - action['views'] = [ - (self.env.ref('stock.view_picking_form').id, 'form')] - action['res_id'] = pickings.id + action["views"] = [(self.env.ref("stock.view_picking_form").id, "form")] + action["res_id"] = pickings.id return action @api.model def create(self, vals): upd_vals = vals.copy() - if upd_vals.get('name', '/') == '/': - upd_vals['name'] = self.env['ir.sequence'].next_by_code( - 'stock.request') + if upd_vals.get("name", "/") == "/": + upd_vals["name"] = self.env["ir.sequence"].next_by_code("stock.request") return super().create(upd_vals) @api.multi def unlink(self): - if self.filtered(lambda r: r.state != 'draft'): - raise UserError(_('Only requests on draft state can be unlinked')) + if self.filtered(lambda r: r.state != "draft"): + raise UserError(_("Only requests on draft state can be unlinked")) return super(StockRequest, self).unlink() diff --git a/stock_request/models/stock_request_abstract.py b/stock_request/models/stock_request_abstract.py index b4568d470..89883c57f 100644 --- a/stock_request/models/stock_request_abstract.py +++ b/stock_request/models/stock_request_abstract.py @@ -1,118 +1,133 @@ # Copyright 2017 Eficent Business and IT Consulting Services, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, fields, models, _ +from odoo import _, api, fields, models from odoo.exceptions import ValidationError + from odoo.addons import decimal_precision as dp class StockRequest(models.AbstractModel): _name = "stock.request.abstract" _description = "Stock Request Template" - _inherit = ['mail.thread', 'mail.activity.mixin'] + _inherit = ["mail.thread", "mail.activity.mixin"] @api.model def default_get(self, fields): res = super(StockRequest, self).default_get(fields) warehouse = None - if 'warehouse_id' not in res and res.get('company_id'): - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', res['company_id'])], limit=1) + if "warehouse_id" not in res and res.get("company_id"): + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", res["company_id"])], limit=1 + ) if warehouse: - res['warehouse_id'] = warehouse.id - res['location_id'] = warehouse.lot_stock_id.id + res["warehouse_id"] = warehouse.id + res["location_id"] = warehouse.lot_stock_id.id return res - @api.depends('product_id', 'product_uom_id', 'product_uom_qty', - 'product_id.product_tmpl_id.uom_id') + @api.depends( + "product_id", + "product_uom_id", + "product_uom_qty", + "product_id.product_tmpl_id.uom_id", + ) def _compute_product_qty(self): for rec in self: rec.product_qty = rec.product_uom_id._compute_quantity( - rec.product_uom_qty, rec.product_id.product_tmpl_id.uom_id) + rec.product_uom_qty, rec.product_id.product_tmpl_id.uom_id + ) - name = fields.Char( - 'Name', copy=False, required=True, readonly=True, - default='/') + name = fields.Char("Name", copy=False, required=True, readonly=True, default="/") warehouse_id = fields.Many2one( - 'stock.warehouse', 'Warehouse', - ondelete="cascade", required=True, + "stock.warehouse", "Warehouse", ondelete="cascade", required=True ) location_id = fields.Many2one( - 'stock.location', 'Location', - domain=[('usage', 'in', ['internal', 'transit'])], - ondelete="cascade", required=True, + "stock.location", + "Location", + domain=[("usage", "in", ["internal", "transit"])], + ondelete="cascade", + required=True, ) product_id = fields.Many2one( - 'product.product', 'Product', - domain=[('type', 'in', ['product', 'consu'])], ondelete='cascade', + "product.product", + "Product", + domain=[("type", "in", ["product", "consu"])], + ondelete="cascade", required=True, ) allow_virtual_location = fields.Boolean( - related='company_id.stock_request_allow_virtual_loc', - readonly=True, + related="company_id.stock_request_allow_virtual_loc", readonly=True ) product_uom_id = fields.Many2one( - 'uom.uom', 'Product Unit of Measure', + "uom.uom", + "Product Unit of Measure", required=True, - default=lambda self: self._context.get('product_uom_id', False), + default=lambda self: self._context.get("product_uom_id", False), ) product_uom_qty = fields.Float( - 'Quantity', digits=dp.get_precision('Product Unit of Measure'), + "Quantity", + digits=dp.get_precision("Product Unit of Measure"), required=True, - help="Quantity, specified in the unit of measure indicated in the " - "request.", + help="Quantity, specified in the unit of measure indicated in the " "request.", ) product_qty = fields.Float( - 'Real Quantity', compute='_compute_product_qty', - store=True, copy=False, - digits=dp.get_precision('Product Unit of Measure'), - help='Quantity in the default UoM of the product', + "Real Quantity", + compute="_compute_product_qty", + store=True, + copy=False, + digits=dp.get_precision("Product Unit of Measure"), + help="Quantity in the default UoM of the product", ) procurement_group_id = fields.Many2one( - 'procurement.group', 'Procurement Group', + "procurement.group", + "Procurement Group", help="Moves created through this stock request will be put in this " - "procurement group. If none is given, the moves generated by " - "procurement rules will be grouped into one big picking.", + "procurement group. If none is given, the moves generated by " + "procurement rules will be grouped into one big picking.", ) company_id = fields.Many2one( - 'res.company', 'Company', required=True, - default=lambda self: self.env['res.company']._company_default_get( - 'stock.request'), + "res.company", + "Company", + required=True, + default=lambda self: self.env["res.company"]._company_default_get( + "stock.request" + ), + ) + route_id = fields.Many2one( + "stock.location.route", + string="Route", + domain="[('id', 'in', route_ids)]", + ondelete="restrict", ) - route_id = fields.Many2one('stock.location.route', string='Route', - domain="[('id', 'in', route_ids)]", - ondelete='restrict') route_ids = fields.Many2many( - 'stock.location.route', string='Routes', - compute='_compute_route_ids', + "stock.location.route", + string="Routes", + compute="_compute_route_ids", readonly=True, ) _sql_constraints = [ - ('name_uniq', 'unique(name, company_id)', - 'Name must be unique'), + ("name_uniq", "unique(name, company_id)", "Name must be unique") ] - @api.depends('product_id', 'warehouse_id', 'location_id') + @api.depends("product_id", "warehouse_id", "location_id") def _compute_route_ids(self): - route_obj = self.env['stock.location.route'] - for wh in self.mapped('warehouse_id'): - wh_routes = route_obj.search( - [('warehouse_ids', '=', wh.id)]) + route_obj = self.env["stock.location.route"] + for wh in self.mapped("warehouse_id"): + wh_routes = route_obj.search([("warehouse_ids", "=", wh.id)]) for record in self.filtered(lambda r: r.warehouse_id == wh): routes = route_obj if record.product_id: routes += record.product_id.mapped( - 'route_ids' - ) | record.product_id.mapped( - 'categ_id' - ).mapped('total_route_ids') + "route_ids" + ) | record.product_id.mapped("categ_id").mapped("total_route_ids") if record.warehouse_id: routes |= wh_routes parents = record.get_parents().ids - record.route_ids = routes.filtered(lambda r: any( - p.location_id.id in parents for p in r.rule_ids)) + record.route_ids = routes.filtered( + lambda r: any(p.location_id.id in parents for p in r.rule_ids) + ) def get_parents(self): location = self.location_id @@ -122,54 +137,80 @@ class StockRequest(models.AbstractModel): result |= location return result - @api.constrains('company_id', 'product_id', 'warehouse_id', - 'location_id', 'route_id') + @api.constrains( + "company_id", "product_id", "warehouse_id", "location_id", "route_id" + ) def _check_company_constrains(self): """ Check if the related models have the same company """ for rec in self: - if rec.product_id.company_id and \ - rec.product_id.company_id != rec.company_id: + if ( + rec.product_id.company_id + and rec.product_id.company_id != rec.company_id + ): raise ValidationError( - _('You have entered a product that is assigned ' - 'to another company.')) - if rec.location_id.company_id and \ - rec.location_id.company_id != rec.company_id: + _( + "You have entered a product that is assigned " + "to another company." + ) + ) + if ( + rec.location_id.company_id + and rec.location_id.company_id != rec.company_id + ): raise ValidationError( - _('You have entered a location that is ' - 'assigned to another company.')) + _( + "You have entered a location that is " + "assigned to another company." + ) + ) if rec.warehouse_id.company_id != rec.company_id: raise ValidationError( - _('You have entered a warehouse that is ' - 'assigned to another company.')) - if rec.route_id and rec.route_id.company_id and \ - rec.route_id.company_id != rec.company_id: + _( + "You have entered a warehouse that is " + "assigned to another company." + ) + ) + if ( + rec.route_id + and rec.route_id.company_id + and rec.route_id.company_id != rec.company_id + ): raise ValidationError( - _('You have entered a route that is ' - 'assigned to another company.')) + _( + "You have entered a route that is " + "assigned to another company." + ) + ) - @api.constrains('product_id') + @api.constrains("product_id") def _check_product_uom(self): - ''' Check if the UoM has the same category as the - product standard UoM ''' - if any(request.product_id.uom_id.category_id != - request.product_uom_id.category_id for request in self): + """ Check if the UoM has the same category as the + product standard UoM """ + if any( + request.product_id.uom_id.category_id != request.product_uom_id.category_id + for request in self + ): raise ValidationError( - _('You have to select a product unit of measure in the ' - 'same category than the default unit ' - 'of measure of the product')) + _( + "You have to select a product unit of measure in the " + "same category than the default unit " + "of measure of the product" + ) + ) - @api.constrains('product_qty') + @api.constrains("product_qty") def _check_qty(self): for rec in self: if rec.product_qty <= 0: - raise ValueError(_('Stock Request product quantity has to be' - ' strictly positive.')) + raise ValueError( + _("Stock Request product quantity has to be" " strictly positive.") + ) - @api.onchange('warehouse_id') + @api.onchange("warehouse_id") def onchange_warehouse_id(self): """ Finds location id for changed warehouse. """ - res = {'domain': {}} - if self._name == 'stock.request' and self.order_id: + res = {"domain": {}} + if self._name == "stock.request" and self.order_id: # When the stock request is created from an order the wh and # location are taken from the order and we rely on it to change # all request associated. Thus, no need to apply @@ -183,42 +224,41 @@ class StockRequest(models.AbstractModel): self.company_id = self.warehouse_id.company_id return res - @api.onchange('location_id') + @api.onchange("location_id") def onchange_location_id(self): if self.location_id: loc_wh = self.location_id.sudo().get_warehouse() if loc_wh and self.warehouse_id != loc_wh: self.warehouse_id = loc_wh - self.with_context( - no_change_childs=True).onchange_warehouse_id() + self.with_context(no_change_childs=True).onchange_warehouse_id() - @api.onchange('allow_virtual_location') + @api.onchange("allow_virtual_location") def onchange_allow_virtual_location(self): if self.allow_virtual_location: - return {'domain': {'location_id': []}} + return {"domain": {"location_id": []}} - @api.onchange('company_id') + @api.onchange("company_id") def onchange_company_id(self): """ Sets a default warehouse when the company is changed and limits the user selection of warehouses. """ if self.company_id and ( - not self.warehouse_id or - self.warehouse_id.company_id != self.company_id): - self.warehouse_id = self.env['stock.warehouse'].search( - [('company_id', '=', self.company_id.id)], limit=1) + not self.warehouse_id or self.warehouse_id.company_id != self.company_id + ): + self.warehouse_id = self.env["stock.warehouse"].search( + [("company_id", "=", self.company_id.id)], limit=1 + ) self.onchange_warehouse_id() - return { - 'domain': { - 'warehouse_id': [('company_id', '=', self.company_id.id)]}} + return {"domain": {"warehouse_id": [("company_id", "=", self.company_id.id)]}} - @api.onchange('product_id') + @api.onchange("product_id") def onchange_product_id(self): - res = {'domain': {}} + res = {"domain": {}} if self.product_id: self.product_uom_id = self.product_id.uom_id.id - res['domain']['product_uom_id'] = [ - ('category_id', '=', self.product_id.uom_id.category_id.id)] + res["domain"]["product_uom_id"] = [ + ("category_id", "=", self.product_id.uom_id.category_id.id) + ] return res - res['domain']['product_uom_id'] = [] + res["domain"]["product_uom_id"] = [] return res diff --git a/stock_request/models/stock_request_allocation.py b/stock_request/models/stock_request_allocation.py index 99b05fb7f..3d75e1657 100644 --- a/stock_request/models/stock_request_allocation.py +++ b/stock_request/models/stock_request_allocation.py @@ -5,67 +5,84 @@ from odoo import api, fields, models class StockRequestAllocation(models.Model): - _name = 'stock.request.allocation' - _description = 'Stock Request Allocation' + _name = "stock.request.allocation" + _description = "Stock Request Allocation" - stock_request_id = fields.Many2one(string='Stock Request', - comodel_name='stock.request', - required=True, ondelete='cascade', - ) - company_id = fields.Many2one(string='Company', - comodel_name='res.company', - readonly=True, - related='stock_request_id.company_id', - store=True, - ) - stock_move_id = fields.Many2one(string='Stock Move', - comodel_name='stock.move', - required=True, ondelete='cascade', - ) - product_id = fields.Many2one(string='Product', - comodel_name='product.product', - related='stock_request_id.product_id', - readonly=True, - ) - product_uom_id = fields.Many2one(string='UoM', comodel_name='uom.uom', - related='stock_request_id.product_uom_id', - readonly=True, - ) + stock_request_id = fields.Many2one( + string="Stock Request", + comodel_name="stock.request", + required=True, + ondelete="cascade", + ) + company_id = fields.Many2one( + string="Company", + comodel_name="res.company", + readonly=True, + related="stock_request_id.company_id", + store=True, + ) + stock_move_id = fields.Many2one( + string="Stock Move", + comodel_name="stock.move", + required=True, + ondelete="cascade", + ) + product_id = fields.Many2one( + string="Product", + comodel_name="product.product", + related="stock_request_id.product_id", + readonly=True, + ) + product_uom_id = fields.Many2one( + string="UoM", + comodel_name="uom.uom", + related="stock_request_id.product_uom_id", + readonly=True, + ) requested_product_uom_qty = fields.Float( - 'Requested Quantity (UoM)', - help='Quantity of the stock request allocated to the stock move, ' - 'in the UoM of the Stock Request', + "Requested Quantity (UoM)", + help="Quantity of the stock request allocated to the stock move, " + "in the UoM of the Stock Request", ) requested_product_qty = fields.Float( - 'Requested Quantity', - help='Quantity of the stock request allocated to the stock move, ' - 'in the default UoM of the product', - compute='_compute_requested_product_qty' + "Requested Quantity", + help="Quantity of the stock request allocated to the stock move, " + "in the default UoM of the product", + compute="_compute_requested_product_qty", ) allocated_product_qty = fields.Float( - 'Allocated Quantity', - help='Quantity of the stock request allocated to the stock move, ' - 'in the default UoM of the product', + "Allocated Quantity", + help="Quantity of the stock request allocated to the stock move, " + "in the default UoM of the product", + ) + open_product_qty = fields.Float( + "Open Quantity", compute="_compute_open_product_qty" ) - open_product_qty = fields.Float('Open Quantity', - compute='_compute_open_product_qty') - @api.depends('stock_request_id.product_id', - 'stock_request_id.product_uom_id', - 'requested_product_uom_qty') + @api.depends( + "stock_request_id.product_id", + "stock_request_id.product_uom_id", + "requested_product_uom_qty", + ) def _compute_requested_product_qty(self): for rec in self: rec.requested_product_qty = rec.product_uom_id._compute_quantity( - rec.requested_product_uom_qty, rec.product_id.uom_id) + rec.requested_product_uom_qty, rec.product_id.uom_id + ) - @api.depends('requested_product_qty', 'allocated_product_qty', - 'stock_move_id', 'stock_move_id.state') + @api.depends( + "requested_product_qty", + "allocated_product_qty", + "stock_move_id", + "stock_move_id.state", + ) def _compute_open_product_qty(self): for rec in self: - if rec.stock_move_id.state == 'cancel': + if rec.stock_move_id.state == "cancel": rec.open_product_qty = 0.0 else: - rec.open_product_qty = \ + rec.open_product_qty = ( rec.requested_product_qty - rec.allocated_product_qty + ) if rec.open_product_qty < 0.0: rec.open_product_qty = 0.0 diff --git a/stock_request/models/stock_request_order.py b/stock_request/models/stock_request_order.py index 392617a1b..b38ba4119 100644 --- a/stock_request/models/stock_request_order.py +++ b/stock_request/models/stock_request_order.py @@ -1,163 +1,190 @@ # Copyright 2018 Creu Blanca # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, fields, models, _ -from odoo.exceptions import UserError, ValidationError, AccessError +from odoo import _, api, fields, models +from odoo.exceptions import AccessError, UserError, ValidationError class StockRequestOrder(models.Model): - _name = 'stock.request.order' - _description = 'Stock Request Order' - _inherit = ['mail.thread', 'mail.activity.mixin'] - _order = 'id desc' + _name = "stock.request.order" + _description = "Stock Request Order" + _inherit = ["mail.thread", "mail.activity.mixin"] + _order = "id desc" @api.model def default_get(self, fields): res = super().default_get(fields) warehouse = None - if 'warehouse_id' not in res and res.get('company_id'): - warehouse = self.env['stock.warehouse'].search( - [('company_id', '=', res['company_id'])], limit=1) + if "warehouse_id" not in res and res.get("company_id"): + warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", res["company_id"])], limit=1 + ) if warehouse: - res['warehouse_id'] = warehouse.id - res['location_id'] = warehouse.lot_stock_id.id + res["warehouse_id"] = warehouse.id + res["location_id"] = warehouse.lot_stock_id.id return res def __get_request_order_states(self): - return self.env['stock.request']._get_request_states() + return self.env["stock.request"]._get_request_states() def _get_request_order_states(self): return self.__get_request_order_states() def _get_default_requested_by(self): - return self.env['res.users'].browse(self.env.uid) + return self.env["res.users"].browse(self.env.uid) name = fields.Char( - 'Name', copy=False, required=True, readonly=True, - states={'draft': [('readonly', False)]}, - default='/') + "Name", + copy=False, + required=True, + readonly=True, + states={"draft": [("readonly", False)]}, + default="/", + ) state = fields.Selection( selection=_get_request_order_states, - string='Status', copy=False, default='draft', index=True, - readonly=True, track_visibility='onchange', + string="Status", + copy=False, + default="draft", + index=True, + readonly=True, + track_visibility="onchange", ) requested_by = fields.Many2one( - 'res.users', 'Requested by', required=True, - track_visibility='onchange', + "res.users", + "Requested by", + required=True, + track_visibility="onchange", default=lambda s: s._get_default_requested_by(), ) warehouse_id = fields.Many2one( - 'stock.warehouse', 'Warehouse', readonly=True, - ondelete="cascade", required=True, - states={'draft': [('readonly', False)]}) + "stock.warehouse", + "Warehouse", + readonly=True, + ondelete="cascade", + required=True, + states={"draft": [("readonly", False)]}, + ) location_id = fields.Many2one( - 'stock.location', 'Location', readonly=True, - domain=[('usage', 'in', ['internal', 'transit'])], - ondelete="cascade", required=True, - states={'draft': [('readonly', False)]}, + "stock.location", + "Location", + readonly=True, + domain=[("usage", "in", ["internal", "transit"])], + ondelete="cascade", + required=True, + states={"draft": [("readonly", False)]}, ) allow_virtual_location = fields.Boolean( - related='company_id.stock_request_allow_virtual_loc', - readonly=True, + related="company_id.stock_request_allow_virtual_loc", readonly=True ) procurement_group_id = fields.Many2one( - 'procurement.group', 'Procurement Group', readonly=True, - states={'draft': [('readonly', False)]}, + "procurement.group", + "Procurement Group", + readonly=True, + states={"draft": [("readonly", False)]}, help="Moves created through this stock request will be put in this " - "procurement group. If none is given, the moves generated by " - "procurement rules will be grouped into one big picking.", + "procurement group. If none is given, the moves generated by " + "procurement rules will be grouped into one big picking.", ) company_id = fields.Many2one( - 'res.company', 'Company', required=True, readonly=True, - states={'draft': [('readonly', False)]}, - default=lambda self: self.env['res.company']._company_default_get( - 'stock.request.order'), + "res.company", + "Company", + required=True, + readonly=True, + states={"draft": [("readonly", False)]}, + default=lambda self: self.env["res.company"]._company_default_get( + "stock.request.order" + ), ) expected_date = fields.Datetime( - 'Expected Date', default=fields.Datetime.now, index=True, - required=True, readonly=True, - states={'draft': [('readonly', False)]}, + "Expected Date", + default=fields.Datetime.now, + index=True, + required=True, + readonly=True, + states={"draft": [("readonly", False)]}, help="Date when you expect to receive the goods.", ) - picking_policy = fields.Selection([ - ('direct', 'Receive each product when available'), - ('one', 'Receive all products at once')], - string='Shipping Policy', required=True, readonly=True, - states={'draft': [('readonly', False)]}, - default='direct', + picking_policy = fields.Selection( + [ + ("direct", "Receive each product when available"), + ("one", "Receive all products at once"), + ], + string="Shipping Policy", + required=True, + readonly=True, + states={"draft": [("readonly", False)]}, + default="direct", + ) + move_ids = fields.One2many( + comodel_name="stock.move", + compute="_compute_move_ids", + string="Stock Moves", + readonly=True, + ) + picking_ids = fields.One2many( + "stock.picking", + compute="_compute_picking_ids", + string="Pickings", + readonly=True, + ) + picking_count = fields.Integer( + string="Delivery Orders", compute="_compute_picking_ids", readonly=True ) - move_ids = fields.One2many(comodel_name='stock.move', - compute='_compute_move_ids', - string='Stock Moves', readonly=True, - ) - picking_ids = fields.One2many('stock.picking', - compute='_compute_picking_ids', - string='Pickings', readonly=True, - ) - picking_count = fields.Integer(string='Delivery Orders', - compute='_compute_picking_ids', - readonly=True, - ) stock_request_ids = fields.One2many( - 'stock.request', - inverse_name='order_id', - copy=True, + "stock.request", inverse_name="order_id", copy=True ) stock_request_count = fields.Integer( - string='Stock requests', - compute='_compute_stock_request_count', - readonly=True, + string="Stock requests", compute="_compute_stock_request_count", readonly=True ) _sql_constraints = [ - ('name_uniq', 'unique(name, company_id)', - 'Stock Request name must be unique'), + ("name_uniq", "unique(name, company_id)", "Stock Request name must be unique") ] - @api.depends('stock_request_ids.allocation_ids') + @api.depends("stock_request_ids.allocation_ids") def _compute_picking_ids(self): for record in self: - record.picking_ids = record.stock_request_ids.mapped('picking_ids') + record.picking_ids = record.stock_request_ids.mapped("picking_ids") record.picking_count = len(record.picking_ids) - @api.depends('stock_request_ids') + @api.depends("stock_request_ids") def _compute_move_ids(self): for record in self: - record.move_ids = record.stock_request_ids.mapped('move_ids') + record.move_ids = record.stock_request_ids.mapped("move_ids") - @api.depends('stock_request_ids') + @api.depends("stock_request_ids") def _compute_stock_request_count(self): for record in self: record.stock_request_count = len(record.stock_request_ids) - @api.onchange('requested_by') + @api.onchange("requested_by") def onchange_requested_by(self): self.change_childs() - @api.onchange('expected_date') + @api.onchange("expected_date") def onchange_expected_date(self): self.change_childs() - @api.onchange('picking_policy') + @api.onchange("picking_policy") def onchange_picking_policy(self): self.change_childs() - @api.onchange('location_id') + @api.onchange("location_id") def onchange_location_id(self): if self.location_id: loc_wh = self.location_id.sudo().get_warehouse() if loc_wh and self.warehouse_id != loc_wh: self.warehouse_id = loc_wh - self.with_context( - no_change_childs=True).onchange_warehouse_id() + self.with_context(no_change_childs=True).onchange_warehouse_id() self.change_childs() - @api.onchange('allow_virtual_location') + @api.onchange("allow_virtual_location") def onchange_allow_virtual_location(self): if self.allow_virtual_location: - return {'domain': {'location_id': []}} + return {"domain": {"location_id": []}} - @api.onchange('warehouse_id') + @api.onchange("warehouse_id") def onchange_warehouse_id(self): if self.warehouse_id: # search with sudo because the user may not have permissions @@ -170,26 +197,25 @@ class StockRequestOrder(models.Model): self.with_context(no_change_childs=True).onchange_company_id() self.change_childs() - @api.onchange('procurement_group_id') + @api.onchange("procurement_group_id") def onchange_procurement_group_id(self): self.change_childs() - @api.onchange('company_id') + @api.onchange("company_id") def onchange_company_id(self): if self.company_id and ( - not self.warehouse_id or - self.warehouse_id.sudo().company_id != self.company_id + not self.warehouse_id + or self.warehouse_id.sudo().company_id != self.company_id ): - self.warehouse_id = self.env['stock.warehouse'].search( - [('company_id', '=', self.company_id.id)], limit=1) + self.warehouse_id = self.env["stock.warehouse"].search( + [("company_id", "=", self.company_id.id)], limit=1 + ) self.with_context(no_change_childs=True).onchange_warehouse_id() self.change_childs() - return { - 'domain': { - 'warehouse_id': [('company_id', '=', self.company_id.id)]}} + return {"domain": {"warehouse_id": [("company_id", "=", self.company_id.id)]}} def change_childs(self): - if not self._context.get('no_change_childs', False): + if not self._context.get("no_change_childs", False): for line in self.stock_request_ids: line.warehouse_id = self.warehouse_id line.location_id = self.location_id @@ -203,121 +229,142 @@ class StockRequestOrder(models.Model): def action_confirm(self): for line in self.stock_request_ids: line.action_confirm() - self.state = 'open' + self.state = "open" return True def action_draft(self): for line in self.stock_request_ids: line.action_draft() - self.state = 'draft' + self.state = "draft" return True def action_cancel(self): for line in self.stock_request_ids: line.action_cancel() - self.state = 'cancel' + self.state = "cancel" return True def action_done(self): - self.state = 'done' + self.state = "done" return True def check_done(self): - if not self.stock_request_ids.filtered(lambda r: r.state != 'done'): + if not self.stock_request_ids.filtered(lambda r: r.state != "done"): self.action_done() return @api.multi def action_view_transfer(self): - action = self.env.ref('stock.action_picking_tree_all').read()[0] + action = self.env.ref("stock.action_picking_tree_all").read()[0] - pickings = self.mapped('picking_ids') + pickings = self.mapped("picking_ids") if len(pickings) > 1: - action['domain'] = [('id', 'in', pickings.ids)] + action["domain"] = [("id", "in", pickings.ids)] elif pickings: - action['views'] = [ - (self.env.ref('stock.view_picking_form').id, 'form')] - action['res_id'] = pickings.id + action["views"] = [(self.env.ref("stock.view_picking_form").id, "form")] + action["res_id"] = pickings.id return action @api.multi def action_view_stock_requests(self): - action = self.env.ref( - 'stock_request.action_stock_request_form').read()[0] + action = self.env.ref("stock_request.action_stock_request_form").read()[0] if len(self.stock_request_ids) > 1: - action['domain'] = [('order_id', 'in', self.ids)] + action["domain"] = [("order_id", "in", self.ids)] elif self.stock_request_ids: - action['views'] = [ - (self.env.ref( - 'stock_request.view_stock_request_form').id, 'form')] - action['res_id'] = self.stock_request_ids.id + action["views"] = [ + (self.env.ref("stock_request.view_stock_request_form").id, "form") + ] + action["res_id"] = self.stock_request_ids.id return action @api.model def create(self, vals): upd_vals = vals.copy() - if upd_vals.get('name', '/') == '/': - upd_vals['name'] = self.env['ir.sequence'].next_by_code( - 'stock.request.order') + if upd_vals.get("name", "/") == "/": + upd_vals["name"] = self.env["ir.sequence"].next_by_code( + "stock.request.order" + ) return super().create(upd_vals) @api.multi def unlink(self): - if self.filtered(lambda r: r.state != 'draft'): - raise UserError(_('Only orders on draft state can be unlinked')) + if self.filtered(lambda r: r.state != "draft"): + raise UserError(_("Only orders on draft state can be unlinked")) return super().unlink() - @api.constrains('warehouse_id', 'company_id') + @api.constrains("warehouse_id", "company_id") def _check_warehouse_company(self): - if any(request.warehouse_id.company_id != - request.company_id for request in self): + if any( + request.warehouse_id.company_id != request.company_id for request in self + ): raise ValidationError( - _('The company of the stock request must match with ' - 'that of the warehouse.')) + _( + "The company of the stock request must match with " + "that of the warehouse." + ) + ) - @api.constrains('location_id', 'company_id') + @api.constrains("location_id", "company_id") def _check_location_company(self): - if any(request.location_id.company_id and - request.location_id.company_id != - request.company_id for request in self): + if any( + request.location_id.company_id + and request.location_id.company_id != request.company_id + for request in self + ): raise ValidationError( - _('The company of the stock request must match with ' - 'that of the location.')) + _( + "The company of the stock request must match with " + "that of the location." + ) + ) @api.model def _create_from_product_multiselect(self, products): if not products: return False - if products._name not in ('product.product', 'product.template'): + if products._name not in ("product.product", "product.template"): raise ValidationError( - _("This action only works in the context of products")) - if products._name == 'product.template': + _("This action only works in the context of products") + ) + if products._name == "product.template": # search instead of mapped so we don't include archived variants - products = self.env['product.product'].search([ - ('product_tmpl_id', 'in', products.ids) - ]) - expected = self.default_get(['expected_date'])['expected_date'] + products = self.env["product.product"].search( + [("product_tmpl_id", "in", products.ids)] + ) + expected = self.default_get(["expected_date"])["expected_date"] try: - order = self.env['stock.request.order'].create(dict( - expected_date=expected, - stock_request_ids=[(0, 0, dict( - product_id=product.id, - product_uom_id=product.uom_id.id, - product_uom_qty=1.0, + order = self.env["stock.request.order"].create( + dict( expected_date=expected, - )) for product in products] - )) + stock_request_ids=[ + ( + 0, + 0, + dict( + product_id=product.id, + product_uom_id=product.uom_id.id, + product_uom_qty=1.0, + expected_date=expected, + ), + ) + for product in products + ], + ) + ) except AccessError: # TODO: if there is a nice way to hide the action from the # Action-menu if the user doesn't have the necessary rights, # that would be a better way of doing this - raise UserError(_( - "Unfortunately it seems you do not have the necessary rights " - "for creating stock requests. Please contact your " - "administrator.")) - action = self.env.ref('stock_request.stock_request_order_action' - ).read()[0] - action['views'] = [( - self.env.ref('stock_request.stock_request_order_form').id, 'form')] - action['res_id'] = order.id + raise UserError( + _( + "Unfortunately it seems you do not have the necessary rights " + "for creating stock requests. Please contact your " + "administrator." + ) + ) + action = self.env.ref("stock_request.stock_request_order_action").read()[0] + action["views"] = [ + (self.env.ref("stock_request.stock_request_order_form").id, "form") + ] + action["res_id"] = order.id return action diff --git a/stock_request/models/stock_rule.py b/stock_request/models/stock_rule.py index d0c6df162..9368a4096 100644 --- a/stock_request/models/stock_rule.py +++ b/stock_request/models/stock_rule.py @@ -5,16 +5,38 @@ from odoo import models class StockRule(models.Model): - _inherit = 'stock.rule' + _inherit = "stock.rule" - def _get_stock_move_values(self, product_id, product_qty, product_uom, - location_id, name, origin, values, group_id): + def _get_stock_move_values( + self, + product_id, + product_qty, + product_uom, + location_id, + name, + origin, + values, + group_id, + ): result = super(StockRule, self)._get_stock_move_values( - product_id, product_qty, product_uom, - location_id, name, origin, values, group_id) - if values.get('stock_request_id', False): - result['allocation_ids'] = [(0, 0, { - 'stock_request_id': values.get('stock_request_id'), - 'requested_product_uom_qty': product_qty, - })] + product_id, + product_qty, + product_uom, + location_id, + name, + origin, + values, + group_id, + ) + if values.get("stock_request_id", False): + result["allocation_ids"] = [ + ( + 0, + 0, + { + "stock_request_id": values.get("stock_request_id"), + "requested_product_uom_qty": product_qty, + }, + ) + ] return result diff --git a/stock_request/models/stock_warehouse.py b/stock_request/models/stock_warehouse.py index d55a73d18..3951180f8 100644 --- a/stock_request/models/stock_warehouse.py +++ b/stock_request/models/stock_warehouse.py @@ -1,28 +1,46 @@ # Copyright 2018 Eficent Business and IT Consulting Services, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, models, _ +from odoo import _, api, models from odoo.exceptions import ValidationError class StockWarehouse(models.Model): - _inherit = 'stock.warehouse' + _inherit = "stock.warehouse" - @api.constrains('company_id') + @api.constrains("company_id") def _check_company_stock_request(self): - if any(self.env['stock.request'].search( - [('company_id', '!=', rec.company_id.id), - ('warehouse_id', '=', rec.id)], limit=1) - for rec in self): + if any( + self.env["stock.request"].search( + [ + ("company_id", "!=", rec.company_id.id), + ("warehouse_id", "=", rec.id), + ], + limit=1, + ) + for rec in self + ): raise ValidationError( - _('You cannot change the company of the warehouse, as it is ' - 'already assigned to stock requests that belong to ' - 'another company.')) - if any(self.env['stock.request.order'].search( - [('company_id', '!=', rec.company_id.id), - ('warehouse_id', '=', rec.id)], limit=1) - for rec in self): + _( + "You cannot change the company of the warehouse, as it is " + "already assigned to stock requests that belong to " + "another company." + ) + ) + if any( + self.env["stock.request.order"].search( + [ + ("company_id", "!=", rec.company_id.id), + ("warehouse_id", "=", rec.id), + ], + limit=1, + ) + for rec in self + ): raise ValidationError( - _('You cannot change the company of the warehouse, as it is ' - 'already assigned to stock request orders that belong to ' - 'another company.')) + _( + "You cannot change the company of the warehouse, as it is " + "already assigned to stock request orders that belong to " + "another company." + ) + ) diff --git a/stock_request/security/stock_request_security.xml b/stock_request/security/stock_request_security.xml index 4d5bc9ce3..b2c91d4da 100644 --- a/stock_request/security/stock_request_security.xml +++ b/stock_request/security/stock_request_security.xml @@ -39,7 +39,7 @@ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] - + Follow Stock Request @@ -51,7 +51,7 @@ ['|',('requested_by','=',user.id), ('message_partner_ids', 'in', [user.partner_id.id])] - + Stock Request User @@ -62,7 +62,7 @@ [('requested_by','=',user.id)] - + Stock Request Manager diff --git a/stock_request/tests/__init__.py b/stock_request/tests/__init__.py index 9f108b1d9..58398d412 100644 --- a/stock_request/tests/__init__.py +++ b/stock_request/tests/__init__.py @@ -1,2 +1 @@ - from . import test_stock_request diff --git a/stock_request/tests/test_stock_request.py b/stock_request/tests/test_stock_request.py index 51b98fa6f..bdcd462e8 100644 --- a/stock_request/tests/test_stock_request.py +++ b/stock_request/tests/test_stock_request.py @@ -1,189 +1,212 @@ # Copyright 2017 Eficent Business and IT Consulting Services S.L. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0). -from odoo.tests import common -from odoo import fields, exceptions from collections import Counter from datetime import datetime +from odoo import exceptions, fields +from odoo.tests import common + class TestStockRequest(common.TransactionCase): - def setUp(self): super(TestStockRequest, self).setUp() # common models - self.stock_request = self.env['stock.request'] - self.request_order = self.env['stock.request.order'] + self.stock_request = self.env["stock.request"] + self.request_order = self.env["stock.request.order"] # refs - self.stock_request_user_group = \ - self.env.ref('stock_request.group_stock_request_user') - self.stock_request_manager_group = \ - self.env.ref('stock_request.group_stock_request_manager') - self.main_company = self.env.ref('base.main_company') - self.warehouse = self.env.ref('stock.warehouse0') - self.categ_unit = self.env.ref('uom.product_uom_categ_unit') - self.virtual_loc = self.env.ref('stock.stock_location_customers') + self.stock_request_user_group = self.env.ref( + "stock_request.group_stock_request_user" + ) + self.stock_request_manager_group = self.env.ref( + "stock_request.group_stock_request_manager" + ) + self.main_company = self.env.ref("base.main_company") + self.warehouse = self.env.ref("stock.warehouse0") + self.categ_unit = self.env.ref("uom.product_uom_categ_unit") + self.virtual_loc = self.env.ref("stock.stock_location_customers") # common data - self.company_2 = self.env['res.company'].create({ - 'name': 'Comp2', - 'parent_id': self.main_company.id - }) - self.wh2 = self.env['stock.warehouse'].search( - [('company_id', '=', self.company_2.id)], limit=1) + self.company_2 = self.env["res.company"].create( + {"name": "Comp2", "parent_id": self.main_company.id} + ) + self.wh2 = self.env["stock.warehouse"].search( + [("company_id", "=", self.company_2.id)], limit=1 + ) self.stock_request_user = self._create_user( - 'stock_request_user', + "stock_request_user", [self.stock_request_user_group.id], - [self.main_company.id, self.company_2.id]) + [self.main_company.id, self.company_2.id], + ) self.stock_request_manager = self._create_user( - 'stock_request_manager', + "stock_request_manager", [self.stock_request_manager_group.id], - [self.main_company.id, self.company_2.id]) - self.product = self._create_product('SH', 'Shoes', False) - self.product_company_2 = self._create_product('SH_2', 'Shoes', - self.company_2.id) + [self.main_company.id, self.company_2.id], + ) + self.product = self._create_product("SH", "Shoes", False) + self.product_company_2 = self._create_product( + "SH_2", "Shoes", self.company_2.id + ) - self.ressuply_loc = self.env['stock.location'].create({ - 'name': 'Ressuply', - 'location_id': self.warehouse.view_location_id.id, - }) + self.ressuply_loc = self.env["stock.location"].create( + {"name": "Ressuply", "location_id": self.warehouse.view_location_id.id} + ) - self.ressuply_loc_2 = self.env['stock.location'].create({ - 'name': 'Ressuply', - 'location_id': self.wh2.view_location_id.id, - }) + self.ressuply_loc_2 = self.env["stock.location"].create( + {"name": "Ressuply", "location_id": self.wh2.view_location_id.id} + ) - self.route = self.env['stock.location.route'].create({ - 'name': 'Transfer', - 'product_categ_selectable': False, - 'product_selectable': True, - 'company_id': self.main_company.id, - 'sequence': 10, - }) + self.route = self.env["stock.location.route"].create( + { + "name": "Transfer", + "product_categ_selectable": False, + "product_selectable": True, + "company_id": self.main_company.id, + "sequence": 10, + } + ) - self.route_2 = self.env['stock.location.route'].create({ - 'name': 'Transfer', - 'product_categ_selectable': False, - 'product_selectable': True, - 'company_id': self.company_2.id, - 'sequence': 10, - }) + self.route_2 = self.env["stock.location.route"].create( + { + "name": "Transfer", + "product_categ_selectable": False, + "product_selectable": True, + "company_id": self.company_2.id, + "sequence": 10, + } + ) - self.uom_dozen = self.env['uom.uom'].create({ - 'name': 'Test-DozenA', - 'category_id': self.categ_unit.id, - 'factor_inv': 12, - 'uom_type': 'bigger', - 'rounding': 0.001}) + self.uom_dozen = self.env["uom.uom"].create( + { + "name": "Test-DozenA", + "category_id": self.categ_unit.id, + "factor_inv": 12, + "uom_type": "bigger", + "rounding": 0.001, + } + ) - self.env['stock.rule'].create({ - 'name': 'Transfer', - 'route_id': self.route.id, - 'location_src_id': self.ressuply_loc.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'action': 'pull', - 'picking_type_id': self.warehouse.int_type_id.id, - 'procure_method': 'make_to_stock', - 'warehouse_id': self.warehouse.id, - 'company_id': self.main_company.id, - 'propagate': 'False', - }) + self.env["stock.rule"].create( + { + "name": "Transfer", + "route_id": self.route.id, + "location_src_id": self.ressuply_loc.id, + "location_id": self.warehouse.lot_stock_id.id, + "action": "pull", + "picking_type_id": self.warehouse.int_type_id.id, + "procure_method": "make_to_stock", + "warehouse_id": self.warehouse.id, + "company_id": self.main_company.id, + "propagate": "False", + } + ) - self.env['stock.rule'].create({ - 'name': 'Transfer', - 'route_id': self.route_2.id, - 'location_src_id': self.ressuply_loc_2.id, - 'location_id': self.wh2.lot_stock_id.id, - 'action': 'pull', - 'picking_type_id': self.wh2.int_type_id.id, - 'procure_method': 'make_to_stock', - 'warehouse_id': self.wh2.id, - 'company_id': self.company_2.id, - 'propagate': 'False', - }) + self.env["stock.rule"].create( + { + "name": "Transfer", + "route_id": self.route_2.id, + "location_src_id": self.ressuply_loc_2.id, + "location_id": self.wh2.lot_stock_id.id, + "action": "pull", + "picking_type_id": self.wh2.int_type_id.id, + "procure_method": "make_to_stock", + "warehouse_id": self.wh2.id, + "company_id": self.company_2.id, + "propagate": "False", + } + ) def _create_user(self, name, group_ids, company_ids): - return self.env['res.users'].with_context( - {'no_reset_password': True}).create( - {'name': name, - 'password': 'demo', - 'login': name, - 'email': '@'.join([name, '@test.com']), - 'groups_id': [(6, 0, group_ids)], - 'company_ids': [(6, 0, company_ids)] - }) + return ( + self.env["res.users"] + .with_context({"no_reset_password": True}) + .create( + { + "name": name, + "password": "demo", + "login": name, + "email": "@".join([name, "@test.com"]), + "groups_id": [(6, 0, group_ids)], + "company_ids": [(6, 0, company_ids)], + } + ) + ) def _create_product(self, default_code, name, company_id, **vals): - return self.env['product.product'].create(dict( - name=name, - default_code=default_code, - uom_id=self.env.ref('uom.product_uom_unit').id, - company_id=company_id, - type='product', - **vals - )) + return self.env["product.product"].create( + dict( + name=name, + default_code=default_code, + uom_id=self.env.ref("uom.product_uom_unit").id, + company_id=company_id, + type="product", + **vals + ) + ) class TestStockRequestBase(TestStockRequest): - def setUp(self): super(TestStockRequestBase, self).setUp() def test_defaults(self): vals = { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, } - stock_request = self.stock_request.sudo( - self.stock_request_user.id).with_context( - company_id=self.main_company.id).create(vals) + stock_request = ( + self.stock_request.sudo(self.stock_request_user.id) + .with_context(company_id=self.main_company.id) + .create(vals) + ) - self.assertEqual( - stock_request.requested_by, self.stock_request_user) + self.assertEqual(stock_request.requested_by, self.stock_request_user) - self.assertEqual( - stock_request.warehouse_id, self.warehouse) + self.assertEqual(stock_request.warehouse_id, self.warehouse) - self.assertEqual( - stock_request.location_id, self.warehouse.lot_stock_id) + self.assertEqual(stock_request.location_id, self.warehouse.lot_stock_id) def test_defaults_order(self): vals = {} - order = self.request_order.sudo( - self.stock_request_user.id).with_context( - company_id=self.main_company.id).create(vals) + order = ( + self.request_order.sudo(self.stock_request_user.id) + .with_context(company_id=self.main_company.id) + .create(vals) + ) - self.assertEqual( - order.requested_by, self.stock_request_user) + self.assertEqual(order.requested_by, self.stock_request_user) - self.assertEqual( - order.warehouse_id, self.warehouse) + self.assertEqual(order.warehouse_id, self.warehouse) - self.assertEqual( - order.location_id, self.warehouse.lot_stock_id) + self.assertEqual(order.location_id, self.warehouse.lot_stock_id) def test_onchanges_order(self): expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } - order = self.request_order.sudo( - self.stock_request_user).new(vals) + order = self.request_order.sudo(self.stock_request_user).new(vals) self.stock_request_user.company_id = self.company_2 order.company_id = self.company_2 @@ -194,50 +217,41 @@ class TestStockRequestBase(TestStockRequest): self.assertEqual(order.location_id, self.wh2.lot_stock_id) self.assertEqual(order.warehouse_id, stock_request.warehouse_id) - procurement_group = self.env['procurement.group'].create({ - 'name': 'TEST' - }) + procurement_group = self.env["procurement.group"].create({"name": "TEST"}) order.procurement_group_id = procurement_group order.onchange_procurement_group_id() self.assertEqual( - order.procurement_group_id, - order.stock_request_ids.procurement_group_id) + order.procurement_group_id, order.stock_request_ids.procurement_group_id + ) order.procurement_group_id = procurement_group order.onchange_procurement_group_id() self.assertEqual( - order.procurement_group_id, - order.stock_request_ids.procurement_group_id) - order.picking_policy = 'one' + order.procurement_group_id, order.stock_request_ids.procurement_group_id + ) + order.picking_policy = "one" order.onchange_picking_policy() - self.assertEqual( - order.picking_policy, - order.stock_request_ids.picking_policy) + self.assertEqual(order.picking_policy, order.stock_request_ids.picking_policy) order.expected_date = datetime.now() order.onchange_expected_date() - self.assertEqual( - order.expected_date, - order.stock_request_ids.expected_date) + self.assertEqual(order.expected_date, order.stock_request_ids.expected_date) order.requested_by = self.stock_request_manager order.onchange_requested_by() - self.assertEqual( - order.requested_by, - order.stock_request_ids.requested_by) + self.assertEqual(order.requested_by, order.stock_request_ids.requested_by) def test_onchanges(self): self.product.route_ids = [(6, 0, self.route.ids)] vals = { - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, } - stock_request = self.stock_request.sudo( - self.stock_request_user).new(vals) + stock_request = self.stock_request.sudo(self.stock_request_user).new(vals) stock_request.product_id = self.product - vals = stock_request.default_get(['warehouse_id', 'company_id']) + vals = stock_request.default_get(["warehouse_id", "company_id"]) stock_request.update(vals) stock_request.onchange_product_id() self.assertIn(self.route.id, stock_request.route_ids.ids) @@ -246,41 +260,40 @@ class TestStockRequestBase(TestStockRequest): stock_request.company_id = self.company_2 stock_request.onchange_company_id() - self.assertEqual( - stock_request.warehouse_id, self.wh2) - self.assertEqual( - stock_request.location_id, self.wh2.lot_stock_id) + self.assertEqual(stock_request.warehouse_id, self.wh2) + self.assertEqual(stock_request.location_id, self.wh2.lot_stock_id) - product = self.env['product.product'].create({ - 'name': 'Wheat', - 'uom_id': self.env.ref('uom.product_uom_kgm').id, - 'uom_po_id': self.env.ref('uom.product_uom_kgm').id, - }) + product = self.env["product.product"].create( + { + "name": "Wheat", + "uom_id": self.env.ref("uom.product_uom_kgm").id, + "uom_po_id": self.env.ref("uom.product_uom_kgm").id, + } + ) # Test onchange_product_id stock_request.product_id = product res = stock_request.onchange_product_id() - self.assertEqual(res['domain']['product_uom_id'], - [('category_id', '=', - product.uom_id.category_id.id)]) self.assertEqual( - stock_request.product_uom_id, - self.env.ref('uom.product_uom_kgm')) + res["domain"]["product_uom_id"], + [("category_id", "=", product.uom_id.category_id.id)], + ) + self.assertEqual( + stock_request.product_uom_id, self.env.ref("uom.product_uom_kgm") + ) - stock_request.product_id = self.env['product.product'] + stock_request.product_id = self.env["product.product"] res = stock_request.onchange_product_id() - self.assertEqual(res['domain']['product_uom_id'], []) + self.assertEqual(res["domain"]["product_uom_id"], []) # Test onchange_warehouse_id - wh2_2 = self.env['stock.warehouse'].with_context( - company_id=self.company_2.id - ).create({ - 'name': 'C2_2', - 'code': 'C2_2', - 'company_id': self.company_2.id - }) + wh2_2 = ( + self.env["stock.warehouse"] + .with_context(company_id=self.company_2.id) + .create({"name": "C2_2", "code": "C2_2", "company_id": self.company_2.id}) + ) stock_request.warehouse_id = wh2_2 stock_request.onchange_warehouse_id() @@ -290,151 +303,180 @@ class TestStockRequestBase(TestStockRequest): stock_request.warehouse_id = self.warehouse stock_request.onchange_warehouse_id() - self.assertEqual( - stock_request.company_id, self.main_company) - self.assertEqual( - stock_request.location_id, self.warehouse.lot_stock_id) + self.assertEqual(stock_request.company_id, self.main_company) + self.assertEqual(stock_request.location_id, self.warehouse.lot_stock_id) def test_stock_request_order_validations_01(self): """ Testing the discrepancy in warehouse_id between stock request and order""" expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.wh2.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.wh2.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } with self.assertRaises(exceptions.ValidationError): - self.request_order.sudo( - self.stock_request_user).create(vals) + self.request_order.sudo(self.stock_request_user).create(vals) def test_stock_request_order_validations_02(self): """ Testing the discrepancy in location_id between stock request and order""" expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.wh2.lot_stock_id.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.wh2.lot_stock_id.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } with self.assertRaises(exceptions.ValidationError): - self.request_order.sudo( - self.stock_request_user).create(vals) + self.request_order.sudo(self.stock_request_user).create(vals) def test_stock_request_order_validations_03(self): """ Testing the discrepancy in requested_by between stock request and order""" expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'requested_by': self.stock_request_user.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'requested_by': self.stock_request_manager.id, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "requested_by": self.stock_request_user.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "requested_by": self.stock_request_manager.id, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } with self.assertRaises(exceptions.ValidationError): - self.request_order.sudo( - self.stock_request_user).create(vals) + self.request_order.sudo(self.stock_request_user).create(vals) def test_stock_request_order_validations_04(self): """ Testing the discrepancy in procurement_group_id between stock request and order""" - procurement_group = self.env['procurement.group'].create({ - 'name': 'Procurement', - }) + procurement_group = self.env["procurement.group"].create( + {"name": "Procurement"} + ) expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'procurement_group_id': procurement_group.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "procurement_group_id": procurement_group.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } with self.assertRaises(exceptions.ValidationError): - self.request_order.sudo( - self.stock_request_user).create(vals) + self.request_order.sudo(self.stock_request_user).create(vals) def test_stock_request_order_validations_05(self): """ Testing the discrepancy in company between stock request and order""" expected_date = fields.Datetime.now() vals = { - 'company_id': self.company_2.id, - 'warehouse_id': self.wh2.id, - 'location_id': self.wh2.lot_stock_id.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.company_2.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.company_2.id, + "warehouse_id": self.wh2.id, + "location_id": self.wh2.lot_stock_id.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.company_2.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } with self.assertRaises(exceptions.ValidationError): - self.request_order.sudo( - self.stock_request_user).create(vals) + self.request_order.sudo(self.stock_request_user).create(vals) def test_stock_request_order_validations_06(self): """ Testing the discrepancy in expected dates between stock request and order""" expected_date = fields.Datetime.now() - child_expected_date = '2015-01-01' + child_expected_date = "2015-01-01" vals = { - 'company_id': self.company_2.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': child_expected_date, - })] + "company_id": self.company_2.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": child_expected_date, + }, + ) + ], } with self.assertRaises(exceptions.ValidationError): self.request_order.sudo().create(vals) @@ -444,51 +486,54 @@ class TestStockRequestBase(TestStockRequest): stock request and order""" expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'picking_policy': 'one', - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "picking_policy": "one", + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } with self.assertRaises(exceptions.ValidationError): - self.request_order.sudo( - self.stock_request_user).create(vals) + self.request_order.sudo(self.stock_request_user).create(vals) def test_stock_request_validations_01(self): vals = { - 'product_id': self.product.id, - 'product_uom_id': self.env.ref('uom.product_uom_kgm').id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, + "product_id": self.product.id, + "product_uom_id": self.env.ref("uom.product_uom_kgm").id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, } # Select a UoM that is incompatible with the product's UoM with self.assertRaises(exceptions.ValidationError): - self.stock_request.sudo( - self.stock_request_user).create(vals) + self.stock_request.sudo(self.stock_request_user).create(vals) def test_stock_request_validations_02(self): vals = { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, } - stock_request = self.stock_request.sudo( - self.stock_request_user).create(vals) + stock_request = self.stock_request.sudo(self.stock_request_user).create(vals) # With no route found, should raise an error with self.assertRaises(exceptions.UserError): @@ -497,43 +542,51 @@ class TestStockRequestBase(TestStockRequest): def test_create_request_01(self): expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } - order = self.request_order.sudo( - self.stock_request_user).create(vals) + order = self.request_order.sudo(self.stock_request_user).create(vals) stock_request = order.stock_request_ids self.product.route_ids = [(6, 0, self.route.ids)] order.action_confirm() - self.assertEqual(order.state, 'open') - self.assertEqual(stock_request.state, 'open') + self.assertEqual(order.state, "open") + self.assertEqual(stock_request.state, "open") self.assertEqual(len(order.sudo().picking_ids), 1) self.assertEqual(len(order.sudo().move_ids), 1) self.assertEqual(len(stock_request.sudo().picking_ids), 1) self.assertEqual(len(stock_request.sudo().move_ids), 1) - self.assertEqual(stock_request.sudo().move_ids[0].location_dest_id, - stock_request.location_id) - self.assertEqual(stock_request.qty_in_progress, - stock_request.product_uom_qty) - self.env['stock.quant'].create({ - 'product_id': self.product.id, - 'location_id': self.ressuply_loc.id, - 'quantity': 5.0}) + self.assertEqual( + stock_request.sudo().move_ids[0].location_dest_id, stock_request.location_id + ) + self.assertEqual(stock_request.qty_in_progress, stock_request.product_uom_qty) + self.env["stock.quant"].create( + { + "product_id": self.product.id, + "location_id": self.ressuply_loc.id, + "quantity": 5.0, + } + ) picking = stock_request.sudo().picking_ids[0] picking.action_confirm() self.assertEqual(stock_request.qty_in_progress, 5.0) @@ -544,39 +597,40 @@ class TestStockRequestBase(TestStockRequest): packout1.qty_done = 5 picking.action_done() self.assertEqual(stock_request.qty_in_progress, 0.0) - self.assertEqual(stock_request.qty_done, - stock_request.product_uom_qty) - self.assertEqual(order.state, 'done') - self.assertEqual(stock_request.state, 'done') + self.assertEqual(stock_request.qty_done, stock_request.product_uom_qty) + self.assertEqual(order.state, "done") + self.assertEqual(stock_request.state, "done") def test_create_request_02(self): """Use different UoM's""" vals = { - 'product_id': self.product.id, - 'product_uom_id': self.uom_dozen.id, - 'product_uom_qty': 1.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, + "product_id": self.product.id, + "product_uom_id": self.uom_dozen.id, + "product_uom_qty": 1.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, } - stock_request = self.stock_request.sudo( - self.stock_request_user).create(vals) + stock_request = self.stock_request.sudo(self.stock_request_user).create(vals) self.product.route_ids = [(6, 0, self.route.ids)] stock_request.action_confirm() - self.assertEqual(stock_request.state, 'open') + self.assertEqual(stock_request.state, "open") self.assertEqual(len(stock_request.sudo().picking_ids), 1) self.assertEqual(len(stock_request.sudo().move_ids), 1) - self.assertEqual(stock_request.sudo().move_ids[0].location_dest_id, - stock_request.location_id) - self.assertEqual(stock_request.qty_in_progress, - stock_request.product_uom_qty) - self.env['stock.quant'].create({ - 'product_id': self.product.id, - 'location_id': self.ressuply_loc.id, - 'quantity': 12.0}) + self.assertEqual( + stock_request.sudo().move_ids[0].location_dest_id, stock_request.location_id + ) + self.assertEqual(stock_request.qty_in_progress, stock_request.product_uom_qty) + self.env["stock.quant"].create( + { + "product_id": self.product.id, + "location_id": self.ressuply_loc.id, + "quantity": 12.0, + } + ) picking = stock_request.sudo().picking_ids[0] picking.action_confirm() self.assertEqual(stock_request.qty_in_progress, 1.0) @@ -586,38 +640,44 @@ class TestStockRequestBase(TestStockRequest): packout1.qty_done = 1 picking.action_done() self.assertEqual(stock_request.qty_in_progress, 0.0) - self.assertEqual(stock_request.qty_done, - stock_request.product_uom_qty) - self.assertEqual(stock_request.state, 'done') + self.assertEqual(stock_request.qty_done, stock_request.product_uom_qty) + self.assertEqual(stock_request.state, "done") def test_create_request_03(self): """Multiple stock requests""" vals = { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 4.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 4.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, } - stock_request_1 = self.env['stock.request'].sudo( - self.stock_request_user).create(vals) - stock_request_2 = self.env['stock.request'].sudo( - self.stock_request_manager).create(vals) + stock_request_1 = ( + self.env["stock.request"].sudo(self.stock_request_user).create(vals) + ) + stock_request_2 = ( + self.env["stock.request"].sudo(self.stock_request_manager).create(vals) + ) stock_request_2.product_uom_qty = 6.0 self.product.route_ids = [(6, 0, self.route.ids)] stock_request_1.action_confirm() stock_request_2.action_confirm() self.assertEqual(len(stock_request_1.sudo().picking_ids), 1) - self.assertEqual(stock_request_1.sudo().picking_ids, - stock_request_2.sudo().picking_ids) - self.assertEqual(stock_request_1.sudo().move_ids, - stock_request_2.sudo().move_ids) - self.env['stock.quant'].create({ - 'product_id': self.product.id, - 'location_id': self.ressuply_loc.id, - 'quantity': 10.0}) + self.assertEqual( + stock_request_1.sudo().picking_ids, stock_request_2.sudo().picking_ids + ) + self.assertEqual( + stock_request_1.sudo().move_ids, stock_request_2.sudo().move_ids + ) + self.env["stock.quant"].create( + { + "product_id": self.product.id, + "location_id": self.ressuply_loc.id, + "quantity": 10.0, + } + ) picking = stock_request_1.sudo().picking_ids[0] picking.action_confirm() picking.action_assign() @@ -628,23 +688,28 @@ class TestStockRequestBase(TestStockRequest): def test_cancel_request(self): expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } - order = self.request_order.sudo( - self.stock_request_user).create(vals) + order = self.request_order.sudo(self.stock_request_user).create(vals) self.product.route_ids = [(6, 0, self.route.ids)] order.action_confirm() @@ -653,14 +718,17 @@ class TestStockRequestBase(TestStockRequest): self.assertEqual(len(order.sudo().move_ids), 1) self.assertEqual(len(stock_request.sudo().picking_ids), 1) self.assertEqual(len(stock_request.sudo().move_ids), 1) - self.assertEqual(stock_request.sudo().move_ids[0].location_dest_id, - stock_request.location_id) - self.assertEqual(stock_request.qty_in_progress, - stock_request.product_uom_qty) - self.env['stock.quant'].create({ - 'product_id': self.product.id, - 'location_id': self.ressuply_loc.id, - 'quantity': 5.0}) + self.assertEqual( + stock_request.sudo().move_ids[0].location_dest_id, stock_request.location_id + ) + self.assertEqual(stock_request.qty_in_progress, stock_request.product_uom_qty) + self.env["stock.quant"].create( + { + "product_id": self.product.id, + "location_id": self.ressuply_loc.id, + "quantity": 5.0, + } + ) picking = stock_request.sudo().picking_ids[0] picking.action_confirm() self.assertEqual(stock_request.qty_in_progress, 5.0) @@ -674,8 +742,8 @@ class TestStockRequestBase(TestStockRequest): # Set the request back to draft order.action_draft() - self.assertEqual(order.state, 'draft') - self.assertEqual(stock_request.state, 'draft') + self.assertEqual(order.state, "draft") + self.assertEqual(stock_request.state, "draft") # Re-confirm. We expect new pickings to be created order.action_confirm() @@ -685,19 +753,25 @@ class TestStockRequestBase(TestStockRequest): def test_view_actions(self): expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + "expected_date": expected_date, + }, + ) + ], } order = self.request_order.sudo().create(vals) @@ -709,36 +783,35 @@ class TestStockRequestBase(TestStockRequest): self.assertTrue(order.picking_ids) action = order.action_view_transfer() - self.assertEqual('domain' in action.keys(), True) - self.assertEqual('views' in action.keys(), True) - self.assertEqual(action['res_id'], order.picking_ids[0].id) + self.assertEqual("domain" in action.keys(), True) + self.assertEqual("views" in action.keys(), True) + self.assertEqual(action["res_id"], order.picking_ids[0].id) action = order.action_view_stock_requests() - self.assertEqual('domain' in action.keys(), True) - self.assertEqual('views' in action.keys(), True) - self.assertEqual(action['res_id'], stock_request[0].id) + self.assertEqual("domain" in action.keys(), True) + self.assertEqual("views" in action.keys(), True) + self.assertEqual(action["res_id"], stock_request[0].id) action = stock_request.action_view_transfer() - self.assertEqual('domain' in action.keys(), True) - self.assertEqual('views' in action.keys(), True) - self.assertEqual(action['res_id'], stock_request.picking_ids[0].id) + self.assertEqual("domain" in action.keys(), True) + self.assertEqual("views" in action.keys(), True) + self.assertEqual(action["res_id"], stock_request.picking_ids[0].id) action = stock_request.picking_ids[0].action_view_stock_request() - self.assertEqual(action['type'], 'ir.actions.act_window') - self.assertEqual(action['res_id'], stock_request.id) + self.assertEqual(action["type"], "ir.actions.act_window") + self.assertEqual(action["res_id"], stock_request.id) def test_stock_request_constrains(self): vals = { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, } - stock_request = self.stock_request.sudo( - self.stock_request_user).create(vals) + stock_request = self.stock_request.sudo(self.stock_request_user).create(vals) # Cannot assign a warehouse that belongs to another company with self.assertRaises(exceptions.ValidationError): @@ -754,22 +827,24 @@ class TestStockRequestBase(TestStockRequest): stock_request.route_id = self.route_2 def test_stock_request_order_from_products(self): - product_a1 = self._create_product('CODEA1', 'Product A1', - self.main_company.id) + product_a1 = self._create_product("CODEA1", "Product A1", self.main_company.id) template_a = product_a1.product_tmpl_id product_a2 = self._create_product( - 'CODEA2', 'Product A2', self.main_company.id, - product_tmpl_id=template_a.id) + "CODEA2", "Product A2", self.main_company.id, product_tmpl_id=template_a.id + ) product_a3 = self._create_product( - 'CODEA3', 'Product A3', self.main_company.id, - product_tmpl_id=template_a.id) - product_b1 = self._create_product('CODEB1', 'Product B1', - self.main_company.id) + "CODEA3", "Product A3", self.main_company.id, product_tmpl_id=template_a.id + ) + product_b1 = self._create_product("CODEB1", "Product B1", self.main_company.id) template_b = product_b1.product_tmpl_id # One archived variant of B self._create_product( - 'CODEB2', 'Product B2', self.main_company.id, - product_tmpl_id=template_b.id, active=False) + "CODEB2", + "Product B2", + self.main_company.id, + product_tmpl_id=template_b.id, + active=False, + ) order = self.request_order # Selecting some variants and creating an order @@ -778,12 +853,15 @@ class TestStockRequestBase(TestStockRequest): action = order._create_from_product_multiselect(wanted_products) new_order = order.search([]) - preexisting self.assertEqual(len(new_order), 1) - self.assertEqual(action['res_id'], new_order.id, - msg="Returned action references the wrong record") + self.assertEqual( + action["res_id"], + new_order.id, + msg="Returned action references the wrong record", + ) self.assertEqual( Counter(wanted_products), - Counter(new_order.stock_request_ids.mapped('product_id')), - msg="Not all wanted products were ordered" + Counter(new_order.stock_request_ids.mapped("product_id")), + msg="Not all wanted products were ordered", ) # Selecting a template and creating an order @@ -791,26 +869,31 @@ class TestStockRequestBase(TestStockRequest): action = order._create_from_product_multiselect(template_a) new_order = order.search([]) - preexisting self.assertEqual(len(new_order), 1) - self.assertEqual(action['res_id'], new_order.id, - msg="Returned action references the wrong record") + self.assertEqual( + action["res_id"], + new_order.id, + msg="Returned action references the wrong record", + ) self.assertEqual( Counter(product_a1 + product_a2 + product_a3), - Counter(new_order.stock_request_ids.mapped('product_id')), - msg="Not all of the template's variants were ordered" + Counter(new_order.stock_request_ids.mapped("product_id")), + msg="Not all of the template's variants were ordered", ) # Selecting a template preexisting = order.search([]) - action = order._create_from_product_multiselect( - template_a + template_b) + action = order._create_from_product_multiselect(template_a + template_b) new_order = order.search([]) - preexisting self.assertEqual(len(new_order), 1) - self.assertEqual(action['res_id'], new_order.id, - msg="Returned action references the wrong record") + self.assertEqual( + action["res_id"], + new_order.id, + msg="Returned action references the wrong record", + ) self.assertEqual( Counter(product_a1 + product_a2 + product_a3 + product_b1), - Counter(new_order.stock_request_ids.mapped('product_id')), - msg="Inactive variant was ordered though it shouldn't have been" + Counter(new_order.stock_request_ids.mapped("product_id")), + msg="Inactive variant was ordered though it shouldn't have been", ) # If a user does not have stock request rights, they can still trigger @@ -818,17 +901,19 @@ class TestStockRequestBase(TestStockRequest): # error message. self.stock_request_user.groups_id -= self.stock_request_user_group with self.assertRaisesRegexp( - exceptions.UserError, - "Unfortunately it seems you do not have the necessary rights " - "for creating stock requests. Please contact your " - "administrator."): - order.sudo( - self.stock_request_user - )._create_from_product_multiselect(template_a + template_b) + exceptions.UserError, + "Unfortunately it seems you do not have the necessary rights " + "for creating stock requests. Please contact your " + "administrator.", + ): + order.sudo(self.stock_request_user)._create_from_product_multiselect( + template_a + template_b + ) # Empty recordsets should just return False - self.assertFalse(order._create_from_product_multiselect( - self.env['product.product'])) + self.assertFalse( + order._create_from_product_multiselect(self.env["product.product"]) + ) # Wrong model should just raise ValidationError with self.assertRaises(exceptions.ValidationError): @@ -837,46 +922,48 @@ class TestStockRequestBase(TestStockRequest): def test_allow_virtual_location(self): self.main_company.stock_request_allow_virtual_loc = True vals = { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.virtual_loc.id, + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.virtual_loc.id, } - stock_request = self.stock_request.sudo( - self.stock_request_user).create(vals) + stock_request = self.stock_request.sudo(self.stock_request_user).create(vals) stock_request.onchange_allow_virtual_location() self.assertTrue(stock_request.allow_virtual_location) vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.virtual_loc.id, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.virtual_loc.id, } - order = self.request_order.sudo( - self.stock_request_user).create(vals) + order = self.request_order.sudo(self.stock_request_user).create(vals) order.onchange_allow_virtual_location() self.assertTrue(order.allow_virtual_location) def test_onchange_wh_no_effect_from_order(self): expected_date = fields.Datetime.now() vals = { - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.virtual_loc.id, - 'expected_date': expected_date, - 'stock_request_ids': [(0, 0, { - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 5.0, - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.virtual_loc.id, - 'expected_date': expected_date, - })] + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.virtual_loc.id, + "expected_date": expected_date, + "stock_request_ids": [ + ( + 0, + 0, + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 5.0, + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.virtual_loc.id, + "expected_date": expected_date, + }, + ) + ], } - order = self.request_order.sudo( - self.stock_request_user).create(vals) + order = self.request_order.sudo(self.stock_request_user).create(vals) order.stock_request_ids.onchange_warehouse_id() - self.assertEqual( - order.stock_request_ids[0].location_id, self.virtual_loc) + self.assertEqual(order.stock_request_ids[0].location_id, self.virtual_loc)