252 lines
9.8 KiB
Python
252 lines
9.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo.tests import tagged
|
|
from odoo.tests.common import TransactionCase
|
|
from hypothesis import given, strategies as st, settings
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestCustomerAccountFields(TransactionCase):
|
|
"""
|
|
Property-based tests for customer account fields on res.partner model.
|
|
Tests Properties 1, 2, and 3 from the design document.
|
|
"""
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
|
|
|
# Use the default company
|
|
cls.company = cls.env.company
|
|
|
|
# Create income accounts for testing
|
|
cls.income_account_1 = cls.env['account.account'].create({
|
|
'name': 'Test Income Account 1',
|
|
'code': 'TINC001',
|
|
'account_type': 'income',
|
|
})
|
|
|
|
cls.income_account_2 = cls.env['account.account'].create({
|
|
'name': 'Test Income Account 2',
|
|
'code': 'TINC002',
|
|
'account_type': 'income',
|
|
})
|
|
|
|
# Create expense accounts for testing
|
|
cls.expense_account_1 = cls.env['account.account'].create({
|
|
'name': 'Test Expense Account 1',
|
|
'code': 'TEXP001',
|
|
'account_type': 'expense',
|
|
})
|
|
|
|
cls.expense_account_2 = cls.env['account.account'].create({
|
|
'name': 'Test Expense Account 2',
|
|
'code': 'TEXP002',
|
|
'account_type': 'expense',
|
|
})
|
|
|
|
@settings(max_examples=100)
|
|
@given(
|
|
customer_name=st.text(min_size=1, max_size=50, alphabet=st.characters(blacklist_categories=('Cs', 'Cc'))),
|
|
)
|
|
def test_property_1_customer_account_field_visibility(self, customer_name):
|
|
"""
|
|
**Feature: customer-cogs-expense-account, Property 1: Customer account field visibility**
|
|
|
|
For any customer form view in the Accounting page, the income account and expense account
|
|
fields should be visible in the Accounting Entries section below the Account Payable field.
|
|
|
|
**Validates: Requirements 1.1, 1.2**
|
|
"""
|
|
# Create a customer
|
|
partner = self.env['res.partner'].with_company(self.company).create({
|
|
'name': customer_name,
|
|
'company_id': self.company.id,
|
|
})
|
|
|
|
# Verify that the fields exist on the model
|
|
self.assertIn(
|
|
'property_account_income_customer_id',
|
|
partner._fields,
|
|
"Income account field should exist on res.partner model"
|
|
)
|
|
self.assertIn(
|
|
'property_account_expense_customer_id',
|
|
partner._fields,
|
|
"Expense account field should exist on res.partner model"
|
|
)
|
|
|
|
# Verify field properties
|
|
income_field = partner._fields['property_account_income_customer_id']
|
|
expense_field = partner._fields['property_account_expense_customer_id']
|
|
|
|
# Check that fields are Many2one to account.account
|
|
self.assertEqual(
|
|
income_field.type,
|
|
'many2one',
|
|
"Income account field should be Many2one type"
|
|
)
|
|
self.assertEqual(
|
|
income_field.comodel_name,
|
|
'account.account',
|
|
"Income account field should reference account.account"
|
|
)
|
|
self.assertEqual(
|
|
expense_field.type,
|
|
'many2one',
|
|
"Expense account field should be Many2one type"
|
|
)
|
|
self.assertEqual(
|
|
expense_field.comodel_name,
|
|
'account.account',
|
|
"Expense account field should reference account.account"
|
|
)
|
|
|
|
# Verify fields are company-dependent (property fields)
|
|
self.assertTrue(
|
|
income_field.company_dependent,
|
|
"Income account field should be company-dependent"
|
|
)
|
|
self.assertTrue(
|
|
expense_field.company_dependent,
|
|
"Expense account field should be company-dependent"
|
|
)
|
|
|
|
# Verify fields are accessible (can read/write)
|
|
partner.write({
|
|
'property_account_income_customer_id': self.income_account_1.id,
|
|
'property_account_expense_customer_id': self.expense_account_1.id,
|
|
})
|
|
|
|
self.assertEqual(
|
|
partner.property_account_income_customer_id.id,
|
|
self.income_account_1.id,
|
|
"Income account field should be readable and writable"
|
|
)
|
|
self.assertEqual(
|
|
partner.property_account_expense_customer_id.id,
|
|
self.expense_account_1.id,
|
|
"Expense account field should be readable and writable"
|
|
)
|
|
|
|
@settings(max_examples=100)
|
|
@given(
|
|
customer_name=st.text(min_size=1, max_size=50, alphabet=st.characters(blacklist_categories=('Cs', 'Cc'))),
|
|
)
|
|
def test_property_2_customer_account_persistence(self, customer_name):
|
|
"""
|
|
**Feature: customer-cogs-expense-account, Property 2: Customer account persistence**
|
|
|
|
For any customer record with income or expense accounts set,
|
|
saving and reloading the record should preserve the account values.
|
|
|
|
**Validates: Requirements 1.5, 1.6**
|
|
"""
|
|
# Create a customer with income and expense accounts
|
|
partner = self.env['res.partner'].with_company(self.company).create({
|
|
'name': customer_name,
|
|
'company_id': self.company.id,
|
|
'property_account_income_customer_id': self.income_account_1.id,
|
|
'property_account_expense_customer_id': self.expense_account_1.id,
|
|
})
|
|
|
|
# Flush to database
|
|
partner.flush_recordset()
|
|
|
|
# Reload the partner from database
|
|
partner_reloaded = self.env['res.partner'].browse(partner.id)
|
|
|
|
# Verify accounts are preserved
|
|
self.assertEqual(
|
|
partner_reloaded.property_account_income_customer_id.id,
|
|
self.income_account_1.id,
|
|
"Income account should be preserved after save and reload"
|
|
)
|
|
self.assertEqual(
|
|
partner_reloaded.property_account_expense_customer_id.id,
|
|
self.expense_account_1.id,
|
|
"Expense account should be preserved after save and reload"
|
|
)
|
|
|
|
@settings(max_examples=100)
|
|
@given(
|
|
customer_name=st.text(min_size=1, max_size=50, alphabet=st.characters(blacklist_categories=('Cs', 'Cc'))),
|
|
has_income=st.booleans(),
|
|
has_expense=st.booleans(),
|
|
)
|
|
def test_property_3_empty_account_acceptance(self, customer_name, has_income, has_expense):
|
|
"""
|
|
**Feature: customer-cogs-expense-account, Property 3: Empty account acceptance**
|
|
|
|
For any customer record, leaving income or expense account fields empty
|
|
should not trigger validation errors.
|
|
|
|
**Validates: Requirements 1.7, 1.8**
|
|
"""
|
|
# Prepare account values (may be empty)
|
|
income_account_id = self.income_account_1.id if has_income else False
|
|
expense_account_id = self.expense_account_1.id if has_expense else False
|
|
|
|
# Create partner with potentially empty accounts
|
|
partner = self.env['res.partner'].with_company(self.company).create({
|
|
'name': customer_name,
|
|
'company_id': self.company.id,
|
|
'property_account_income_customer_id': income_account_id,
|
|
'property_account_expense_customer_id': expense_account_id,
|
|
})
|
|
|
|
# Verify partner was created successfully
|
|
self.assertTrue(partner.id, "Partner should be created even with empty account fields")
|
|
|
|
# Verify the account values match what was set
|
|
if has_income:
|
|
self.assertEqual(partner.property_account_income_customer_id.id, self.income_account_1.id)
|
|
else:
|
|
self.assertFalse(partner.property_account_income_customer_id, "Income account should be empty")
|
|
|
|
if has_expense:
|
|
self.assertEqual(partner.property_account_expense_customer_id.id, self.expense_account_1.id)
|
|
else:
|
|
self.assertFalse(partner.property_account_expense_customer_id, "Expense account should be empty")
|
|
|
|
def test_helper_methods(self):
|
|
"""
|
|
Test the helper methods _get_customer_income_account() and _get_customer_expense_account().
|
|
"""
|
|
# Create partner with accounts
|
|
partner_with_accounts = self.env['res.partner'].with_company(self.company).create({
|
|
'name': 'Partner With Accounts',
|
|
'company_id': self.company.id,
|
|
'property_account_income_customer_id': self.income_account_1.id,
|
|
'property_account_expense_customer_id': self.expense_account_1.id,
|
|
})
|
|
|
|
# Test helper methods return correct accounts
|
|
self.assertEqual(
|
|
partner_with_accounts._get_customer_income_account().id,
|
|
self.income_account_1.id,
|
|
"Helper method should return income account"
|
|
)
|
|
self.assertEqual(
|
|
partner_with_accounts._get_customer_expense_account().id,
|
|
self.expense_account_1.id,
|
|
"Helper method should return expense account"
|
|
)
|
|
|
|
# Create partner without accounts
|
|
partner_without_accounts = self.env['res.partner'].with_company(self.company).create({
|
|
'name': 'Partner Without Accounts',
|
|
'company_id': self.company.id,
|
|
})
|
|
|
|
# Test helper methods return False when no accounts set
|
|
self.assertFalse(
|
|
partner_without_accounts._get_customer_income_account(),
|
|
"Helper method should return False when no income account set"
|
|
)
|
|
self.assertFalse(
|
|
partner_without_accounts._get_customer_expense_account(),
|
|
"Helper method should return False when no expense account set"
|
|
)
|