[18.0][MIG] account_invoice_triple_discount_readonly: Port to Odoo 18.0
* Update module version to 18.0.1.0.0 * Remove view modifications as they are handled by parent modules * Add comprehensive test suite (34 tests): - Test triple discount mixin write() method behavior - Test account.move.line with triple discounts - Test purchase.order.line with triple discounts * Add oca_dependencies.txt with required OCA repositories * Fix write() method to handle explicit discounts correctly
This commit is contained in:
parent
67554c95f5
commit
123aabb775
10 changed files with 602 additions and 77 deletions
|
|
@ -0,0 +1,187 @@
|
|||
# Copyright (C) 2025: Criptomart (https://criptomart.net)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestAccountMove(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
# Create a partner
|
||||
cls.partner = cls.env["res.partner"].create({
|
||||
"name": "Test Customer",
|
||||
"email": "customer@test.com",
|
||||
})
|
||||
|
||||
# Create a product
|
||||
cls.product = cls.env["product.product"].create({
|
||||
"name": "Test Product Invoice",
|
||||
"type": "consu",
|
||||
"list_price": 200.0,
|
||||
"standard_price": 100.0,
|
||||
})
|
||||
|
||||
# Create tax
|
||||
cls.tax = cls.env["account.tax"].create({
|
||||
"name": "Test Tax 10%",
|
||||
"amount": 10.0,
|
||||
"amount_type": "percent",
|
||||
"type_tax_use": "sale",
|
||||
})
|
||||
|
||||
# Create an invoice
|
||||
cls.invoice = cls.env["account.move"].create({
|
||||
"move_type": "out_invoice",
|
||||
"partner_id": cls.partner.id,
|
||||
"invoice_date": "2026-01-01",
|
||||
})
|
||||
|
||||
# Create invoice line
|
||||
cls.invoice_line = cls.env["account.move.line"].create({
|
||||
"move_id": cls.invoice.id,
|
||||
"product_id": cls.product.id,
|
||||
"quantity": 5,
|
||||
"price_unit": 200.0,
|
||||
"discount1": 10.0,
|
||||
"discount2": 5.0,
|
||||
"discount3": 2.0,
|
||||
"tax_ids": [(6, 0, [cls.tax.id])],
|
||||
})
|
||||
|
||||
def test_invoice_line_discount_readonly(self):
|
||||
"""Test that discount field is readonly in invoice lines"""
|
||||
field = self.invoice_line._fields["discount"]
|
||||
self.assertTrue(field.readonly, "Discount field should be readonly in invoice lines")
|
||||
|
||||
def test_invoice_line_write_with_explicit_discounts(self):
|
||||
"""Test writing invoice line with explicit discounts"""
|
||||
self.invoice_line.write({
|
||||
"discount": 30.0, # Should be ignored
|
||||
"discount1": 15.0,
|
||||
"discount2": 10.0,
|
||||
"discount3": 5.0,
|
||||
})
|
||||
|
||||
self.assertEqual(self.invoice_line.discount1, 15.0)
|
||||
self.assertEqual(self.invoice_line.discount2, 10.0)
|
||||
self.assertEqual(self.invoice_line.discount3, 5.0)
|
||||
|
||||
def test_invoice_line_legacy_discount(self):
|
||||
"""Test legacy discount behavior in invoice lines"""
|
||||
self.invoice_line.write({
|
||||
"discount": 20.0,
|
||||
})
|
||||
|
||||
# Should map to discount1 and reset others
|
||||
self.assertEqual(self.invoice_line.discount1, 20.0)
|
||||
self.assertEqual(self.invoice_line.discount2, 0.0)
|
||||
self.assertEqual(self.invoice_line.discount3, 0.0)
|
||||
|
||||
def test_invoice_line_price_calculation(self):
|
||||
"""Test that price subtotal is calculated correctly with triple discount"""
|
||||
self.invoice_line.write({
|
||||
"discount1": 10.0,
|
||||
"discount2": 5.0,
|
||||
"discount3": 0.0,
|
||||
})
|
||||
|
||||
# Base: 5 * 200 = 1000
|
||||
# After 10% discount: 900
|
||||
# After 5% discount: 855
|
||||
expected_subtotal = 5 * 200 * 0.9 * 0.95
|
||||
self.assertAlmostEqual(
|
||||
self.invoice_line.price_subtotal, expected_subtotal, places=2
|
||||
)
|
||||
|
||||
def test_multiple_invoice_lines(self):
|
||||
"""Test multiple invoice lines with different discounts"""
|
||||
line2 = self.env["account.move.line"].create({
|
||||
"move_id": self.invoice.id,
|
||||
"product_id": self.product.id,
|
||||
"quantity": 3,
|
||||
"price_unit": 150.0,
|
||||
"discount1": 20.0,
|
||||
"discount2": 10.0,
|
||||
"discount3": 5.0,
|
||||
"tax_ids": [(6, 0, [self.tax.id])],
|
||||
})
|
||||
|
||||
# Verify both lines have correct discounts
|
||||
self.assertEqual(self.invoice_line.discount1, 10.0)
|
||||
self.assertEqual(line2.discount1, 20.0)
|
||||
self.assertEqual(line2.discount2, 10.0)
|
||||
self.assertEqual(line2.discount3, 5.0)
|
||||
|
||||
def test_invoice_line_update_quantity(self):
|
||||
"""Test updating quantity doesn't affect discounts"""
|
||||
initial_discount1 = self.invoice_line.discount1
|
||||
initial_discount2 = self.invoice_line.discount2
|
||||
|
||||
self.invoice_line.write({
|
||||
"quantity": 10,
|
||||
})
|
||||
|
||||
# Discounts should remain unchanged
|
||||
self.assertEqual(self.invoice_line.discount1, initial_discount1)
|
||||
self.assertEqual(self.invoice_line.discount2, initial_discount2)
|
||||
# Quantity should be updated
|
||||
self.assertEqual(self.invoice_line.quantity, 10)
|
||||
|
||||
def test_invoice_line_update_price(self):
|
||||
"""Test updating price doesn't affect discounts"""
|
||||
initial_discount1 = self.invoice_line.discount1
|
||||
|
||||
self.invoice_line.write({
|
||||
"price_unit": 250.0,
|
||||
})
|
||||
|
||||
# Discount should remain unchanged
|
||||
self.assertEqual(self.invoice_line.discount1, initial_discount1)
|
||||
# Price should be updated
|
||||
self.assertEqual(self.invoice_line.price_unit, 250.0)
|
||||
|
||||
def test_invoice_with_zero_discounts(self):
|
||||
"""Test invoice line with all zero discounts"""
|
||||
self.invoice_line.write({
|
||||
"discount1": 0.0,
|
||||
"discount2": 0.0,
|
||||
"discount3": 0.0,
|
||||
})
|
||||
|
||||
# All discounts should be zero
|
||||
self.assertEqual(self.invoice_line.discount, 0.0)
|
||||
self.assertEqual(self.invoice_line.discount1, 0.0)
|
||||
self.assertEqual(self.invoice_line.discount2, 0.0)
|
||||
self.assertEqual(self.invoice_line.discount3, 0.0)
|
||||
|
||||
# Subtotal should be quantity * price
|
||||
expected = 5 * 200
|
||||
self.assertEqual(self.invoice_line.price_subtotal, expected)
|
||||
|
||||
def test_invoice_line_combined_operations(self):
|
||||
"""Test combined operations on invoice line"""
|
||||
# Update multiple fields at once
|
||||
self.invoice_line.write({
|
||||
"quantity": 8,
|
||||
"price_unit": 180.0,
|
||||
"discount1": 12.0,
|
||||
"discount2": 6.0,
|
||||
"discount3": 0.0, # Reset discount3 explicitly
|
||||
})
|
||||
|
||||
# All fields should be updated correctly
|
||||
self.assertEqual(self.invoice_line.quantity, 8)
|
||||
self.assertEqual(self.invoice_line.price_unit, 180.0)
|
||||
self.assertEqual(self.invoice_line.discount1, 12.0)
|
||||
self.assertEqual(self.invoice_line.discount2, 6.0)
|
||||
self.assertEqual(self.invoice_line.discount3, 0.0)
|
||||
|
||||
# Calculate expected subtotal: 8 * 180 * (1-0.12) * (1-0.06)
|
||||
expected = 8 * 180 * 0.88 * 0.94
|
||||
self.assertAlmostEqual(
|
||||
self.invoice_line.price_subtotal, expected, places=2
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue