diff --git a/stock_request_kanban/__manifest__.py b/stock_request_kanban/__manifest__.py index 37a0551de..751ef59bc 100644 --- a/stock_request_kanban/__manifest__.py +++ b/stock_request_kanban/__manifest__.py @@ -2,30 +2,27 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). { - 'name': 'Stock Request kanban', - 'version': '12.0.1.0.1', - 'category': 'Reporting', - 'website': 'https://github.com/OCA/stock-logistics-warehouse', - 'author': 'Creu Blanca, Eficent, Odoo Community Association (OCA)', - 'license': 'AGPL-3', - 'summary': 'Adds a stock request order, and takes stock requests as lines', - 'depends': [ - 'stock_request', - 'barcodes', + "name": "Stock Request kanban", + "version": "13.0.1.0.1", + "category": "Warehouse Management", + "website": "https://github.com/OCA/stock-logistics-warehouse", + "author": "Creu Blanca, ForgeFlow, Odoo Community Association (OCA)", + "license": "LGPL-3", + "summary": "Adds a stock request order, and takes stock requests as lines", + "depends": ["stock_request", "barcodes"], + "data": [ + "data/stock_request_sequence_data.xml", + "report/report_paper_format.xml", + "wizard/wizard_stock_inventory_kanban_views.xml", + "wizard/wizard_stock_request_kanban_views.xml", + "wizard/wizard_stock_request_order_kanban_views.xml", + "views/stock_request_order_views.xml", + "views/stock_request_kanban_views.xml", + "views/stock_inventory_kanban_views.xml", + "views/stock_request_menu.xml", + "report/stock_request_kanban_templates.xml", + "security/ir.model.access.csv", ], - 'data': [ - 'data/stock_request_sequence_data.xml', - 'report/report_paper_format.xml', - 'wizard/wizard_stock_inventory_kanban_views.xml', - 'wizard/wizard_stock_request_kanban_views.xml', - 'wizard/wizard_stock_request_order_kanban_views.xml', - 'views/stock_request_order_views.xml', - 'views/stock_request_kanban_views.xml', - 'views/stock_inventory_kanban_views.xml', - 'views/stock_request_menu.xml', - 'report/stock_request_kanban_templates.xml', - 'security/ir.model.access.csv', - ], - 'installable': True, - 'application': False, + "installable": True, + "application": False, } diff --git a/stock_request_kanban/data/stock_request_sequence_data.xml b/stock_request_kanban/data/stock_request_sequence_data.xml index d3ead8e74..04d8d3843 100644 --- a/stock_request_kanban/data/stock_request_sequence_data.xml +++ b/stock_request_kanban/data/stock_request_sequence_data.xml @@ -1,22 +1,19 @@ - + - Stock Request Kanban stock.request.kanban KB 5 - + - Stock Inventory Kanban stock.inventory.kanban IKB 5 - + - diff --git a/stock_request_kanban/models/stock_inventory_kanban.py b/stock_request_kanban/models/stock_inventory_kanban.py index 36b8ccb8e..06f5bed02 100644 --- a/stock_request_kanban/models/stock_inventory_kanban.py +++ b/stock_request_kanban/models/stock_inventory_kanban.py @@ -1,69 +1,76 @@ # Copyright 2018 Creu Blanca # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, models, fields +from odoo import api, fields, models from odoo.osv import expression class StockInventoryKanban(models.Model): - _name = 'stock.inventory.kanban' - _description = 'Inventory for Kanban' - _inherit = ['mail.thread', 'mail.activity.mixin'] + _name = "stock.inventory.kanban" + _description = "Inventory for Kanban" + _inherit = ["mail.thread", "mail.activity.mixin"] name = fields.Char( - readonly=True, states={'draft': [('readonly', False)]}, copy=False, + readonly=True, states={"draft": [("readonly", False)]}, copy=False ) state = fields.Selection( [ - ('draft', 'Draft'), - ('in_progress', 'In progress'), - ('finished', 'Finished'), - ('closed', 'Closed'), - ('cancelled', 'Cancelled') + ("draft", "Draft"), + ("in_progress", "In progress"), + ("finished", "Finished"), + ("closed", "Closed"), + ("cancelled", "Cancelled"), ], - required=True, default='draft', readonly=True, copy=False, - track_visibility='onchange' + required=True, + default="draft", + readonly=True, + copy=False, + track_visibility="onchange", ) warehouse_ids = fields.Many2many( - 'stock.warehouse', string='Warehouse', + "stock.warehouse", + string="Warehouse", ondelete="cascade", - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, ) location_ids = fields.Many2many( - 'stock.location', string='Location', - domain=[('usage', 'in', ['internal', 'transit'])], + "stock.location", + string="Location", + domain=[("usage", "in", ["internal", "transit"])], ondelete="cascade", - readonly=True, states={'draft': [('readonly', False)]}, + readonly=True, + states={"draft": [("readonly", False)]}, ) product_ids = fields.Many2many( - 'product.product', string='Products', - domain=[('type', 'in', ['product', 'consu'])], - ondelete='cascade', - readonly=True, states={'draft': [('readonly', False)]}, + "product.product", + string="Products", + domain=[("type", "in", ["product", "consu"])], + ondelete="cascade", + readonly=True, + states={"draft": [("readonly", False)]}, ) kanban_ids = fields.Many2many( - 'stock.request.kanban', - relation='stock_inventory_kanban_kanban', - readonly=True, copy=False, + "stock.request.kanban", + relation="stock_inventory_kanban_kanban", + readonly=True, + copy=False, ) scanned_kanban_ids = fields.Many2many( - 'stock.request.kanban', - relation='stock_inventory_kanban_scanned_kanban', - readonly=True, copy=False, + "stock.request.kanban", + relation="stock_inventory_kanban_scanned_kanban", + readonly=True, + copy=False, ) missing_kanban_ids = fields.Many2many( - 'stock.request.kanban', - readonly=True, - compute='_compute_missing_kanban' + "stock.request.kanban", readonly=True, compute="_compute_missing_kanban" ) count_missing_kanbans = fields.Integer( - 'Missing Kanbans', - readonly=True, - compute='_compute_missing_kanban', + "Missing Kanbans", readonly=True, compute="_compute_missing_kanban" ) - @api.depends('kanban_ids', 'scanned_kanban_ids') + @api.depends("kanban_ids", "scanned_kanban_ids") def _compute_missing_kanban(self): for rec in self: rec.missing_kanban_ids = rec.kanban_ids.filtered( @@ -74,88 +81,73 @@ class StockInventoryKanban(models.Model): def _get_inventory_kanban_domain(self): domain = [] if self.warehouse_ids: - domain = expression.AND(( - domain, [('warehouse_id', 'in', self.warehouse_ids.ids)] - )) + domain = expression.AND( + (domain, [("warehouse_id", "in", self.warehouse_ids.ids)]) + ) if self.product_ids: - domain = expression.AND(( - domain, [('product_id', 'in', self.product_ids.ids)] - )) + domain = expression.AND( + (domain, [("product_id", "in", self.product_ids.ids)]) + ) if self.location_ids: - domain = expression.AND(( - domain, [('location_id', 'in', self.location_ids.ids)] - )) + domain = expression.AND( + (domain, [("location_id", "in", self.location_ids.ids)]) + ) return domain def _start_inventory_values(self): - return { - 'state': 'in_progress' - } + return {"state": "in_progress"} def _finish_inventory_values(self): - return { - 'state': 'finished' - } + return {"state": "finished"} def _close_inventory_values(self): - return { - 'state': 'closed' - } + return {"state": "closed"} @api.model def create(self, vals): - if vals.get('name', '/') == '/': - vals['name'] = self.env['ir.sequence'].next_by_code( - 'stock.inventory.kanban') + if vals.get("name", "/") == "/": + vals["name"] = self.env["ir.sequence"].next_by_code( + "stock.inventory.kanban" + ) return super().create(vals) - @api.multi def calculate_kanbans(self): for rec in self: - if rec.state == 'draft': - rec.kanban_ids = self.env['stock.request.kanban'].search( + if rec.state == "draft": + rec.kanban_ids = self.env["stock.request.kanban"].search( rec._get_inventory_kanban_domain() ) - @api.multi def start_inventory(self): self.calculate_kanbans() self.write(self._start_inventory_values()) - @api.multi def finish_inventory(self): self.write(self._finish_inventory_values()) - @api.multi def close_inventory(self): self.write(self._close_inventory_values()) - @api.multi def print_missing_kanbans(self): """ Print the missing kanban cards in order to restore them """ self.ensure_one() - return self.env.ref( - 'stock_request_kanban.action_report_kanban').report_action( + return self.env.ref("stock_request_kanban.action_report_kanban").report_action( self.missing_kanban_ids ) def _cancel_inventory_values(self): - return { - 'state': 'cancelled', - } + return {"state": "cancelled"} - @api.multi def cancel(self): self.write(self._cancel_inventory_values()) def _to_draft_inventory_values(self): return { - 'state': 'draft', - 'kanban_ids': [(5, 0)], - 'scanned_kanban_ids': [(5, 0)], + "state": "draft", + "kanban_ids": [(5, 0)], + "scanned_kanban_ids": [(5, 0)], } - @api.multi def to_draft(self): self.write(self._to_draft_inventory_values()) diff --git a/stock_request_kanban/models/stock_request.py b/stock_request_kanban/models/stock_request.py index 664b71afe..3a4462eec 100644 --- a/stock_request_kanban/models/stock_request.py +++ b/stock_request_kanban/models/stock_request.py @@ -1,10 +1,10 @@ # Copyright 2018 Creu Blanca # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import models, fields +from odoo import fields, models class StockRequest(models.Model): - _inherit = 'stock.request' + _inherit = "stock.request" - kanban_id = fields.Many2one('stock.request.kanban', readonly=True) + kanban_id = fields.Many2one("stock.request.kanban", readonly=True) diff --git a/stock_request_kanban/models/stock_request_kanban.py b/stock_request_kanban/models/stock_request_kanban.py index 1c0fc0cc9..754ca735b 100644 --- a/stock_request_kanban/models/stock_request_kanban.py +++ b/stock_request_kanban/models/stock_request_kanban.py @@ -1,47 +1,52 @@ # Copyright 2018 Creu Blanca # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo import api, models, fields, _ -from odoo.exceptions import ValidationError from reportlab.graphics.barcode import getCodes +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + class StockRequestKanban(models.Model): - _name = 'stock.request.kanban' - _description = 'Stock Request Kanban' - _inherit = 'stock.request.abstract' + _name = "stock.request.kanban" + _description = "Stock Request Kanban" + _inherit = "stock.request.abstract" active = fields.Boolean(default=True) @api.model def create(self, vals): - if vals.get('name', '/') == '/': - vals['name'] = self.env['ir.sequence'].next_by_code( - 'stock.request.kanban') + if vals.get("name", "/") == "/": + vals["name"] = self.env["ir.sequence"].next_by_code("stock.request.kanban") return super().create(vals) @api.model def get_barcode_format(self): - return self.env['ir.config_parameter'].sudo().get_param( - 'stock_request_kanban.barcode_format', default='Standard39' + return ( + self.env["ir.config_parameter"] + .sudo() + .get_param("stock_request_kanban.barcode_format", default="Standard39") ) @api.model def _recompute_barcode(self, barcode): - if self.env['ir.config_parameter'].sudo().get_param( - 'stock_request_kanban.crc', default='1' - ) == '0': + if ( + self.env["ir.config_parameter"] + .sudo() + .get_param("stock_request_kanban.crc", default="1") + == "0" + ): return barcode bcc = getCodes()[self.get_barcode_format()](value=barcode[:-1]) bcc.validate() bcc.encode() if bcc.encoded[1:-1] != barcode: - raise ValidationError(_('CRC is not valid')) + raise ValidationError(_("CRC is not valid")) return barcode[:-1] @api.model def search_barcode(self, barcode): recomputed_barcode = self._recompute_barcode(barcode) - return self.env['stock.request.kanban'].search([ - ('name', '=', recomputed_barcode) - ]) + return self.env["stock.request.kanban"].search( + [("name", "ilike", recomputed_barcode)] + ) diff --git a/stock_request_kanban/report/report_paper_format.xml b/stock_request_kanban/report/report_paper_format.xml index 4296a6412..1c29095e8 100644 --- a/stock_request_kanban/report/report_paper_format.xml +++ b/stock_request_kanban/report/report_paper_format.xml @@ -11,5 +11,4 @@ 0 72 - - \ No newline at end of file + diff --git a/stock_request_kanban/report/stock_request_kanban_templates.xml b/stock_request_kanban/report/stock_request_kanban_templates.xml index 7ba023505..246e31fb7 100644 --- a/stock_request_kanban/report/stock_request_kanban_templates.xml +++ b/stock_request_kanban/report/stock_request_kanban_templates.xml @@ -1,90 +1,103 @@ - - + + - - + id="action_report_kanban" + string="Print kanban" + model="stock.request.kanban" + report_type="qweb-pdf" + name="stock_request_kanban.report_kanban_label" + file="stock_request_kanban.report_kanban_label" + paperformat="stock_request_kanban.kanban_paper_format" + menu="True" + /> diff --git a/stock_request_kanban/static/src/js/stock_request_kanban_scan_controller.js b/stock_request_kanban/static/src/js/stock_request_kanban_scan_controller.js new file mode 100644 index 000000000..2ba3b1e6b --- /dev/null +++ b/stock_request_kanban/static/src/js/stock_request_kanban_scan_controller.js @@ -0,0 +1,49 @@ +odoo.define("stock_request_kanban.StockRequestKanbanController", function(require) { + "use strict"; + + var core = require("web.core"); + var ListController = require("web.ListController"); + + var qweb = core.qweb; + + var StockRequestKanbanController = ListController.extend({ + // ------------------------------------------------------------------------- + // Public + // ------------------------------------------------------------------------- + + init: function(parent, model, renderer) { + this.context = renderer.state.getContext(); + return this._super.apply(this, arguments); + }, + + /** + * @override + */ + renderButtons: function($node) { + this._super.apply(this, arguments); + var $buttonScan = $(qweb.render("StockRequestKanban.Buttons")); + $buttonScan.on("click", this._onOpenWizard.bind(this)); + + $buttonScan.prependTo($node.find(".o_list_buttons")); + }, + + // ------------------------------------------------------------------------- + // Handlers + // ------------------------------------------------------------------------- + + _onOpenWizard: function() { + var context = { + active_model: this.modelName, + }; + this.do_action({ + res_model: "wizard.stock.request.kanban", + views: [[false, "form"]], + target: "new", + type: "ir.actions.act_window", + context: context, + }); + }, + }); + + return StockRequestKanbanController; +}); diff --git a/stock_request_kanban/static/src/js/stock_request_kanban_scan_view.js b/stock_request_kanban/static/src/js/stock_request_kanban_scan_view.js new file mode 100644 index 000000000..349d786d8 --- /dev/null +++ b/stock_request_kanban/static/src/js/stock_request_kanban_scan_view.js @@ -0,0 +1,17 @@ +odoo.define("stock_request_kanban.StockRequestKanbanListView", function(require) { + "use strict"; + + var ListView = require("web.ListView"); + var StockRequestKanbanController = require("stock_request_kanban.StockRequestKanbanController"); + var viewRegistry = require("web.view_registry"); + + var StockRequestKanbanListView = ListView.extend({ + config: _.extend({}, ListView.prototype.config, { + Controller: StockRequestKanbanController, + }), + }); + + viewRegistry.add("stock_request_kanban_list", StockRequestKanbanListView); + + return StockRequestKanbanListView; +}); diff --git a/stock_request_kanban/static/src/xml/stock_request_kanban_scan.xml b/stock_request_kanban/static/src/xml/stock_request_kanban_scan.xml new file mode 100644 index 000000000..9588c1027 --- /dev/null +++ b/stock_request_kanban/static/src/xml/stock_request_kanban_scan.xml @@ -0,0 +1,6 @@ + + + + diff --git a/stock_request_kanban/tests/base_test.py b/stock_request_kanban/tests/base_test.py index ff529bde3..41e9b13d7 100644 --- a/stock_request_kanban/tests/base_test.py +++ b/stock_request_kanban/tests/base_test.py @@ -1,16 +1,17 @@ # Copyright 2017 Creu Blanca -# Copyright 2017 Eficent Business and IT Consulting Services, S.L. +# Copyright 2017-2020 ForgeFlow, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). -from odoo.tests.common import TransactionCase from reportlab.graphics.barcode import getCodes +from odoo.tests.common import TransactionCase + class TestBaseKanban(TransactionCase): - def pass_code(self, wizard, code): - bcc = getCodes()[ - self.env['stock.request.kanban'].get_barcode_format()](value=code) + bcc = getCodes()[self.env["stock.request.kanban"].get_barcode_format()]( + value=code + ) bcc.validate() bcc.encode() wizard.on_barcode_scanned(bcc.encoded[1:-1]) diff --git a/stock_request_kanban/tests/test_inventory_kanban.py b/stock_request_kanban/tests/test_inventory_kanban.py index e5d41be2f..1e0eab7cd 100644 --- a/stock_request_kanban/tests/test_inventory_kanban.py +++ b/stock_request_kanban/tests/test_inventory_kanban.py @@ -1,5 +1,5 @@ # Copyright 2017 Creu Blanca -# Copyright 2017 Eficent Business and IT Consulting Services, S.L. +# Copyright 2017-2020 ForgeFlow, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). from .base_test import TestBaseKanban @@ -8,68 +8,78 @@ from .base_test import TestBaseKanban class TestKanban(TestBaseKanban): def setUp(self): super().setUp() - self.main_company = self.env.ref('base.main_company') - 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.product = self.env['product.product'].create({ - 'name': 'Product', - 'route_ids': [(4, self.route.id)], - 'company_id': False, - }) - self.product_2 = self.env['product.product'].create({ - 'name': 'Product 2', - 'route_ids': [(4, self.route.id)], - 'company_id': False, - }) - self.kanban_1 = self.env['stock.request.kanban'].create({ - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - }) - self.kanban_2 = self.env['stock.request.kanban'].create({ - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - }) - self.kanban_3 = self.env['stock.request.kanban'].create({ - 'product_id': self.product_2.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - }) + self.main_company = self.env.ref("base.main_company") + 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.product = self.env["product.product"].create( + {"name": "Product", "route_ids": [(4, self.route.id)], "company_id": False} + ) + self.product_2 = self.env["product.product"].create( + { + "name": "Product 2", + "route_ids": [(4, self.route.id)], + "company_id": False, + } + ) + self.kanban_1 = self.env["stock.request.kanban"].create( + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + } + ) + self.kanban_2 = self.env["stock.request.kanban"].create( + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + } + ) + self.kanban_3 = self.env["stock.request.kanban"].create( + { + "product_id": self.product_2.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + } + ) def test_inventory_warehouse(self): - inventory = self.env['stock.inventory.kanban'].create({ - 'warehouse_ids': [(4, self.kanban_1.warehouse_id.id)], - }) + inventory = self.env["stock.inventory.kanban"].create( + {"warehouse_ids": [(4, self.kanban_1.warehouse_id.id)]} + ) inventory.start_inventory() self.assertIn(self.kanban_1, inventory.kanban_ids) self.assertIn(self.kanban_1, inventory.missing_kanban_ids) def test_inventory_location(self): - inventory = self.env['stock.inventory.kanban'].create({ - 'location_ids': [(4, self.kanban_1.location_id.id)], - }) + inventory = self.env["stock.inventory.kanban"].create( + {"location_ids": [(4, self.kanban_1.location_id.id)]} + ) inventory.start_inventory() self.assertIn(self.kanban_1, inventory.kanban_ids) self.assertIn(self.kanban_1, inventory.missing_kanban_ids) def test_inventory_product(self): - inventory = self.env['stock.inventory.kanban'].create({ - 'product_ids': [(4, self.product.id)], - }) + inventory = self.env["stock.inventory.kanban"].create( + {"product_ids": [(4, self.product.id)]} + ) inventory.start_inventory() self.assertIn(self.kanban_1, inventory.kanban_ids) self.assertNotIn(self.kanban_3, inventory.kanban_ids) self.assertIn(self.kanban_1, inventory.missing_kanban_ids) - self.assertEqual(inventory.state, 'in_progress') - wizard = self.env['wizard.stock.inventory.kanban'].with_context( - default_inventory_kanban_id=inventory.id - ).create({}) + self.assertEqual(inventory.state, "in_progress") + wizard = ( + self.env["wizard.stock.inventory.kanban"] + .with_context(default_inventory_kanban_id=inventory.id) + .create({}) + ) self.pass_code(wizard, self.kanban_3.name) self.assertEqual(wizard.status_state, 1) self.pass_code(wizard, self.kanban_1.name) @@ -81,22 +91,22 @@ class TestKanban(TestBaseKanban): self.assertNotIn(self.kanban_1, inventory.missing_kanban_ids) self.assertIn(self.kanban_1, inventory.scanned_kanban_ids) inventory.finish_inventory() - self.assertEqual(inventory.state, 'finished') + self.assertEqual(inventory.state, "finished") inventory.close_inventory() - self.assertEqual(inventory.state, 'closed') + self.assertEqual(inventory.state, "closed") def test_cancel_inventory(self): - inventory = self.env['stock.inventory.kanban'].create({ - 'product_ids': [(4, self.product.id)], - }) + inventory = self.env["stock.inventory.kanban"].create( + {"product_ids": [(4, self.product.id)]} + ) inventory.start_inventory() self.assertIn(self.kanban_1, inventory.kanban_ids) self.assertNotIn(self.kanban_3, inventory.kanban_ids) self.assertIn(self.kanban_1, inventory.missing_kanban_ids) - self.assertEqual(inventory.state, 'in_progress') + self.assertEqual(inventory.state, "in_progress") inventory.cancel() - self.assertEqual(inventory.state, 'cancelled') + self.assertEqual(inventory.state, "cancelled") inventory.to_draft() - self.assertEqual(inventory.state, 'draft') + self.assertEqual(inventory.state, "draft") self.assertFalse(inventory.kanban_ids) self.assertFalse(inventory.scanned_kanban_ids) diff --git a/stock_request_kanban/tests/test_kanban.py b/stock_request_kanban/tests/test_kanban.py index 5c28639f0..1e59ed68c 100644 --- a/stock_request_kanban/tests/test_kanban.py +++ b/stock_request_kanban/tests/test_kanban.py @@ -1,71 +1,74 @@ # Copyright 2017 Creu Blanca -# Copyright 2017 Eficent Business and IT Consulting Services, S.L. +# Copyright 2017-2020 ForgeFlow, S.L. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). from odoo.exceptions import ValidationError + from .base_test import TestBaseKanban class TestKanban(TestBaseKanban): - def setUp(self): super().setUp() - 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.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") # common data - self.company_2 = self.env['res.company'].create({ - 'name': 'Comp2', - }) - self.wh2 = self.env['stock.warehouse'].search( - [('company_id', '=', self.company_2.id)], limit=1) - self.wh3 = self.env['stock.warehouse'].create({ - 'name': 'Warehouse TEst', - 'code': 'WH-TEST', - 'company_id': self.main_company.id, - }) + self.company_2 = self.env["res.company"].create({"name": "Comp2"}) + self.wh2 = self.env["stock.warehouse"].search( + [("company_id", "=", self.company_2.id)], limit=1 + ) + self.wh3 = self.env["stock.warehouse"].create( + { + "name": "Warehouse TEst", + "code": "WH-TEST", + "company_id": self.main_company.id, + } + ) - self.ressuply_loc = self.env['stock.location'].create({ - 'name': 'Ressuply', - 'location_id': self.warehouse.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.product = self.env['product.product'].create({ - 'name': 'Product', - 'route_ids': [(4, self.route.id)], - 'company_id': False, - }) - 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.ressuply_loc = self.env["stock.location"].create( + {"name": "Ressuply", "location_id": self.warehouse.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.product = self.env["product.product"].create( + {"name": "Product", "route_ids": [(4, self.route.id)], "company_id": False} + ) + 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_push', - '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['ir.config_parameter'].set_param( - 'stock_request_kanban.crc', '1') + 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_push", + "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, + } + ) + self.env["ir.config_parameter"].set_param("stock_request_kanban.crc", "1") def test_onchanges(self): - kanban = self.env['stock.request.kanban'].new({}) + kanban = self.env["stock.request.kanban"].new({}) kanban.product_id = self.product kanban.onchange_product_id() kanban.company_id = self.main_company @@ -80,7 +83,7 @@ class TestKanban(TestBaseKanban): self.assertEqual(kanban.warehouse_id, self.warehouse) def test_create(self): - kanban = self.env['stock.request.kanban'].new({}) + kanban = self.env["stock.request.kanban"].new({}) kanban.product_id = self.product kanban.onchange_product_id() kanban.product_uom_qty = 1 @@ -89,95 +92,109 @@ class TestKanban(TestBaseKanban): self.assertEqual(kanban.route_ids, self.route) def test_order_barcodes(self): - kanban_1 = self.env['stock.request.kanban'].create({ - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - }) - kanban_2 = self.env['stock.request.kanban'].create({ - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - }) - kanban_3 = self.env['stock.request.kanban'].create({ - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - 'company_id': self.main_company.id, - 'warehouse_id': self.wh3.id, - 'location_id': self.wh3.lot_stock_id.id, - }) - order = self.env['stock.request.order'].create({ - 'company_id': self.main_company.id, - 'warehouse_id': self.warehouse.id, - 'location_id': self.warehouse.lot_stock_id.id, - }) - wizard = self.env['wizard.stock.request.order.kanban'].with_context( - default_order_id=order.id - ).create({}) + kanban_1 = self.env["stock.request.kanban"].create( + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + } + ) + kanban_2 = self.env["stock.request.kanban"].create( + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + } + ) + kanban_3 = self.env["stock.request.kanban"].create( + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + "company_id": self.main_company.id, + "warehouse_id": self.wh3.id, + "location_id": self.wh3.lot_stock_id.id, + } + ) + order = self.env["stock.request.order"].create( + { + "company_id": self.main_company.id, + "warehouse_id": self.warehouse.id, + "location_id": self.warehouse.lot_stock_id.id, + } + ) + wizard = ( + self.env["wizard.stock.request.order.kanban"] + .with_context(default_order_id=order.id) + .create({}) + ) with self.assertRaises(ValidationError): wizard.on_barcode_scanned(kanban_1.name) self.pass_code(wizard, kanban_1.name) self.assertEqual(wizard.status_state, 0) - self.assertTrue(order.stock_request_ids.filtered( - lambda r: r.kanban_id == kanban_1 - )) + self.assertTrue( + order.stock_request_ids.filtered(lambda r: r.kanban_id == kanban_1) + ) self.pass_code(wizard, kanban_2.name) - self.assertTrue(order.stock_request_ids.filtered( - lambda r: r.kanban_id == kanban_2 - )) + self.assertTrue( + order.stock_request_ids.filtered(lambda r: r.kanban_id == kanban_2) + ) self.assertEqual(wizard.status_state, 0) self.pass_code(wizard, kanban_1.name) self.assertEqual(wizard.status_state, 1) - self.pass_code(wizard, kanban_2.name+kanban_1.name) + self.pass_code(wizard, kanban_2.name + kanban_1.name) self.assertEqual(wizard.status_state, 1) with self.assertRaises(ValidationError): self.pass_code(wizard, kanban_3.name) def test_barcodes(self): - kanban_1 = self.env['stock.request.kanban'].create({ - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - }) - kanban_2 = self.env['stock.request.kanban'].create({ - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - }) - kanban_3 = self.env['stock.request.kanban'].create({ - 'product_id': self.product.id, - 'product_uom_id': self.product.uom_id.id, - 'product_uom_qty': 1, - }) - wizard = self.env['wizard.stock.request.kanban'].with_context( - ).create({}) + kanban_1 = self.env["stock.request.kanban"].create( + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + } + ) + kanban_2 = self.env["stock.request.kanban"].create( + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + } + ) + kanban_3 = self.env["stock.request.kanban"].create( + { + "product_id": self.product.id, + "product_uom_id": self.product.uom_id.id, + "product_uom_qty": 1, + } + ) + wizard = self.env["wizard.stock.request.kanban"].with_context().create({}) with self.assertRaises(ValidationError): wizard.on_barcode_scanned(kanban_1.name) - self.assertFalse(self.env['stock.request'].search( - [('kanban_id', '=', kanban_1.id)]) + self.assertFalse( + self.env["stock.request"].search([("kanban_id", "=", kanban_1.id)]) ) self.pass_code(wizard, kanban_1.name) self.assertEqual(wizard.status_state, 0) - self.assertTrue(self.env['stock.request'].search( - [('kanban_id', '=', kanban_1.id)]) + self.assertTrue( + self.env["stock.request"].search([("kanban_id", "=", kanban_1.id)]) ) - self.assertFalse(self.env['stock.request'].search( - [('kanban_id', '=', kanban_2.id)]) + self.assertFalse( + self.env["stock.request"].search([("kanban_id", "=", kanban_2.id)]) ) self.pass_code(wizard, kanban_2.name) - self.assertTrue(self.env['stock.request'].search( - [('kanban_id', '=', kanban_2.id)]) + self.assertTrue( + self.env["stock.request"].search([("kanban_id", "=", kanban_2.id)]) ) with self.assertRaises(ValidationError): wizard.on_barcode_scanned(kanban_3.name) - self.assertFalse(self.env['stock.request'].search( - [('kanban_id', '=', kanban_3.id)]) + self.assertFalse( + self.env["stock.request"].search([("kanban_id", "=", kanban_3.id)]) ) - self.env['ir.config_parameter'].set_param( - 'stock_request_kanban.crc', '0') + self.env["ir.config_parameter"].set_param("stock_request_kanban.crc", "0") wizard.on_barcode_scanned(kanban_3.name) self.assertEqual(wizard.status_state, 0) - self.assertTrue(self.env['stock.request'].search( - [('kanban_id', '=', kanban_3.id)]) + self.assertTrue( + self.env["stock.request"].search([("kanban_id", "=", kanban_3.id)]) ) diff --git a/stock_request_kanban/views/product_views.xml b/stock_request_kanban/views/product_views.xml new file mode 100644 index 000000000..fad8699d5 --- /dev/null +++ b/stock_request_kanban/views/product_views.xml @@ -0,0 +1,57 @@ + + + + + product.product.stock.request.kanban + product.product + + + +
+ +
+
+
+ + product.template.stock.request.kanban + product.template + + + +
+ +
+
+
+
diff --git a/stock_request_kanban/views/stock_inventory_kanban_views.xml b/stock_request_kanban/views/stock_inventory_kanban_views.xml index 6833dbc1c..ec5239838 100644 --- a/stock_request_kanban/views/stock_inventory_kanban_views.xml +++ b/stock_request_kanban/views/stock_inventory_kanban_views.xml @@ -1,97 +1,122 @@ - stock.inventory.kanban.tree stock.inventory.kanban - - - + + + - stock.inventory.kanban.form stock.inventory.kanban
-
-
- - - + + + - + - + - +
- - - + + +
- Stock Inventory Kanbans stock.inventory.kanban ir.actions.act_window - form tree,form -

+

Click to add a Stock Inventory Kanban.

-
diff --git a/stock_request_kanban/views/stock_request_kanban_views.xml b/stock_request_kanban/views/stock_request_kanban_views.xml index b2e122558..5b980b3b6 100644 --- a/stock_request_kanban/views/stock_request_kanban_views.xml +++ b/stock_request_kanban/views/stock_request_kanban_views.xml @@ -1,145 +1,198 @@ - - + + - stock.request.kanban.tree stock.request.kanban - - - - - - - - - - + + + + + + + + + + - stock.request.kanban.search stock.request.kanban - - - - - - + + + + + + - - + + - stock.request.kanban.form stock.request.kanban
-
+
-
+
- + - - - - - - + + + + + + -
- - - + + +
- - - stock.request.kanban.kanban - stock.request.kanban - - - - - - - - - - - -
- -
- Kanban Image -
-
- -
-
    -
  • -
  • -
  • -
  • -
-
+ + stock.request.kanban.kanban + stock.request.kanban + + + + + + + + + + + +
+
+ Kanban Image
- - - - - - - +
+ + + +
+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + + +
  • +
+
+
+ + + + + Stock Request Kanbans stock.request.kanban ir.actions.act_window - form kanban,tree,form -

+

Click to add a Stock Request Kanban.

- diff --git a/stock_request_kanban/views/stock_request_menu.xml b/stock_request_kanban/views/stock_request_menu.xml index 6b89f0e93..8f9150392 100644 --- a/stock_request_kanban/views/stock_request_menu.xml +++ b/stock_request_kanban/views/stock_request_menu.xml @@ -1,22 +1,25 @@ - - - - - - + + + diff --git a/stock_request_kanban/views/stock_request_order_views.xml b/stock_request_kanban/views/stock_request_order_views.xml index d830b6c75..cc7b55200 100644 --- a/stock_request_kanban/views/stock_request_order_views.xml +++ b/stock_request_kanban/views/stock_request_order_views.xml @@ -1,21 +1,20 @@ - stock.request.order.form stock.request.order - + -