From d2555605718b455ab0b0e8c44baca7966bf8cfce Mon Sep 17 00:00:00 2001 From: SButko Date: Tue, 22 Sep 2020 18:04:58 +0300 Subject: [PATCH] [REF] sale_automatic_workflow|_stock: separate There is an issue for service companies that do not need the stock module to be installed when using `sale_automatic_workflow`. Module depended on `stock`, therefore it was auto installed. Now, stock related part is moved to a separate module - `sale_automatic_workflow_stock` and can be installed separately. --- sale_automatic_workflow/README.rst | 1 + sale_automatic_workflow/__manifest__.py | 6 +- .../data/automatic_workflow_data.xml | 14 - sale_automatic_workflow/models/__init__.py | 2 - .../models/automatic_workflow_job.py | 27 +- sale_automatic_workflow/models/sale_order.py | 35 +- .../models/sale_workflow_process.py | 19 - .../readme/CONTRIBUTORS.md | 1 + .../static/description/index.html | 13 +- sale_automatic_workflow/tests/common.py | 152 +++++- .../tests/test_automatic_workflow.py | 55 +-- .../tests/test_multicompany.py | 142 +----- .../{sale_view.xml => sale_order_views.xml} | 10 - ...ew.xml => sale_workflow_process_views.xml} | 51 -- sale_automatic_workflow_stock/README.rst | 100 ++++ sale_automatic_workflow_stock/__init__.py | 1 + sale_automatic_workflow_stock/__manifest__.py | 23 + .../data/automatic_workflow_data.xml | 33 ++ .../models/__init__.py | 5 + .../models/automatic_workflow_job.py | 48 ++ .../models/sale_order.py | 34 ++ .../models/sale_workflow_process.py | 32 ++ .../models/stock_move.py | 0 .../models/stock_picking.py | 0 sale_automatic_workflow_stock/pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 12 + .../readme/DESCRIPTION.md | 9 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 446 ++++++++++++++++++ .../tests/__init__.py | 2 + sale_automatic_workflow_stock/tests/common.py | 38 ++ .../tests/test_automatic_workflow.py | 104 ++++ .../tests/test_multicompany.py | 95 ++++ .../views/sale_order_views.xml | 18 + .../views/sale_workflow_process_views.xml | 83 ++++ sale_order_type/models/sale.py | 9 +- 36 files changed, 1286 insertions(+), 337 deletions(-) rename sale_automatic_workflow/views/{sale_view.xml => sale_order_views.xml} (64%) rename sale_automatic_workflow/views/{sale_workflow_process_view.xml => sale_workflow_process_views.xml} (85%) create mode 100644 sale_automatic_workflow_stock/README.rst create mode 100644 sale_automatic_workflow_stock/__init__.py create mode 100644 sale_automatic_workflow_stock/__manifest__.py create mode 100644 sale_automatic_workflow_stock/data/automatic_workflow_data.xml create mode 100644 sale_automatic_workflow_stock/models/__init__.py create mode 100644 sale_automatic_workflow_stock/models/automatic_workflow_job.py create mode 100644 sale_automatic_workflow_stock/models/sale_order.py create mode 100644 sale_automatic_workflow_stock/models/sale_workflow_process.py rename {sale_automatic_workflow => sale_automatic_workflow_stock}/models/stock_move.py (100%) rename {sale_automatic_workflow => sale_automatic_workflow_stock}/models/stock_picking.py (100%) create mode 100644 sale_automatic_workflow_stock/pyproject.toml create mode 100644 sale_automatic_workflow_stock/readme/CONTRIBUTORS.md create mode 100644 sale_automatic_workflow_stock/readme/DESCRIPTION.md create mode 100644 sale_automatic_workflow_stock/static/description/icon.png create mode 100644 sale_automatic_workflow_stock/static/description/index.html create mode 100644 sale_automatic_workflow_stock/tests/__init__.py create mode 100644 sale_automatic_workflow_stock/tests/common.py create mode 100644 sale_automatic_workflow_stock/tests/test_automatic_workflow.py create mode 100644 sale_automatic_workflow_stock/tests/test_multicompany.py create mode 100644 sale_automatic_workflow_stock/views/sale_order_views.xml create mode 100644 sale_automatic_workflow_stock/views/sale_workflow_process_views.xml diff --git a/sale_automatic_workflow/README.rst b/sale_automatic_workflow/README.rst index 1f1a89dca286..0d8484ab57d3 100644 --- a/sale_automatic_workflow/README.rst +++ b/sale_automatic_workflow/README.rst @@ -91,6 +91,7 @@ Contributors - Thomas Fossoul - Phuc Tran Thanh - Sander Lienaerts +- Tri Doan Other credits ------------- diff --git a/sale_automatic_workflow/__manifest__.py b/sale_automatic_workflow/__manifest__.py index 40180d2ad729..b240351748ea 100644 --- a/sale_automatic_workflow/__manifest__.py +++ b/sale_automatic_workflow/__manifest__.py @@ -13,11 +13,11 @@ "Sodexis, " "Odoo Community Association (OCA)", "website": "https://github.com/OCA/sale-workflow", - "depends": ["sale_stock", "sales_team"], + "depends": ["sale"], "data": [ "security/ir.model.access.csv", - "views/sale_view.xml", - "views/sale_workflow_process_view.xml", + "views/sale_order_views.xml", + "views/sale_workflow_process_views.xml", "data/automatic_workflow_data.xml", ], "installable": True, diff --git a/sale_automatic_workflow/data/automatic_workflow_data.xml b/sale_automatic_workflow/data/automatic_workflow_data.xml index efa171a447f0..ece7f7aff480 100644 --- a/sale_automatic_workflow/data/automatic_workflow_data.xml +++ b/sale_automatic_workflow/data/automatic_workflow_data.xml @@ -10,14 +10,6 @@ [('state', '=', 'draft')] - - Automatic Workflow Picking Filter - stock.picking - [('state', 'in', ['draft', 'confirmed', 'assigned'])] - - Automatic Workflow Create Invoice Filter sale.order @@ -52,7 +44,6 @@ Automatic - one @@ -67,8 +58,6 @@ eval="automatic_workflow_validate_invoice_filter" /> - - @@ -79,11 +68,9 @@ Manual - one - - diff --git a/sale_automatic_workflow/models/__init__.py b/sale_automatic_workflow/models/__init__.py index cc4d5a8836c5..3e3e944beb50 100644 --- a/sale_automatic_workflow/models/__init__.py +++ b/sale_automatic_workflow/models/__init__.py @@ -2,5 +2,3 @@ from . import automatic_workflow_job from . import sale_order from . import sale_workflow_process -from . import stock_move -from . import stock_picking diff --git a/sale_automatic_workflow/models/automatic_workflow_job.py b/sale_automatic_workflow/models/automatic_workflow_job.py index d514a2963583..e1e30011fdab 100644 --- a/sale_automatic_workflow/models/automatic_workflow_job.py +++ b/sale_automatic_workflow/models/automatic_workflow_job.py @@ -112,24 +112,6 @@ def _validate_invoices(self, validate_invoice_filter): invoice.with_company(invoice.company_id), validate_invoice_filter ) - def _do_validate_picking(self, picking, domain_filter): - """Validate a stock.picking, filter ensure no duplication""" - if not self.env["stock.picking"].search_count( - [("id", "=", picking.id)] + domain_filter - ): - return f"{picking.display_name} {picking} job bypassed" - picking.validate_picking() - return f"{picking.display_name} {picking} validate picking successfully" - - @api.model - def _validate_pickings(self, picking_filter): - picking_obj = self.env["stock.picking"] - pickings = picking_obj.search(picking_filter) - _logger.debug("Pickings to validate: %s", pickings.ids) - for picking in pickings: - with savepoint(self.env.cr): - self._do_validate_picking(picking, picking_filter) - def _do_sale_done(self, sale, domain_filter): """Lock a sales order, filter ensure no duplication""" if not self.env["sale.order"].search_count( @@ -188,6 +170,10 @@ def _register_payment_invoice(self, invoice): [("account_id", "=", account.id), ("reconciled", "=", False)] ).reconcile() + @api.model + def _handle_pickings(self, sale_workflow): + pass + @api.model def run_with_workflow(self, sale_workflow): workflow_domain = [("workflow_process_id", "=", sale_workflow.id)] @@ -197,10 +183,7 @@ def run_with_workflow(self, sale_workflow): )._validate_sale_orders( safe_eval(sale_workflow.order_filter_id.domain) + workflow_domain ) - if sale_workflow.validate_picking: - self._validate_pickings( - safe_eval(sale_workflow.picking_filter_id.domain) + workflow_domain - ) + self._handle_pickings(sale_workflow) if sale_workflow.create_invoice: self._create_invoices( safe_eval(sale_workflow.create_invoice_filter_id.domain) diff --git a/sale_automatic_workflow/models/sale_order.py b/sale_automatic_workflow/models/sale_order.py index 3cbde0662dae..e0b03bc83b92 100644 --- a/sale_automatic_workflow/models/sale_order.py +++ b/sale_automatic_workflow/models/sale_order.py @@ -4,6 +4,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import _, api, fields, models +from odoo.tools import float_compare class SaleOrder(models.Model): @@ -20,10 +21,20 @@ class SaleOrder(models.Model): store=True, ) - @api.depends("delivery_status") + @api.depends("order_line.qty_delivered", "order_line.product_uom_qty") def _compute_all_qty_delivered(self): + precision = self.env["decimal.precision"].precision_get( + "Product Unit of Measure" + ) for order in self: - order.all_qty_delivered = order.delivery_status == "full" + order.all_qty_delivered = all( + line.product_id.type == "service" + or float_compare( + line.qty_delivered, line.product_uom_qty, precision_digits=precision + ) + == 0 + for line in order.order_line + ) def _prepare_invoice(self): invoice_vals = super()._prepare_invoice() @@ -41,17 +52,19 @@ def _prepare_invoice(self): @api.onchange("workflow_process_id") def _onchange_workflow_process_id(self): - if not self.workflow_process_id: - return - workflow = self.workflow_process_id - if workflow.picking_policy: - self.picking_policy = workflow.picking_policy - if workflow.team_id: - self.team_id = workflow.team_id.id - if workflow.warning: - warning = {"title": _("Workflow Warning"), "message": workflow.warning} + if self.workflow_process_id.warning: + warning = { + "title": _("Workflow Warning"), + "message": self.workflow_process_id.warning, + } return {"warning": warning} + @api.depends("partner_id", "user_id", "workflow_process_id") + def _compute_team_id(self): # pylint: disable=W8110 + super()._compute_team_id() + if self.workflow_process_id.team_id: + self.team_id = self.workflow_process_id.team_id.id + def _create_invoices(self, grouped=False, final=False, date=None): for order in self: if not order.workflow_process_id.invoice_service_delivery: diff --git a/sale_automatic_workflow/models/sale_workflow_process.py b/sale_automatic_workflow/models/sale_workflow_process.py index 486b81d978d4..622b992c5d05 100644 --- a/sale_automatic_workflow/models/sale_workflow_process.py +++ b/sale_automatic_workflow/models/sale_workflow_process.py @@ -28,14 +28,6 @@ def _default_filter(self, xmlid): return self.env["ir.filters"].browse() name = fields.Char(required=True) - picking_policy = fields.Selection( - selection=[ - ("direct", "Deliver each product when available"), - ("one", "Deliver all products at once"), - ], - string="Shipping Policy", - default="direct", - ) validate_order = fields.Boolean() send_order_confirmation_mail = fields.Boolean( help="When checked, after order confirmation, a confirmation email will be " @@ -53,10 +45,6 @@ def _default_filter(self, xmlid): string="Validate Invoice Filter Domain", related="validate_invoice_filter_id.domain", ) - validate_picking = fields.Boolean(string="Confirm and Transfer Picking") - picking_filter_domain = fields.Text( - string="Picking Filter Domain", related="picking_filter_id.domain" - ) invoice_date_is_order_date = fields.Boolean( string="Force Invoice Date", help="When checked, the invoice date will be " "the same than the order's date", @@ -91,13 +79,6 @@ def _default_filter(self, xmlid): "sale_automatic_workflow.automatic_workflow_order_filter" ), ) - picking_filter_id = fields.Many2one( - "ir.filters", - string="Picking Filter", - default=lambda self: self._default_filter( - "sale_automatic_workflow.automatic_workflow_picking_filter" - ), - ) create_invoice_filter_id = fields.Many2one( "ir.filters", string="Create Invoice Filter", diff --git a/sale_automatic_workflow/readme/CONTRIBUTORS.md b/sale_automatic_workflow/readme/CONTRIBUTORS.md index c03c09465a49..ed3c76a65df3 100644 --- a/sale_automatic_workflow/readme/CONTRIBUTORS.md +++ b/sale_automatic_workflow/readme/CONTRIBUTORS.md @@ -10,3 +10,4 @@ - Thomas Fossoul \<\> - Phuc Tran Thanh \<\> - Sander Lienaerts \<\> +- Tri Doan \<\> diff --git a/sale_automatic_workflow/static/description/index.html b/sale_automatic_workflow/static/description/index.html index 937cffd415ee..ecda7c9901a8 100644 --- a/sale_automatic_workflow/static/description/index.html +++ b/sale_automatic_workflow/static/description/index.html @@ -1,4 +1,3 @@ - @@ -9,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -275,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -301,7 +301,7 @@ span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -438,6 +438,7 @@

Contributors

  • Thomas Fossoul <thomas@niboo.com>
  • Phuc Tran Thanh <phuc@trobz.com>
  • Sander Lienaerts <sander.lienaerts@codeforward.nl>
  • +
  • Tri Doan <tridm@trobz.com>
  • @@ -450,7 +451,9 @@

    Other credits

    Maintainers

    This module is maintained by the OCA.

    -Odoo Community Association + +Odoo Community Association +

    OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

    diff --git a/sale_automatic_workflow/tests/common.py b/sale_automatic_workflow/tests/common.py index 6f41023ce9a5..1b4e360d38e8 100644 --- a/sale_automatic_workflow/tests/common.py +++ b/sale_automatic_workflow/tests/common.py @@ -2,8 +2,11 @@ # Copyright 2020 Camptocamp SA (author: Simone Orsi) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo.tests import tagged from odoo.tests.common import TransactionCase +from odoo.addons.account.tests.common import AccountTestInvoicingCommon + class TestCommon(TransactionCase): @classmethod @@ -13,13 +16,13 @@ def setUpClass(cls): class TestAutomaticWorkflowMixin: - def create_sale_order(self, workflow, override=None): + def create_sale_order(self, workflow, override=None, product_type="consu"): sale_obj = self.env["sale.order"] partner_values = {"name": "Imperator Caius Julius Caesar Divus"} partner = self.env["res.partner"].create(partner_values) - product_values = {"name": "Bread", "list_price": 5, "type": "product"} + product_values = {"name": "Bread", "list_price": 5, "type": product_type} product = self.env["product.product"].create(product_values) self.product_uom_unit = self.env.ref("uom.product_uom_unit") values = { @@ -41,28 +44,14 @@ def create_sale_order(self, workflow, override=None): } if override: values.update(override) - order = sale_obj.create(values) - # Create inventory - for line in order.order_line: - if line.product_id.type == "product": - inventory = self.env["stock.quant"].create( - { - "product_id": line.product_id.id, - "location_id": self.env.ref("stock.stock_location_stock").id, - "inventory_quantity": line.product_uom_qty, - } - ) - inventory._apply_inventory() - return order + return sale_obj.create(values) def create_full_automatic(self, override=None): workflow_obj = self.env["sale.workflow.process"] values = workflow_obj.create( { "name": "Full Automatic", - "picking_policy": "one", "validate_order": True, - "validate_picking": True, "create_invoice": True, "validate_invoice": True, "invoice_date_is_order_date": True, @@ -74,3 +63,132 @@ def create_full_automatic(self, override=None): def run_job(self): self.env["automatic.workflow.job"].run() + + +@tagged("post_install", "-at_install") +class TestMultiCompanyCommon(AccountTestInvoicingCommon): + @classmethod + def create_product(cls, values): + values.update({"type": "consu", "invoice_policy": "order"}) + product_template = cls.env["product.template"].create(values) + return product_template.product_variant_id + + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass() + cls.env = cls.env( + context=dict( + cls.env.context, + tracking_disable=True, + # Compatibility with sale_automatic_workflow_job: even if + # the module is installed, ensure we don't delay a job. + # Thus, we test the usual flow. + _job_force_sync=True, + ) + ) + cls.company_fr = cls.setup_company_data( + { + "name": "French company", + "currency_id": cls.env.ref("base.EUR").id, + "country_id": cls.env.ref("base.fr").id, + } + )["company"] + + cls.company_ch = cls.setup_company_data( + { + "name": "Swiss company", + "currency_id": cls.env.ref("base.CHF").id, + "country_id": cls.env.ref("base.ch").id, + } + )["company"] + + cls.company_be = cls.setup_company_data( + { + "name": "Belgian company", + "currency_id": cls.env.ref("base.EUR").id, + "country_id": cls.env.ref("base.be").id, + } + )["company"] + + cls.company_fr_daughter = cls.setup_company_data( + { + "name": "French company daughter", + "currency_id": cls.env.ref("base.EUR").id, + "country_id": cls.env.ref("base.fr").id, + } + )["company"] + + cls.env.user.company_ids |= cls.company_fr + cls.env.user.company_ids |= cls.company_ch + cls.env.user.company_ids |= cls.company_be + cls.env.user.company_ids |= cls.company_fr_daughter + + cls.env.user.company_id = cls.company_fr.id + cls.customer_fr = ( + cls.env["res.partner"] + .with_context(default_company_id=cls.company_fr.id) + .create({"name": "Customer FR"}) + ) + cls.product_fr = cls.create_product({"name": "Evian bottle", "list_price": 2.0}) + + cls.env.user.company_id = cls.company_ch.id + + cls.customer_ch = cls.env["res.partner"].create({"name": "Customer CH"}) + cls.product_ch = cls.create_product( + {"name": "Henniez bottle", "list_price": 3.0} + ) + + cls.env.user.company_id = cls.company_be.id + cls.customer_be = cls.env["res.partner"].create({"name": "Customer BE"}) + cls.product_be = ( + cls.env["product.template"] + .create( + { + "name": "SPA bottle", + "list_price": 1.5, + "type": "consu", + "invoice_policy": "order", + } + ) + .product_variant_id + ) + + cls.env.user.company_id = cls.company_fr_daughter.id + cls.customer_fr_daughter = cls.env["res.partner"].create( + {"name": "Customer FR Daughter"} + ) + cls.product_fr_daughter = cls.create_product( + {"name": "Contrex bottle", "list_price": 1.5} + ) + + cls.auto_wkf = cls.env.ref("sale_automatic_workflow.automatic_validation") + cls.env.user.company_id = cls.env.ref("base.main_company") + + def create_auto_wkf_order(self, company, customer, product, qty): + # We need to change to the proper company + # to pick up correct company dependent fields + SaleOrder = self.env["sale.order"].with_company(company) + + self.product_uom_unit = self.env.ref("uom.product_uom_unit") + + order = SaleOrder.create( + { + "partner_id": customer.id, + "company_id": company.id, + "workflow_process_id": self.auto_wkf.id, + "order_line": [ + ( + 0, + 0, + { + "name": product.name, + "product_id": product.id, + "price_unit": product.list_price, + "product_uom_qty": qty, + "product_uom": self.product_uom_unit.id, + }, + ) + ], + } + ) + return order diff --git a/sale_automatic_workflow/tests/test_automatic_workflow.py b/sale_automatic_workflow/tests/test_automatic_workflow.py index 8a729c92bc02..8191fc4adcfc 100644 --- a/sale_automatic_workflow/tests/test_automatic_workflow.py +++ b/sale_automatic_workflow/tests/test_automatic_workflow.py @@ -25,40 +25,34 @@ def setUp(self): ) ) - def test_full_automatic(self): + def test_01_full_automatic(self): workflow = self.create_full_automatic() sale = self.create_sale_order(workflow) - sale._onchange_workflow_process_id() self.assertEqual(sale.state, "draft") self.assertEqual(sale.workflow_process_id, workflow) self.run_job() self.assertEqual(sale.state, "sale") - self.assertTrue(sale.picking_ids) self.assertTrue(sale.invoice_ids) invoice = sale.invoice_ids self.assertEqual(invoice.state, "posted") - picking = sale.picking_ids - self.run_job() - self.assertEqual(picking.state, "done") - def test_onchange(self): - workflow = self.create_full_automatic() + def test_02_onchange(self): + team_1 = self.env.ref("sales_team.crm_team_1") + team_2 = self.env.ref("sales_team.team_sales_department") + workflow = self.create_full_automatic(override={"team_id": team_1.id}) sale = self.create_sale_order(workflow) - sale._onchange_workflow_process_id() - self.assertEqual(sale.picking_policy, "one") - workflow2 = self.create_full_automatic(override={"picking_policy": "direct"}) + self.assertEqual(sale.team_id, team_1) + workflow2 = self.create_full_automatic(override={"team_id": team_2.id}) sale.workflow_process_id = workflow2.id - sale._onchange_workflow_process_id() - self.assertEqual(sale.picking_policy, "direct") + self.assertEqual(sale.team_id, team_2) - def test_date_invoice_from_sale_order(self): + def test_03_date_invoice_from_sale_order(self): workflow = self.create_full_automatic() # date_order on sale.order is date + time # invoice_date on account.move is date only last_week_time = fields.Datetime.now() - timedelta(days=7) override = {"date_order": last_week_time} sale = self.create_sale_order(workflow, override=override) - sale._onchange_workflow_process_id() self.assertEqual(sale.date_order, last_week_time) self.run_job() self.assertTrue(sale.invoice_ids) @@ -66,40 +60,20 @@ def test_date_invoice_from_sale_order(self): self.assertEqual(invoice.invoice_date, last_week_time.date()) self.assertEqual(invoice.workflow_process_id, sale.workflow_process_id) - def test_create_invoice_from_sale_order(self): + def test_04_create_invoice_from_sale_order(self): workflow = self.create_full_automatic() sale = self.create_sale_order(workflow) - sale._onchange_workflow_process_id() line = sale.order_line[0] - self.assertFalse(workflow.invoice_service_delivery) - self.assertEqual(line.qty_delivered_method, "stock_move") - self.assertEqual(line.qty_delivered, 0.0) - self.assertFalse(sale.delivery_status) - self.assertFalse(sale.all_qty_delivered) - # `_create_invoices` is already tested in `sale` module. # Make sure this addon works properly in regards to it. mock_path = "odoo.addons.sale.models.sale_order.SaleOrder._create_invoices" - with mock.patch(mock_path) as mocked: - sale._create_invoices() - mocked.assert_called() - self.assertEqual(line.qty_delivered, 0.0) - workflow.invoice_service_delivery = True line.qty_delivered_method = "manual" with mock.patch(mock_path) as mocked: sale._create_invoices() mocked.assert_called() self.assertEqual(line.qty_delivered, 1.0) - sale.action_confirm() - # Force the state to "full" - # note : this is not needed if you have the module sale_delivery_state - # installed but sale_automatic_workflow do not depend on it - # so we just force it so we can check the sale.all_qty_delivered - sale.delivery_status = "full" - sale._compute_all_qty_delivered() - self.assertTrue(sale.all_qty_delivered) - def test_invoice_from_picking_with_service_product(self): + def test_05_invoice_from_picking_with_service_product(self): workflow = self.create_full_automatic() product_service = self.env["product.product"].create( { @@ -131,14 +105,12 @@ def test_invoice_from_picking_with_service_product(self): ] } sale = self.create_sale_order(workflow, override=override) - sale._onchange_workflow_process_id() self.run_job() - self.assertFalse(sale.picking_ids) self.assertTrue(sale.invoice_ids) invoice = sale.invoice_ids self.assertEqual(invoice.workflow_process_id, sale.workflow_process_id) - def test_journal_on_invoice(self): + def test_06_journal_on_invoice(self): sale_journal = self.env["account.journal"].search( [("type", "=", "sale")], limit=1 ) @@ -148,7 +120,6 @@ def test_journal_on_invoice(self): workflow = self.create_full_automatic() sale = self.create_sale_order(workflow) - sale._onchange_workflow_process_id() self.run_job() self.assertTrue(sale.invoice_ids) invoice = sale.invoice_ids @@ -158,7 +129,6 @@ def test_journal_on_invoice(self): override={"property_journal_id": new_sale_journal.id} ) sale = self.create_sale_order(workflow) - sale._onchange_workflow_process_id() self.run_job() self.assertTrue(sale.invoice_ids) invoice = sale.invoice_ids @@ -168,7 +138,6 @@ def test_automatic_sale_order_confirmation_mail(self): workflow = self.create_full_automatic() workflow.send_order_confirmation_mail = True sale = self.create_sale_order(workflow) - sale._onchange_workflow_process_id() previous_message_ids = sale.message_ids self.run_job() self.assertEqual(sale.state, "sale") diff --git a/sale_automatic_workflow/tests/test_multicompany.py b/sale_automatic_workflow/tests/test_multicompany.py index 0b5e29d96799..50f45abe5d60 100644 --- a/sale_automatic_workflow/tests/test_multicompany.py +++ b/sale_automatic_workflow/tests/test_multicompany.py @@ -2,142 +2,12 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo.tests import tagged -from odoo.addons.account.tests.common import AccountTestInvoicingCommon +from .common import TestMultiCompanyCommon @tagged("post_install", "-at_install") -class TestMultiCompany(AccountTestInvoicingCommon): - @classmethod - def create_product(cls, values): - values.update({"type": "consu", "invoice_policy": "order"}) - product_template = cls.env["product.template"].create(values) - return product_template.product_variant_id - - @classmethod - def setUpClass(cls, chart_template_ref=None): - super().setUpClass() - cls.env = cls.env( - context=dict( - cls.env.context, - tracking_disable=True, - # Compatibility with sale_automatic_workflow_job: even if - # the module is installed, ensure we don't delay a job. - # Thus, we test the usual flow. - _job_force_sync=True, - ) - ) - cls.company_fr = cls.setup_company_data( - { - "name": "French company", - "currency_id": cls.env.ref("base.EUR").id, - "country_id": cls.env.ref("base.fr").id, - } - )["company"] - - cls.company_ch = cls.setup_company_data( - { - "name": "Swiss company", - "currency_id": cls.env.ref("base.CHF").id, - "country_id": cls.env.ref("base.ch").id, - } - )["company"] - - cls.company_be = cls.setup_company_data( - { - "name": "Belgian company", - "currency_id": cls.env.ref("base.EUR").id, - "country_id": cls.env.ref("base.be").id, - } - )["company"] - - cls.company_fr_daughter = cls.setup_company_data( - { - "name": "French company daughter", - "currency_id": cls.env.ref("base.EUR").id, - "country_id": cls.env.ref("base.fr").id, - } - )["company"] - - cls.env.user.company_ids |= cls.company_fr - cls.env.user.company_ids |= cls.company_ch - cls.env.user.company_ids |= cls.company_be - cls.env.user.company_ids |= cls.company_fr_daughter - - cls.env.user.company_id = cls.company_fr.id - cls.customer_fr = ( - cls.env["res.partner"] - .with_context(default_company_id=cls.company_fr.id) - .create({"name": "Customer FR"}) - ) - cls.product_fr = cls.create_product({"name": "Evian bottle", "list_price": 2.0}) - - cls.env.user.company_id = cls.company_ch.id - - cls.customer_ch = cls.env["res.partner"].create({"name": "Customer CH"}) - cls.product_ch = cls.create_product( - {"name": "Henniez bottle", "list_price": 3.0} - ) - - cls.env.user.company_id = cls.company_be.id - cls.customer_be = cls.env["res.partner"].create({"name": "Customer BE"}) - cls.product_be = ( - cls.env["product.template"] - .create( - { - "name": "SPA bottle", - "list_price": 1.5, - "type": "consu", - "invoice_policy": "order", - } - ) - .product_variant_id - ) - - cls.env.user.company_id = cls.company_fr_daughter.id - cls.customer_fr_daughter = cls.env["res.partner"].create( - {"name": "Customer FR Daughter"} - ) - cls.product_fr_daughter = cls.create_product( - {"name": "Contrex bottle", "list_price": 1.5} - ) - - cls.auto_wkf = cls.env.ref("sale_automatic_workflow.automatic_validation") - cls.auto_wkf.validate_picking = True - cls.env.user.company_id = cls.env.ref("base.main_company") - - def create_auto_wkf_order(self, company, customer, product, qty): - # We need to change to the proper company - # to pick up correct company dependent fields - SaleOrder = self.env["sale.order"].with_company(company) - warehouse = self.env["stock.warehouse"].search( - [("company_id", "=", company.id)], limit=1 - ) - - self.product_uom_unit = self.env.ref("uom.product_uom_unit") - - order = SaleOrder.create( - { - "partner_id": customer.id, - "company_id": company.id, - "warehouse_id": warehouse.id, - "workflow_process_id": self.auto_wkf.id, - "order_line": [ - ( - 0, - 0, - { - "name": product.name, - "product_id": product.id, - "price_unit": product.list_price, - "product_uom_qty": qty, - "product_uom": self.product_uom_unit.id, - }, - ) - ], - } - ) - order._onchange_workflow_process_id() - return order +class TestMultiCompany(TestMultiCompanyCommon): + """Class to test sale automated workflow with multi-company.""" def test_sale_order_multicompany(self): self.env.user.company_id = self.env.ref("base.main_company") @@ -163,12 +33,6 @@ def test_sale_order_multicompany(self): self.assertEqual(order_fr_daughter.state, "draft") self.env["automatic.workflow.job"].run() - self.assertTrue(order_fr.picking_ids) - self.assertTrue(order_ch.picking_ids) - self.assertTrue(order_be.picking_ids) - self.assertEqual(order_fr.picking_ids.state, "done") - self.assertEqual(order_ch.picking_ids.state, "done") - self.assertEqual(order_be.picking_ids.state, "done") invoice_fr = order_fr.invoice_ids invoice_ch = order_ch.invoice_ids invoice_be = order_be.invoice_ids diff --git a/sale_automatic_workflow/views/sale_view.xml b/sale_automatic_workflow/views/sale_order_views.xml similarity index 64% rename from sale_automatic_workflow/views/sale_view.xml rename to sale_automatic_workflow/views/sale_order_views.xml index 70b5e08184a8..8e59b9159492 100644 --- a/sale_automatic_workflow/views/sale_view.xml +++ b/sale_automatic_workflow/views/sale_order_views.xml @@ -19,14 +19,4 @@ - - sale.order.form.sale.stock - sale.order - - - - - - - diff --git a/sale_automatic_workflow/views/sale_workflow_process_view.xml b/sale_automatic_workflow/views/sale_workflow_process_views.xml similarity index 85% rename from sale_automatic_workflow/views/sale_workflow_process_view.xml rename to sale_automatic_workflow/views/sale_workflow_process_views.xml index d77b5008c389..50e246d47876 100644 --- a/sale_automatic_workflow/views/sale_workflow_process_view.xml +++ b/sale_automatic_workflow/views/sale_workflow_process_views.xml @@ -20,17 +20,6 @@

    Order Configuration

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -