From ab354499332592061ed4882825b683e3d9072347 Mon Sep 17 00:00:00 2001 From: Francois Poizat Date: Wed, 6 Dec 2023 17:12:20 +0100 Subject: [PATCH 01/12] wms_connector: ADD inventory import support --- wms_connector/models/attachment_queue.py | 7 +++++++ .../models/attachment_synchronize_task.py | 9 +++++++++ wms_connector/models/stock_warehouse.py | 14 ++++++++++++++ wms_connector/views/stock_warehouse.xml | 2 ++ 4 files changed, 32 insertions(+) diff --git a/wms_connector/models/attachment_queue.py b/wms_connector/models/attachment_queue.py index 5293e468e5e..15f966d99a4 100644 --- a/wms_connector/models/attachment_queue.py +++ b/wms_connector/models/attachment_queue.py @@ -6,6 +6,7 @@ WMS_IMPORT_FILETYPES = [ ("wms_reception_confirmed", "WMS Reception confirmed"), ("wms_delivery_confirmed", "WMS Delivery confirmed"), + ("wms_update_inventory", "WMS inventory update"), ] @@ -13,6 +14,9 @@ class AttachmentQueue(models.Model): _inherit = "attachment.queue" file_type = fields.Selection(selection_add=WMS_IMPORT_FILETYPES) + # This seems fishy but we need the warehouse id to allow + # for update inventory + default_warehouse_id = fields.Many2one("stock.warehouse") def _run(self): for filetype in [el[0] for el in WMS_IMPORT_FILETYPES]: @@ -25,3 +29,6 @@ def _run_wms_reception_confirmed(self): def _run_wms_delivery_confirmed(self): raise NotImplementedError + + def _run_wms_update_inventory(self): + raise NotImplementedError diff --git a/wms_connector/models/attachment_synchronize_task.py b/wms_connector/models/attachment_synchronize_task.py index b1263521671..db252a943ef 100644 --- a/wms_connector/models/attachment_synchronize_task.py +++ b/wms_connector/models/attachment_synchronize_task.py @@ -7,10 +7,19 @@ class AttachmentSynchronizeTask(models.Model): _inherit = "attachment.synchronize.task" + default_warehouse_id = fields.Many2one("stock.warehouse") + file_type = fields.Selection( selection_add=[ ("export", "Export"), ("wms_reception_confirmed", "Reception confirmed"), ("wms_delivery_confirmed", "Delivery confirmed"), + ("wms_update_inventory", "Inventory update"), ] ) + + def _prepare_attachment_vals(self, data, filename): + self.ensure_one() + vals = super()._prepare_attachment_vals(data, filename) + vals["default_warehouse_id"] = self.default_warehouse_id.id + return vals diff --git a/wms_connector/models/stock_warehouse.py b/wms_connector/models/stock_warehouse.py index 54f56dd4af0..394098a3068 100644 --- a/wms_connector/models/stock_warehouse.py +++ b/wms_connector/models/stock_warehouse.py @@ -80,6 +80,15 @@ "name_fragment": "delivery confirmation", "code": "env['stock.warehouse'].browse({}).{}.run_import()", }, + "inventory": { + "fieldname_task": "wms_import_update_inventory_task_id", + "fieldname_cron": "wms_import_update_inventory_cron_id", + "filetype": "wms_update_inventory", + "method_type": "import", + "filepath": "OUT/", + "name_fragment": "Update inventory", + "code": "env['stock.warehouse'].browse({}).{}.run_import()", + }, } @@ -96,11 +105,15 @@ class StockWarehouse(models.Model): wms_import_confirm_delivery_task_id = fields.Many2one( "attachment.synchronize.task", readonly=True ) + wms_import_update_inventory_task_id = fields.Many2one( + "attachment.synchronize.task", readonly=True + ) wms_export_product_cron_id = fields.Many2one("ir.cron", readonly=True) wms_export_picking_in_cron_id = fields.Many2one("ir.cron", readonly=True) wms_export_picking_out_cron_id = fields.Many2one("ir.cron", readonly=True) wms_import_confirm_reception_cron_id = fields.Many2one("ir.cron", readonly=True) wms_import_confirm_delivery_cron_id = fields.Many2one("ir.cron", readonly=True) + wms_import_update_inventory_cron_id = fields.Many2one("ir.cron", readonly=True) wms_export_product_filter_id = fields.Many2one("ir.filters") wms_export_picking_in_filter_id = fields.Many2one("ir.filters") wms_export_picking_out_filter_id = fields.Many2one("ir.filters") @@ -187,6 +200,7 @@ def _prepare_wms_task_vals( "filepath": filepath, "backend_id": self.env.ref("storage_backend.default_storage_backend").id, "file_type": filetype, + "default_warehouse_id": self.id, } def _prepare_wms_cron_vals(self, code="", name_fragment=""): diff --git a/wms_connector/views/stock_warehouse.xml b/wms_connector/views/stock_warehouse.xml index 61f547f9d49..f106eaab273 100644 --- a/wms_connector/views/stock_warehouse.xml +++ b/wms_connector/views/stock_warehouse.xml @@ -46,6 +46,7 @@ + @@ -53,6 +54,7 @@ + From fd36a2d9fe30c54886a7da2a9d6fd5dbfed636c2 Mon Sep 17 00:00:00 2001 From: Francois Poizat Date: Thu, 7 Dec 2023 16:04:24 +0100 Subject: [PATCH 02/12] wms_connector: compute default_warehouse_id for inventory in a simpler way --- wms_connector/models/attachment_queue.py | 21 ++++++++++++++++--- .../models/attachment_synchronize_task.py | 8 ------- wms_connector/models/stock_warehouse.py | 1 - 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/wms_connector/models/attachment_queue.py b/wms_connector/models/attachment_queue.py index 15f966d99a4..bdbf42a23cb 100644 --- a/wms_connector/models/attachment_queue.py +++ b/wms_connector/models/attachment_queue.py @@ -14,9 +14,24 @@ class AttachmentQueue(models.Model): _inherit = "attachment.queue" file_type = fields.Selection(selection_add=WMS_IMPORT_FILETYPES) - # This seems fishy but we need the warehouse id to allow - # for update inventory - default_warehouse_id = fields.Many2one("stock.warehouse") + default_warehouse_id = fields.Many2one( + "stock.warehouse", compute="_compute_default_warehouse", store=True + ) + + def _compute_default_warehouse(self): + for rec in self: + task_queue_prefix = None + if rec.file_type == "wms_reception_confirmed": + task_queue_prefix = "wms_import_picking_in" + elif rec.file_type == "wms_delivery_confirmed": + task_queue_prefix = "wms_import_picking_out" + elif rec.file_type == "wms_update_inventory": + task_queue_prefix = "wms_import_update_inventory" + + if task_queue_prefix is not None: + rec.default_warehouse_id = rec.env["stock.warehouse"].search( + [(f"{task_queue_prefix}_task_id.attachment_ids", "=", rec.id)] + ) def _run(self): for filetype in [el[0] for el in WMS_IMPORT_FILETYPES]: diff --git a/wms_connector/models/attachment_synchronize_task.py b/wms_connector/models/attachment_synchronize_task.py index db252a943ef..75470198e90 100644 --- a/wms_connector/models/attachment_synchronize_task.py +++ b/wms_connector/models/attachment_synchronize_task.py @@ -7,8 +7,6 @@ class AttachmentSynchronizeTask(models.Model): _inherit = "attachment.synchronize.task" - default_warehouse_id = fields.Many2one("stock.warehouse") - file_type = fields.Selection( selection_add=[ ("export", "Export"), @@ -17,9 +15,3 @@ class AttachmentSynchronizeTask(models.Model): ("wms_update_inventory", "Inventory update"), ] ) - - def _prepare_attachment_vals(self, data, filename): - self.ensure_one() - vals = super()._prepare_attachment_vals(data, filename) - vals["default_warehouse_id"] = self.default_warehouse_id.id - return vals diff --git a/wms_connector/models/stock_warehouse.py b/wms_connector/models/stock_warehouse.py index 394098a3068..207052dc1ff 100644 --- a/wms_connector/models/stock_warehouse.py +++ b/wms_connector/models/stock_warehouse.py @@ -200,7 +200,6 @@ def _prepare_wms_task_vals( "filepath": filepath, "backend_id": self.env.ref("storage_backend.default_storage_backend").id, "file_type": filetype, - "default_warehouse_id": self.id, } def _prepare_wms_cron_vals(self, code="", name_fragment=""): From 94d470466379577091071c58d8b88b4ef0652da5 Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Mon, 30 Oct 2023 09:34:35 +0200 Subject: [PATCH 03/12] wip --- wms_connector/models/synchronize_exportable_mixin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wms_connector/models/synchronize_exportable_mixin.py b/wms_connector/models/synchronize_exportable_mixin.py index cf409e251e1..a32b2051b47 100644 --- a/wms_connector/models/synchronize_exportable_mixin.py +++ b/wms_connector/models/synchronize_exportable_mixin.py @@ -104,4 +104,4 @@ def _schedule_export(self, warehouse, domain=False): recs = self.search(domain) if not recs: return - recs.with_context(warehouse=warehouse).synchronize_export() + return recs.with_context(warehouse=warehouse).synchronize_export() From 37ee95a9602a462a58ae2a77dbbee4fce2fe713c Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Mon, 30 Oct 2023 10:54:44 +0200 Subject: [PATCH 04/12] add api model --- wms_connector/models/synchronize_exportable_mixin.py | 3 ++- wms_connector/models/wms_product_sync.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/wms_connector/models/synchronize_exportable_mixin.py b/wms_connector/models/synchronize_exportable_mixin.py index a32b2051b47..cb69fa3e1b9 100644 --- a/wms_connector/models/synchronize_exportable_mixin.py +++ b/wms_connector/models/synchronize_exportable_mixin.py @@ -6,7 +6,7 @@ import datetime from io import StringIO -from odoo import fields, models +from odoo import api, fields, models from odoo.tools import config @@ -98,6 +98,7 @@ def _format_to_exportfile_csv(self, data): def _get_export_name(self): raise NotImplementedError + @api.model def _schedule_export(self, warehouse, domain=False): if not domain: domain = [] diff --git a/wms_connector/models/wms_product_sync.py b/wms_connector/models/wms_product_sync.py index cc9bef3b5f8..9264c528e8c 100644 --- a/wms_connector/models/wms_product_sync.py +++ b/wms_connector/models/wms_product_sync.py @@ -23,6 +23,7 @@ def _compute_to_export(self): for record in self: record.to_export = True + @api.model def _schedule_export(self, warehouse, domain=False): warehouse.refresh_wms_products() return super()._schedule_export(warehouse, domain) From 153830d23b37c797bccac284f37e387879a7c9c7 Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Wed, 8 Nov 2023 17:21:12 +0200 Subject: [PATCH 05/12] minor imp --- wms_connector/models/synchronize_exportable_mixin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wms_connector/models/synchronize_exportable_mixin.py b/wms_connector/models/synchronize_exportable_mixin.py index cb69fa3e1b9..8598dbff3fa 100644 --- a/wms_connector/models/synchronize_exportable_mixin.py +++ b/wms_connector/models/synchronize_exportable_mixin.py @@ -104,5 +104,5 @@ def _schedule_export(self, warehouse, domain=False): domain = [] recs = self.search(domain) if not recs: - return + return self.env["attachment.queue"] return recs.with_context(warehouse=warehouse).synchronize_export() From 3f065f88c2eb7c71b68bb0ce57997e9ad0d4e149 Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Tue, 9 Jan 2024 08:20:28 +0200 Subject: [PATCH 06/12] revert unnecessary changes --- wms_connector/models/synchronize_exportable_mixin.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wms_connector/models/synchronize_exportable_mixin.py b/wms_connector/models/synchronize_exportable_mixin.py index 8598dbff3fa..731c5555f45 100644 --- a/wms_connector/models/synchronize_exportable_mixin.py +++ b/wms_connector/models/synchronize_exportable_mixin.py @@ -73,10 +73,15 @@ def _get_wms_export_task(self): raise NotImplementedError # TODO cleanup this code +<<<<<<< HEAD # We should just have a method that return the data # and a generic one that return the vals def _format_to_exportfile(self, name, data): return self._format_to_exportfile_csv(name, data) +======= + def _format_to_exportfile(self, data): + return self._format_to_exportfile_csv(data) +>>>>>>> a7bdc61d (revert unnecessary changes) def _format_to_exportfile_csv(self, data): csv_file = StringIO() From 7f8cad733dffc70f817da9862efbe543b873d2fd Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Tue, 9 Jan 2024 08:29:24 +0200 Subject: [PATCH 07/12] use fs_storage --- wms_connector/__manifest__.py | 2 +- wms_connector/demo/{storage_backend.xml => fs_storage.xml} | 5 +++-- wms_connector/models/stock_warehouse.py | 2 +- wms_connector/tests/common.py | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) rename wms_connector/demo/{storage_backend.xml => fs_storage.xml} (59%) diff --git a/wms_connector/__manifest__.py b/wms_connector/__manifest__.py index 8cb405b8912..9e98ded6e97 100644 --- a/wms_connector/__manifest__.py +++ b/wms_connector/__manifest__.py @@ -17,6 +17,6 @@ "views/stock_warehouse.xml", ], "demo": [ - "demo/storage_backend.xml", + "demo/fs_storage.xml", ], } diff --git a/wms_connector/demo/storage_backend.xml b/wms_connector/demo/fs_storage.xml similarity index 59% rename from wms_connector/demo/storage_backend.xml rename to wms_connector/demo/fs_storage.xml index 265fa10a05f..55804823e0b 100644 --- a/wms_connector/demo/storage_backend.xml +++ b/wms_connector/demo/fs_storage.xml @@ -3,9 +3,10 @@ License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> - + Demo WMS backend - / + odoofs + demo_wms_storage diff --git a/wms_connector/models/stock_warehouse.py b/wms_connector/models/stock_warehouse.py index 207052dc1ff..16ebb232d69 100644 --- a/wms_connector/models/stock_warehouse.py +++ b/wms_connector/models/stock_warehouse.py @@ -198,7 +198,7 @@ def _prepare_wms_task_vals( "name": "WMS task for {} {}".format(self.name, name_fragment), "method_type": method_type, "filepath": filepath, - "backend_id": self.env.ref("storage_backend.default_storage_backend").id, + "backend_id": self.env.ref("fs_storage.default_fs_storage").id, "file_type": filetype, } diff --git a/wms_connector/tests/common.py b/wms_connector/tests/common.py index 4428dd60c4e..19d083eadbc 100644 --- a/wms_connector/tests/common.py +++ b/wms_connector/tests/common.py @@ -17,7 +17,7 @@ def setUp(self): @classmethod def setUpClass(cls): super().setUpClass() - cls.backend = cls.env.ref("wms_connector.demo_wms_backend") + cls.backend = cls.env.ref("wms_connector.demo_wms_storage") cls.backend.directory_path = str(uuid.uuid1()) + "/" cls.aq_before = cls.env["attachment.queue"].search([]) cls.warehouse = cls.env.ref("stock.warehouse0") From 2774d83e88029de5d6845a1cc3496c2ccc2fe948 Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Tue, 9 Jan 2024 09:50:20 +0200 Subject: [PATCH 08/12] change prefixes on task queues --- wms_connector/models/attachment_queue.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wms_connector/models/attachment_queue.py b/wms_connector/models/attachment_queue.py index bdbf42a23cb..ca9facff0cb 100644 --- a/wms_connector/models/attachment_queue.py +++ b/wms_connector/models/attachment_queue.py @@ -22,9 +22,9 @@ def _compute_default_warehouse(self): for rec in self: task_queue_prefix = None if rec.file_type == "wms_reception_confirmed": - task_queue_prefix = "wms_import_picking_in" + task_queue_prefix = "wms_import_confirm_reception" elif rec.file_type == "wms_delivery_confirmed": - task_queue_prefix = "wms_import_picking_out" + task_queue_prefix = "wms_import_confirm_delivery" elif rec.file_type == "wms_update_inventory": task_queue_prefix = "wms_import_update_inventory" From 7df68b83cecb439b485e288d0e5a773c9e015005 Mon Sep 17 00:00:00 2001 From: Francois Poizat Date: Wed, 6 Dec 2023 17:12:20 +0100 Subject: [PATCH 09/12] wms_connector: ADD inventory import support --- wms_connector/models/attachment_synchronize_task.py | 8 ++++++++ wms_connector/models/stock_warehouse.py | 1 + 2 files changed, 9 insertions(+) diff --git a/wms_connector/models/attachment_synchronize_task.py b/wms_connector/models/attachment_synchronize_task.py index 75470198e90..db252a943ef 100644 --- a/wms_connector/models/attachment_synchronize_task.py +++ b/wms_connector/models/attachment_synchronize_task.py @@ -7,6 +7,8 @@ class AttachmentSynchronizeTask(models.Model): _inherit = "attachment.synchronize.task" + default_warehouse_id = fields.Many2one("stock.warehouse") + file_type = fields.Selection( selection_add=[ ("export", "Export"), @@ -15,3 +17,9 @@ class AttachmentSynchronizeTask(models.Model): ("wms_update_inventory", "Inventory update"), ] ) + + def _prepare_attachment_vals(self, data, filename): + self.ensure_one() + vals = super()._prepare_attachment_vals(data, filename) + vals["default_warehouse_id"] = self.default_warehouse_id.id + return vals diff --git a/wms_connector/models/stock_warehouse.py b/wms_connector/models/stock_warehouse.py index 16ebb232d69..e45d177c712 100644 --- a/wms_connector/models/stock_warehouse.py +++ b/wms_connector/models/stock_warehouse.py @@ -200,6 +200,7 @@ def _prepare_wms_task_vals( "filepath": filepath, "backend_id": self.env.ref("fs_storage.default_fs_storage").id, "file_type": filetype, + "default_warehouse_id": self.id, } def _prepare_wms_cron_vals(self, code="", name_fragment=""): From 38780d3a76c9f59bdcd8848132f9c73c3a8adf8c Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Tue, 9 Jan 2024 10:08:15 +0200 Subject: [PATCH 10/12] fix error --- wms_connector/models/synchronize_exportable_mixin.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/wms_connector/models/synchronize_exportable_mixin.py b/wms_connector/models/synchronize_exportable_mixin.py index 731c5555f45..24c1dc2ae8e 100644 --- a/wms_connector/models/synchronize_exportable_mixin.py +++ b/wms_connector/models/synchronize_exportable_mixin.py @@ -73,15 +73,10 @@ def _get_wms_export_task(self): raise NotImplementedError # TODO cleanup this code -<<<<<<< HEAD # We should just have a method that return the data # and a generic one that return the vals - def _format_to_exportfile(self, name, data): - return self._format_to_exportfile_csv(name, data) -======= def _format_to_exportfile(self, data): return self._format_to_exportfile_csv(data) ->>>>>>> a7bdc61d (revert unnecessary changes) def _format_to_exportfile_csv(self, data): csv_file = StringIO() From 571ffca6925936f5e39024af3b3a3c4b728a6ee4 Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Thu, 11 Jan 2024 10:48:27 +0200 Subject: [PATCH 11/12] remove default backend --- wms_connector/models/stock_warehouse.py | 1 - 1 file changed, 1 deletion(-) diff --git a/wms_connector/models/stock_warehouse.py b/wms_connector/models/stock_warehouse.py index e45d177c712..e2cbf4e14a9 100644 --- a/wms_connector/models/stock_warehouse.py +++ b/wms_connector/models/stock_warehouse.py @@ -198,7 +198,6 @@ def _prepare_wms_task_vals( "name": "WMS task for {} {}".format(self.name, name_fragment), "method_type": method_type, "filepath": filepath, - "backend_id": self.env.ref("fs_storage.default_fs_storage").id, "file_type": filetype, "default_warehouse_id": self.id, } From 833995576fdc1d009cc0a7c7767c921d4a6530d9 Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Mon, 15 Jan 2024 13:34:31 +0200 Subject: [PATCH 12/12] fix formatting to export file in case of multiple records --- wms_connector/models/synchronize_exportable_mixin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wms_connector/models/synchronize_exportable_mixin.py b/wms_connector/models/synchronize_exportable_mixin.py index 24c1dc2ae8e..e7b892af61c 100644 --- a/wms_connector/models/synchronize_exportable_mixin.py +++ b/wms_connector/models/synchronize_exportable_mixin.py @@ -56,7 +56,7 @@ def _get_export_data(self, raise_error=False): def synchronize_export(self, raise_error=False): attachments = self.env["attachment.queue"] for records, data in self._get_export_data(raise_error=raise_error): - vals = self._format_to_exportfile(data) + vals = records._format_to_exportfile(data) attachment = self.env["attachment.queue"].create(vals) records.track_export(attachment) attachments |= attachment