[16.0] sale_order_batch: add tests
This commit is contained in:
parent
12736d9972
commit
4b9796521e
9 changed files with 768 additions and 1 deletions
|
|
@ -49,6 +49,7 @@ Changelog
|
||||||
- 16.0.2.2.1: Add lst_price to view
|
- 16.0.2.2.1: Add lst_price to view
|
||||||
- 16.0.2.3.0: Add "Reset to Open"
|
- 16.0.2.3.0: Add "Reset to Open"
|
||||||
- 16.0.2.3.1: Remove Sale Order from batch on cancelation
|
- 16.0.2.3.1: Remove Sale Order from batch on cancelation
|
||||||
|
- 16.0.2.4.0: Add Followers on In Progress & add tests
|
||||||
|
|
||||||
Bug Tracker
|
Bug Tracker
|
||||||
===========
|
===========
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,4 @@
|
||||||
- 16.0.2.2.1: Add lst_price to view
|
- 16.0.2.2.1: Add lst_price to view
|
||||||
- 16.0.2.3.0: Add "Reset to Open"
|
- 16.0.2.3.0: Add "Reset to Open"
|
||||||
- 16.0.2.3.1: Remove Sale Order from batch on cancelation
|
- 16.0.2.3.1: Remove Sale Order from batch on cancelation
|
||||||
|
- 16.0.2.4.0: Add Followers on In Progress & add tests
|
||||||
|
|
@ -405,6 +405,7 @@ anymore as log as they are part of a batch. Only Sale Orders in state Qutotation
|
||||||
<li>16.0.2.2.1: Add lst_price to view</li>
|
<li>16.0.2.2.1: Add lst_price to view</li>
|
||||||
<li>16.0.2.3.0: Add “Reset to Open”</li>
|
<li>16.0.2.3.0: Add “Reset to Open”</li>
|
||||||
<li>16.0.2.3.1: Remove Sale Order from batch on cancelation</li>
|
<li>16.0.2.3.1: Remove Sale Order from batch on cancelation</li>
|
||||||
|
<li>16.0.2.4.0: Add Followers on In Progress & add tests</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="bug-tracker">
|
<div class="section" id="bug-tracker">
|
||||||
|
|
|
||||||
7
sale_order_batch/tests/__init__.py
Normal file
7
sale_order_batch/tests/__init__.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
from . import (
|
||||||
|
test_sale_order,
|
||||||
|
test_sale_order_batch,
|
||||||
|
test_sale_order_batch_cancel_wizard,
|
||||||
|
test_sale_order_batch_product,
|
||||||
|
test_sale_order_line,
|
||||||
|
)
|
||||||
158
sale_order_batch/tests/test_sale_order.py
Normal file
158
sale_order_batch/tests/test_sale_order.py
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
from odoo.tests import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestSaleOrder(TransactionCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.env = cls.env(context={**cls.env.context, "tracking_disable": True})
|
||||||
|
cls.partner = cls.env["res.partner"].create({"name": "Test Partner"})
|
||||||
|
cls.product = cls.env["product.product"].create(
|
||||||
|
{"name": "Test Service", "type": "service", "list_price": 100.0}
|
||||||
|
)
|
||||||
|
|
||||||
|
def _create_order(self, **kwargs):
|
||||||
|
vals = {
|
||||||
|
"partner_id": self.partner.id,
|
||||||
|
"order_line": [
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"product_uom_qty": 1,
|
||||||
|
"price_unit": 100.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
}
|
||||||
|
vals.update(kwargs)
|
||||||
|
return self.env["sale.order"].create(vals)
|
||||||
|
|
||||||
|
def _create_batch(self):
|
||||||
|
return self.env["sale.order.batch"].create({})
|
||||||
|
|
||||||
|
# --- _get_current_batch ---
|
||||||
|
|
||||||
|
def test_get_current_batch_finds_open_batch(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order()
|
||||||
|
self.assertEqual(order._get_current_batch(), batch)
|
||||||
|
|
||||||
|
def test_get_current_batch_ignores_closed_batch(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
batch.action_confirm()
|
||||||
|
order = self._create_order()
|
||||||
|
self.assertNotEqual(order._get_current_batch(), batch)
|
||||||
|
|
||||||
|
# --- action_add_to_batch ---
|
||||||
|
|
||||||
|
def test_action_add_to_batch_creates_new_batch(self):
|
||||||
|
order = self._create_order()
|
||||||
|
order.action_add_to_batch()
|
||||||
|
self.assertTrue(order.batch_id)
|
||||||
|
|
||||||
|
def test_action_add_to_batch_uses_existing_open_batch(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order()
|
||||||
|
order.action_add_to_batch()
|
||||||
|
self.assertEqual(order.batch_id, batch)
|
||||||
|
|
||||||
|
def test_action_add_to_batch_skips_already_batched_order(self):
|
||||||
|
batch1 = self._create_batch()
|
||||||
|
order = self._create_order(batch_id=batch1.id)
|
||||||
|
order.action_add_to_batch()
|
||||||
|
self.assertEqual(order.batch_id, batch1)
|
||||||
|
|
||||||
|
def test_action_add_to_batch_skips_confirmed_order(self):
|
||||||
|
order = self._create_order()
|
||||||
|
order.with_context(bypass_batch=True).action_confirm()
|
||||||
|
order.action_add_to_batch()
|
||||||
|
self.assertFalse(order.batch_id)
|
||||||
|
|
||||||
|
# --- action_view_sale_order_batch ---
|
||||||
|
|
||||||
|
def test_action_view_sale_order_batch_returns_form_action(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch_id=batch.id)
|
||||||
|
result = order.action_view_sale_order_batch()
|
||||||
|
self.assertEqual(result["res_model"], "sale.order.batch")
|
||||||
|
self.assertEqual(result["res_id"], batch.id)
|
||||||
|
self.assertEqual(result["view_mode"], "form")
|
||||||
|
|
||||||
|
# --- action_confirm ---
|
||||||
|
|
||||||
|
def test_action_confirm_raises_user_error_when_in_batch(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch_id=batch.id)
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
order.action_confirm()
|
||||||
|
|
||||||
|
def test_action_confirm_raises_for_multiple_batched_orders(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order1 = self._create_order(batch_id=batch.id)
|
||||||
|
order2 = self._create_order(batch_id=batch.id)
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
(order1 | order2).action_confirm()
|
||||||
|
|
||||||
|
def test_action_confirm_works_with_bypass_batch_context(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch_id=batch.id)
|
||||||
|
order.with_context(bypass_batch=True).action_confirm()
|
||||||
|
self.assertEqual(order.state, "sale")
|
||||||
|
|
||||||
|
def test_action_confirm_works_without_batch(self):
|
||||||
|
order = self._create_order()
|
||||||
|
order.action_confirm()
|
||||||
|
self.assertEqual(order.state, "sale")
|
||||||
|
|
||||||
|
# --- action_quotation_send ---
|
||||||
|
|
||||||
|
def test_action_quotation_send_raises_user_error_when_in_batch(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch_id=batch.id)
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
order.action_quotation_send()
|
||||||
|
|
||||||
|
def test_action_quotation_send_raises_for_multiple_batched_orders(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order1 = self._create_order(batch_id=batch.id)
|
||||||
|
order2 = self._create_order(batch_id=batch.id)
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
(order1 | order2).action_quotation_send()
|
||||||
|
|
||||||
|
def test_action_quotation_send_works_with_bypass_batch_context(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch_id=batch.id)
|
||||||
|
result = order.with_context(bypass_batch=True).action_quotation_send()
|
||||||
|
self.assertIsNotNone(result)
|
||||||
|
|
||||||
|
def test_action_quotation_send_works_without_batch(self):
|
||||||
|
order = self._create_order()
|
||||||
|
result = order.action_quotation_send()
|
||||||
|
self.assertIsNotNone(result)
|
||||||
|
|
||||||
|
# --- action_cancel ---
|
||||||
|
|
||||||
|
def test_action_cancel_clears_batch_id(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch_id=batch.id)
|
||||||
|
order.action_cancel()
|
||||||
|
self.assertFalse(order.batch_id)
|
||||||
|
|
||||||
|
# --- write ---
|
||||||
|
|
||||||
|
def test_write_batch_id_updates_batch_products(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order()
|
||||||
|
self.assertFalse(order.order_line.batch_product_id)
|
||||||
|
order.write({"batch_id": batch.id})
|
||||||
|
self.assertTrue(order.order_line.batch_product_id)
|
||||||
|
|
||||||
|
def test_write_without_batch_id_does_not_change_products(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch_id=batch.id)
|
||||||
|
batch_product = order.order_line.batch_product_id
|
||||||
|
order.write({"note": "test note"})
|
||||||
|
self.assertEqual(order.order_line.batch_product_id, batch_product)
|
||||||
249
sale_order_batch/tests/test_sale_order_batch.py
Normal file
249
sale_order_batch/tests/test_sale_order_batch.py
Normal file
|
|
@ -0,0 +1,249 @@
|
||||||
|
from odoo.tests import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestSaleOrderBatch(TransactionCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.env = cls.env(context={**cls.env.context, "tracking_disable": True})
|
||||||
|
cls.partner = cls.env["res.partner"].create({"name": "Test Partner"})
|
||||||
|
cls.product = cls.env["product.product"].create(
|
||||||
|
{
|
||||||
|
"name": "Test Service Product",
|
||||||
|
"type": "service",
|
||||||
|
"list_price": 100.0,
|
||||||
|
"invoice_policy": "order",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cls.product2 = cls.env["product.product"].create(
|
||||||
|
{
|
||||||
|
"name": "Test Service Product 2",
|
||||||
|
"type": "service",
|
||||||
|
"list_price": 200.0,
|
||||||
|
"invoice_policy": "order",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def _create_batch(self, **kwargs):
|
||||||
|
return self.env["sale.order.batch"].create(kwargs)
|
||||||
|
|
||||||
|
def _create_order(self, batch=None, product=None, qty=1, price=100.0):
|
||||||
|
if product is None:
|
||||||
|
product = self.product
|
||||||
|
vals = {
|
||||||
|
"partner_id": self.partner.id,
|
||||||
|
"order_line": [
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"product_id": product.id,
|
||||||
|
"product_uom_qty": qty,
|
||||||
|
"price_unit": price,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
}
|
||||||
|
if batch:
|
||||||
|
vals["batch_id"] = batch.id
|
||||||
|
return self.env["sale.order"].create(vals)
|
||||||
|
|
||||||
|
def test_create_generates_sequence_name(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self.assertTrue(batch.name.startswith("SOB"))
|
||||||
|
self.assertNotEqual(batch.name, "New")
|
||||||
|
|
||||||
|
def test_create_keeps_explicit_name(self):
|
||||||
|
batch = self.env["sale.order.batch"].create({"name": "MY-BATCH-001"})
|
||||||
|
self.assertEqual(batch.name, "MY-BATCH-001")
|
||||||
|
|
||||||
|
def test_compute_sale_order_count_with_orders(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
self.assertEqual(batch.sale_order_count, 2)
|
||||||
|
|
||||||
|
def test_compute_amount_total(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order1 = self._create_order(batch=batch, price=100.0)
|
||||||
|
order2 = self._create_order(batch=batch, price=200.0)
|
||||||
|
self.assertAlmostEqual(
|
||||||
|
batch.amount_total, order1.amount_total + order2.amount_total
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_compute_product_count_with_products(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch, product=self.product)
|
||||||
|
self._create_order(batch=batch, product=self.product2)
|
||||||
|
self.assertEqual(batch.product_count, 2)
|
||||||
|
|
||||||
|
def test_compute_invoice_ids_with_invoice(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
order.with_context(bypass_batch=True).action_confirm()
|
||||||
|
invoice = order._create_invoices()
|
||||||
|
self.assertIn(invoice, batch.invoice_ids)
|
||||||
|
self.assertEqual(batch.invoice_count, 1)
|
||||||
|
|
||||||
|
def test_compute_partner_credit_warning_no_warnings(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
self.assertEqual(batch.partner_credit_warning, "")
|
||||||
|
|
||||||
|
# --- action_view_source_sale_orders ---
|
||||||
|
|
||||||
|
def test_action_view_source_sale_orders_zero(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
result = batch.action_view_source_sale_orders()
|
||||||
|
self.assertEqual(result["type"], "ir.actions.act_window_close")
|
||||||
|
|
||||||
|
def test_action_view_source_sale_orders_one(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
result = batch.action_view_source_sale_orders()
|
||||||
|
self.assertEqual(result["res_id"], order.id)
|
||||||
|
self.assertIn("views", result)
|
||||||
|
|
||||||
|
def test_action_view_source_sale_orders_multiple(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
result = batch.action_view_source_sale_orders()
|
||||||
|
self.assertIn("domain", result)
|
||||||
|
|
||||||
|
# --- action_view_products ---
|
||||||
|
|
||||||
|
def test_action_view_products_zero(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
result = batch.action_view_products()
|
||||||
|
self.assertEqual(result["type"], "ir.actions.act_window_close")
|
||||||
|
|
||||||
|
def test_action_view_products_one(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
result = batch.action_view_products()
|
||||||
|
self.assertIn("res_id", result)
|
||||||
|
self.assertIn("views", result)
|
||||||
|
self.assertEqual(result["res_id"], batch.product_ids.id)
|
||||||
|
|
||||||
|
def test_action_view_products_multiple(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch, product=self.product)
|
||||||
|
self._create_order(batch=batch, product=self.product2)
|
||||||
|
result = batch.action_view_products()
|
||||||
|
self.assertIn("domain", result)
|
||||||
|
|
||||||
|
# --- action_view_invoice ---
|
||||||
|
|
||||||
|
def test_action_view_invoice_zero(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
result = batch.action_view_invoice()
|
||||||
|
self.assertEqual(result["type"], "ir.actions.act_window_close")
|
||||||
|
|
||||||
|
def test_action_view_invoice_one(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
order.with_context(bypass_batch=True).action_confirm()
|
||||||
|
order._create_invoices()
|
||||||
|
result = batch.action_view_invoice()
|
||||||
|
self.assertIn("res_id", result)
|
||||||
|
self.assertIn("views", result)
|
||||||
|
|
||||||
|
def test_action_view_invoice_multiple(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order1 = self._create_order(batch=batch)
|
||||||
|
order2 = self._create_order(batch=batch)
|
||||||
|
order1.with_context(bypass_batch=True).action_confirm()
|
||||||
|
order2.with_context(bypass_batch=True).action_confirm()
|
||||||
|
order1._create_invoices()
|
||||||
|
order2._create_invoices()
|
||||||
|
result = batch.action_view_invoice()
|
||||||
|
self.assertIn("domain", result)
|
||||||
|
|
||||||
|
# --- action_in_progress ---
|
||||||
|
|
||||||
|
def test_action_in_progress_sets_state(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
batch.action_in_progress()
|
||||||
|
self.assertEqual(batch.state, "in_progress")
|
||||||
|
|
||||||
|
def test_action_in_progress_sends_quotation(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
batch.action_in_progress()
|
||||||
|
self.assertEqual(order.state, "sent")
|
||||||
|
|
||||||
|
# --- action_confirm ---
|
||||||
|
|
||||||
|
def test_action_confirm_sets_batch_closed(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
batch.action_confirm()
|
||||||
|
self.assertEqual(batch.state, "closed")
|
||||||
|
|
||||||
|
def test_action_confirm_confirms_orders(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
batch.action_confirm()
|
||||||
|
self.assertEqual(order.state, "sale")
|
||||||
|
|
||||||
|
# --- action_open ---
|
||||||
|
|
||||||
|
def test_action_open_resets_state(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
batch.action_in_progress()
|
||||||
|
batch.action_open()
|
||||||
|
self.assertEqual(batch.state, "open")
|
||||||
|
|
||||||
|
def test_action_open_resets_orders_to_draft(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
batch.action_in_progress()
|
||||||
|
batch.action_open()
|
||||||
|
self.assertEqual(order.state, "draft")
|
||||||
|
|
||||||
|
# --- _show_cancel_wizard ---
|
||||||
|
|
||||||
|
def test_show_cancel_wizard_disabled_by_context(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
batch.action_in_progress()
|
||||||
|
result = batch.with_context(disable_cancel_warning=True)._show_cancel_wizard()
|
||||||
|
self.assertFalse(result)
|
||||||
|
|
||||||
|
def test_show_cancel_wizard_no_orders(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self.assertFalse(batch._show_cancel_wizard())
|
||||||
|
|
||||||
|
def test_show_cancel_wizard_with_sent_orders(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
batch.action_in_progress()
|
||||||
|
self.assertTrue(batch._show_cancel_wizard())
|
||||||
|
|
||||||
|
# --- action_cancel ---
|
||||||
|
|
||||||
|
def test_action_cancel_returns_wizard_for_sent_orders(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
batch.action_in_progress()
|
||||||
|
result = batch.action_cancel()
|
||||||
|
self.assertIsNotNone(result)
|
||||||
|
self.assertEqual(result.get("res_model"), "sale.order.batch.cancel.wizard")
|
||||||
|
|
||||||
|
def test_action_cancel_without_wizard_sets_cancel(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
self._create_order(batch=batch)
|
||||||
|
batch.with_context(disable_cancel_warning=True).action_cancel()
|
||||||
|
self.assertEqual(batch.state, "cancel")
|
||||||
|
|
||||||
|
# --- _action_cancel ---
|
||||||
|
|
||||||
|
def test_action_cancel_directly(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
batch._action_cancel()
|
||||||
|
self.assertEqual(batch.state, "cancel")
|
||||||
|
self.assertEqual(order.state, "cancel")
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
from odoo.tests import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestSaleOrderBatchCancelWizard(TransactionCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.env = cls.env(context={**cls.env.context, "tracking_disable": True})
|
||||||
|
cls.partner = cls.env["res.partner"].create({"name": "Test Partner"})
|
||||||
|
cls.product = cls.env["product.product"].create(
|
||||||
|
{"name": "Test Product", "type": "service"}
|
||||||
|
)
|
||||||
|
|
||||||
|
def _create_batch_with_order(self):
|
||||||
|
batch = self.env["sale.order.batch"].create({})
|
||||||
|
order = self.env["sale.order"].create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner.id,
|
||||||
|
"batch_id": batch.id,
|
||||||
|
"order_line": [
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"product_uom_qty": 1,
|
||||||
|
"price_unit": 10.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return batch, order
|
||||||
|
|
||||||
|
def _create_wizard(self, batch):
|
||||||
|
return (
|
||||||
|
self.env["sale.order.batch.cancel.wizard"]
|
||||||
|
.with_context(active_ids=[batch.id])
|
||||||
|
.create({"batch_ids": [(4, batch.id)]})
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- _compute_order_ids ---
|
||||||
|
|
||||||
|
def test_compute_order_ids(self):
|
||||||
|
batch, order = self._create_batch_with_order()
|
||||||
|
wizard = self._create_wizard(batch)
|
||||||
|
self.assertIn(order, wizard.order_ids)
|
||||||
|
|
||||||
|
def test_compute_order_ids_multiple_batches(self):
|
||||||
|
batch1, order1 = self._create_batch_with_order()
|
||||||
|
batch2, order2 = self._create_batch_with_order()
|
||||||
|
wizard = (
|
||||||
|
self.env["sale.order.batch.cancel.wizard"]
|
||||||
|
.with_context(active_ids=[batch1.id, batch2.id])
|
||||||
|
.create({"batch_ids": [(4, batch1.id), (4, batch2.id)]})
|
||||||
|
)
|
||||||
|
self.assertIn(order1, wizard.order_ids)
|
||||||
|
self.assertIn(order2, wizard.order_ids)
|
||||||
|
|
||||||
|
# --- action_cancel ---
|
||||||
|
|
||||||
|
def test_action_cancel_sets_batch_state_cancel(self):
|
||||||
|
batch, order = self._create_batch_with_order()
|
||||||
|
wizard = self._create_wizard(batch)
|
||||||
|
wizard.action_cancel()
|
||||||
|
self.assertEqual(batch.state, "cancel")
|
||||||
|
|
||||||
|
def test_action_cancel_cancels_orders(self):
|
||||||
|
batch, order = self._create_batch_with_order()
|
||||||
|
wizard = self._create_wizard(batch)
|
||||||
|
wizard.action_cancel()
|
||||||
|
self.assertEqual(order.state, "cancel")
|
||||||
|
|
||||||
|
def test_action_cancel_returns_window_close(self):
|
||||||
|
batch, order = self._create_batch_with_order()
|
||||||
|
wizard = self._create_wizard(batch)
|
||||||
|
result = wizard.action_cancel()
|
||||||
|
self.assertEqual(result["type"], "ir.actions.act_window_close")
|
||||||
|
|
||||||
|
# --- action_discard ---
|
||||||
|
|
||||||
|
def test_action_discard_returns_window_close(self):
|
||||||
|
batch, order = self._create_batch_with_order()
|
||||||
|
wizard = self._create_wizard(batch)
|
||||||
|
result = wizard.action_discard()
|
||||||
|
self.assertEqual(result["type"], "ir.actions.act_window_close")
|
||||||
119
sale_order_batch/tests/test_sale_order_batch_product.py
Normal file
119
sale_order_batch/tests/test_sale_order_batch_product.py
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
from odoo.tests import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestSaleOrderBatchProduct(TransactionCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.env = cls.env(context={**cls.env.context, "tracking_disable": True})
|
||||||
|
cls.partner = cls.env["res.partner"].create({"name": "Test Partner"})
|
||||||
|
cls.product = cls.env["product.product"].create(
|
||||||
|
{"name": "Test Product", "type": "service"}
|
||||||
|
)
|
||||||
|
|
||||||
|
def _create_batch_with_order(self, qty=1):
|
||||||
|
batch = self.env["sale.order.batch"].create({})
|
||||||
|
order = self.env["sale.order"].create(
|
||||||
|
{
|
||||||
|
"partner_id": self.partner.id,
|
||||||
|
"batch_id": batch.id,
|
||||||
|
"order_line": [
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"product_uom_qty": qty,
|
||||||
|
"price_unit": 10.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return batch, order, batch.product_ids[0]
|
||||||
|
|
||||||
|
# --- _compute_uom_qty ---
|
||||||
|
|
||||||
|
def test_compute_uom_qty_single_line(self):
|
||||||
|
batch, order, batch_product = self._create_batch_with_order(qty=3)
|
||||||
|
self.assertAlmostEqual(batch_product.product_uom_qty, 3.0)
|
||||||
|
|
||||||
|
def test_compute_uom_qty_multiple_lines(self):
|
||||||
|
batch, order, batch_product = self._create_batch_with_order(qty=3)
|
||||||
|
self.env["sale.order.line"].create(
|
||||||
|
{
|
||||||
|
"order_id": order.id,
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"product_uom_qty": 2,
|
||||||
|
"price_unit": 10.0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertAlmostEqual(batch_product.product_uom_qty, 5.0)
|
||||||
|
|
||||||
|
# --- _compute_product_packaging_qty ---
|
||||||
|
|
||||||
|
def test_compute_product_packaging_qty_without_packaging(self):
|
||||||
|
batch, order, batch_product = self._create_batch_with_order()
|
||||||
|
if not batch_product.product_packaging_id:
|
||||||
|
self.assertEqual(batch_product.product_packaging_qty, 1)
|
||||||
|
|
||||||
|
def test_compute_product_packaging_qty_with_packaging(self):
|
||||||
|
packaging = self.env["product.packaging"].create(
|
||||||
|
{
|
||||||
|
"name": "Box of 10",
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"qty": 10.0,
|
||||||
|
"sales": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
batch, order, batch_product = self._create_batch_with_order(qty=5)
|
||||||
|
self.assertEqual(batch_product.product_packaging_id, packaging)
|
||||||
|
self.assertEqual(batch_product.product_packaging_qty, 10.0)
|
||||||
|
|
||||||
|
# --- _compute_product_packaging_id ---
|
||||||
|
|
||||||
|
def test_compute_product_packaging_id_suggests_first_packaging(self):
|
||||||
|
packaging = self.env["product.packaging"].create(
|
||||||
|
{
|
||||||
|
"name": "Box of 6",
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"qty": 6.0,
|
||||||
|
"sales": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
batch, order, batch_product = self._create_batch_with_order(qty=4)
|
||||||
|
self.assertEqual(batch_product.product_packaging_id, packaging)
|
||||||
|
|
||||||
|
def test_compute_product_packaging_id_clears_wrong_product_packaging(self):
|
||||||
|
product2 = self.env["product.product"].create(
|
||||||
|
{"name": "Other Product", "type": "service"}
|
||||||
|
)
|
||||||
|
packaging2 = self.env["product.packaging"].create(
|
||||||
|
{
|
||||||
|
"name": "Box of 5",
|
||||||
|
"product_id": product2.id,
|
||||||
|
"qty": 5.0,
|
||||||
|
"sales": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
batch, order, batch_product = self._create_batch_with_order()
|
||||||
|
batch_product.product_packaging_id = packaging2
|
||||||
|
batch_product._compute_product_packaging_id()
|
||||||
|
self.assertFalse(batch_product.product_packaging_id)
|
||||||
|
|
||||||
|
def test_compute_product_packaging_id_no_packaging_when_no_qty(self):
|
||||||
|
self.env["product.packaging"].create(
|
||||||
|
{
|
||||||
|
"name": "Box of 12",
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"qty": 12.0,
|
||||||
|
"sales": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
batch = self.env["sale.order.batch"].create({})
|
||||||
|
batch_product = self.env["sale.order.batch.product"].create(
|
||||||
|
{"batch_id": batch.id, "product_id": self.product.id}
|
||||||
|
)
|
||||||
|
# With no lines, product_uom_qty is 0 — packaging should not be suggested
|
||||||
|
self.assertFalse(batch_product.product_uom_qty)
|
||||||
|
self.assertFalse(batch_product.product_packaging_id)
|
||||||
145
sale_order_batch/tests/test_sale_order_line.py
Normal file
145
sale_order_batch/tests/test_sale_order_line.py
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
from odoo.tests import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestSaleOrderLine(TransactionCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.env = cls.env(context={**cls.env.context, "tracking_disable": True})
|
||||||
|
cls.partner = cls.env["res.partner"].create({"name": "Test Partner"})
|
||||||
|
cls.product = cls.env["product.product"].create(
|
||||||
|
{"name": "Product A", "type": "service"}
|
||||||
|
)
|
||||||
|
cls.product2 = cls.env["product.product"].create(
|
||||||
|
{"name": "Product B", "type": "service"}
|
||||||
|
)
|
||||||
|
|
||||||
|
def _create_batch(self):
|
||||||
|
return self.env["sale.order.batch"].create({})
|
||||||
|
|
||||||
|
def _create_order(self, batch=None, product=None, qty=1):
|
||||||
|
if product is None:
|
||||||
|
product = self.product
|
||||||
|
vals = {
|
||||||
|
"partner_id": self.partner.id,
|
||||||
|
"order_line": [
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
"product_id": product.id,
|
||||||
|
"product_uom_qty": qty,
|
||||||
|
"price_unit": 10.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
}
|
||||||
|
if batch:
|
||||||
|
vals["batch_id"] = batch.id
|
||||||
|
return self.env["sale.order"].create(vals)
|
||||||
|
|
||||||
|
# --- create ---
|
||||||
|
|
||||||
|
def test_create_line_with_batch_links_batch_product(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
line = order.order_line
|
||||||
|
self.assertTrue(line.batch_product_id)
|
||||||
|
self.assertEqual(line.batch_product_id.product_id, self.product)
|
||||||
|
self.assertEqual(line.batch_product_id.batch_id, batch)
|
||||||
|
|
||||||
|
def test_create_line_without_batch_has_no_batch_product(self):
|
||||||
|
order = self._create_order()
|
||||||
|
self.assertFalse(order.order_line.batch_product_id)
|
||||||
|
|
||||||
|
def test_create_two_lines_same_product_share_batch_product(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
line2 = self.env["sale.order.line"].create(
|
||||||
|
{
|
||||||
|
"order_id": order.id,
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"product_uom_qty": 2,
|
||||||
|
"price_unit": 10.0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEqual(order.order_line[0].batch_product_id, line2.batch_product_id)
|
||||||
|
|
||||||
|
def test_create_two_lines_different_products_get_different_batch_products(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
line2 = self.env["sale.order.line"].create(
|
||||||
|
{
|
||||||
|
"order_id": order.id,
|
||||||
|
"product_id": self.product2.id,
|
||||||
|
"product_uom_qty": 1,
|
||||||
|
"price_unit": 10.0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertNotEqual(
|
||||||
|
order.order_line[0].batch_product_id, line2.batch_product_id
|
||||||
|
)
|
||||||
|
self.assertEqual(batch.product_count, 2)
|
||||||
|
|
||||||
|
# --- write ---
|
||||||
|
|
||||||
|
def test_write_product_id_updates_batch_product(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
line = order.order_line
|
||||||
|
old_batch_product = line.batch_product_id
|
||||||
|
line.write({"product_id": self.product2.id})
|
||||||
|
self.assertNotEqual(line.batch_product_id, old_batch_product)
|
||||||
|
self.assertEqual(line.batch_product_id.product_id, self.product2)
|
||||||
|
|
||||||
|
def test_write_without_product_id_keeps_batch_product(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
line = order.order_line
|
||||||
|
batch_product = line.batch_product_id
|
||||||
|
line.write({"product_uom_qty": 5})
|
||||||
|
self.assertEqual(line.batch_product_id, batch_product)
|
||||||
|
|
||||||
|
# --- unlink ---
|
||||||
|
|
||||||
|
def test_unlink_last_line_removes_batch_product(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
line = order.order_line
|
||||||
|
batch_product = line.batch_product_id
|
||||||
|
line.unlink()
|
||||||
|
self.assertFalse(batch_product.exists())
|
||||||
|
|
||||||
|
def test_unlink_line_keeps_batch_product_when_other_lines_exist(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
line2 = self.env["sale.order.line"].create(
|
||||||
|
{
|
||||||
|
"order_id": order.id,
|
||||||
|
"product_id": self.product.id,
|
||||||
|
"product_uom_qty": 2,
|
||||||
|
"price_unit": 10.0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
batch_product = order.order_line[0].batch_product_id
|
||||||
|
order.order_line[0].unlink()
|
||||||
|
self.assertTrue(batch_product.exists())
|
||||||
|
self.assertIn(line2, batch_product.sale_order_line_ids)
|
||||||
|
|
||||||
|
# --- _update_batch_product ---
|
||||||
|
|
||||||
|
def test_update_batch_product_links_when_batch_assigned(self):
|
||||||
|
order = self._create_order()
|
||||||
|
line = order.order_line
|
||||||
|
self.assertFalse(line.batch_product_id)
|
||||||
|
batch = self._create_batch()
|
||||||
|
order.write({"batch_id": batch.id})
|
||||||
|
self.assertTrue(line.batch_product_id)
|
||||||
|
|
||||||
|
def test_update_batch_product_unlinks_when_batch_removed(self):
|
||||||
|
batch = self._create_batch()
|
||||||
|
order = self._create_order(batch=batch)
|
||||||
|
line = order.order_line
|
||||||
|
self.assertTrue(line.batch_product_id)
|
||||||
|
order.with_context(disable_cancel_warning=True).write({"batch_id": False})
|
||||||
|
self.assertFalse(line.batch_product_id)
|
||||||
Loading…
Reference in a new issue