196 lines
8.2 KiB
Python
196 lines
8.2 KiB
Python
from odoo.tests import TransactionCase, tagged
|
||
from odoo.exceptions import ValidationError
|
||
|
||
|
||
@tagged('post_install', '-at_install')
|
||
class TestCommService(TransactionCase):
|
||
|
||
@classmethod
|
||
def setUpClass(cls):
|
||
super().setUpClass()
|
||
cls.company = cls.env.company
|
||
cls.partner = cls.env['res.partner'].create({'name': 'Арендатор ООО'})
|
||
cls.btype = cls.env['comm.btype'].create({'name': 'Офис'})
|
||
cls.building = cls.env['comm.building'].create({
|
||
'name': '101', 'type': cls.btype.id,
|
||
})
|
||
cls.ctype = cls.env['comm.countertype'].create({
|
||
'name': 'Электроэнергия',
|
||
'uom': cls.env.ref('uom.product_uom_unit').id,
|
||
})
|
||
cls.product = cls.env['product.product'].create({
|
||
'name': 'Аренда офиса',
|
||
'type': 'service',
|
||
'lst_price': 1000.0,
|
||
})
|
||
cls.contract = cls.env['comm.contract'].create({
|
||
'name': 'АР-001',
|
||
'partner_id': cls.partner.id,
|
||
'company_id': cls.company.id,
|
||
'building_id': cls.building.id,
|
||
'state': 'open',
|
||
'date_start': '2026-01-01',
|
||
'date_end': '2026-12-31',
|
||
})
|
||
|
||
# ------------------------------------------------------------------
|
||
def test_building_display_name(self):
|
||
self.assertEqual(self.building.display_name, 'Офис 101')
|
||
|
||
def test_building_busy_and_free(self):
|
||
# Действующий договор занимает объект.
|
||
self.assertEqual(self.building.busy_until, self.contract.date_end)
|
||
self.assertFalse(self.building.is_free)
|
||
# Свободный объект без договора.
|
||
free_building = self.env['comm.building'].create({'name': '202'})
|
||
self.assertTrue(free_building.is_free)
|
||
found = self.env['comm.building'].search([('is_free', '=', True)])
|
||
self.assertIn(free_building, found)
|
||
self.assertNotIn(self.building, found)
|
||
|
||
def test_commercial_partner(self):
|
||
parent = self.env['res.partner'].create({
|
||
'name': 'Головная компания', 'is_company': True,
|
||
})
|
||
self.partner.parent_id = parent
|
||
self.contract._compute_commercial_partner_id()
|
||
self.assertEqual(self.contract.commercial_partner_id, parent)
|
||
|
||
# ------------------------------------------------------------------
|
||
def test_counter_value_constraints(self):
|
||
counter = self.env['comm.counter'].create({
|
||
'name': 'С-1', 'type': self.ctype.id, 'contract_id': self.contract.id,
|
||
})
|
||
self.env['comm.counterval'].create({
|
||
'name': 100.0, 'year': 2026, 'month': 1, 'counter_id': counter.id,
|
||
})
|
||
# Показание не может быть меньше предыдущего.
|
||
with self.assertRaises(ValidationError):
|
||
self.env['comm.counterval'].create({
|
||
'name': 90.0, 'year': 2026, 'month': 2, 'counter_id': counter.id,
|
||
})
|
||
# Ноль запрещён.
|
||
with self.assertRaises(ValidationError):
|
||
self.env['comm.counterval'].create({
|
||
'name': 0.0, 'year': 2026, 'month': 3, 'counter_id': counter.id,
|
||
})
|
||
|
||
def test_counter_last_value_and_period(self):
|
||
counter = self.env['comm.counter'].create({
|
||
'name': 'С-2', 'type': self.ctype.id, 'contract_id': self.contract.id,
|
||
})
|
||
self.env['comm.counterval'].create({
|
||
'name': 100.0, 'year': 2026, 'month': 1, 'counter_id': counter.id,
|
||
})
|
||
self.env['comm.counterval'].create({
|
||
'name': 150.0, 'year': 2026, 'month': 2, 'counter_id': counter.id,
|
||
})
|
||
counter.invalidate_recordset()
|
||
self.assertEqual(counter.last_value_val, 150.0)
|
||
self.assertEqual(counter.last_period, '2026-2')
|
||
|
||
# ------------------------------------------------------------------
|
||
def test_create_flat_invoice(self):
|
||
self.env['comm.contractline'].create({
|
||
'contract_id': self.contract.id,
|
||
'product_id': self.product.id,
|
||
'price': 5000.0,
|
||
'period': 'month',
|
||
})
|
||
result = self.contract.create_invoice(year=2026, month=3)
|
||
self.assertIn('Создано начисление', result)
|
||
invoice = self.env['account.move'].search([
|
||
('comm_contract_id', '=', self.contract.id),
|
||
])
|
||
self.assertEqual(len(invoice), 1)
|
||
self.assertEqual(invoice.move_type, 'out_invoice')
|
||
self.assertEqual(invoice.year, 2026)
|
||
self.assertEqual(invoice.month, 3)
|
||
self.assertAlmostEqual(invoice.amount_untaxed, 5000.0)
|
||
|
||
def test_no_duplicate_invoice(self):
|
||
self.env['comm.contractline'].create({
|
||
'contract_id': self.contract.id,
|
||
'product_id': self.product.id,
|
||
'price': 5000.0,
|
||
'period': 'month',
|
||
})
|
||
self.contract.create_invoice(year=2026, month=4)
|
||
result = self.contract.create_invoice(year=2026, month=4)
|
||
self.assertIn('уже есть в базе', result)
|
||
invoices = self.env['account.move'].search([
|
||
('comm_contract_id', '=', self.contract.id),
|
||
('invoice_origin', 'like', '2026-4'),
|
||
])
|
||
self.assertEqual(len(invoices), 1)
|
||
|
||
def test_quarterly_period_skips_off_months(self):
|
||
self.env['comm.contractline'].create({
|
||
'contract_id': self.contract.id,
|
||
'product_id': self.product.id,
|
||
'price': 3000.0,
|
||
'period': 'quarter',
|
||
})
|
||
# Февраль — не начало квартала, начисления быть не должно.
|
||
self.contract.create_invoice(year=2026, month=2)
|
||
self.assertFalse(self.env['account.move'].search([
|
||
('comm_contract_id', '=', self.contract.id),
|
||
]))
|
||
# Апрель — начало квартала.
|
||
self.contract.create_invoice(year=2026, month=4)
|
||
self.assertTrue(self.env['account.move'].search([
|
||
('comm_contract_id', '=', self.contract.id),
|
||
]))
|
||
|
||
def test_counter_based_invoice(self):
|
||
counter = self.env['comm.counter'].create({
|
||
'name': 'С-3', 'type': self.ctype.id, 'contract_id': self.contract.id,
|
||
})
|
||
self.env['comm.counterval'].create({
|
||
'name': 100.0, 'year': 2026, 'month': 4, 'counter_id': counter.id,
|
||
})
|
||
self.env['comm.counterval'].create({
|
||
'name': 130.0, 'year': 2026, 'month': 5, 'counter_id': counter.id,
|
||
})
|
||
self.env['comm.contractline'].create({
|
||
'contract_id': self.contract.id,
|
||
'product_id': self.product.id,
|
||
'counter_id': counter.id,
|
||
'price': 7.0,
|
||
'period': 'month',
|
||
})
|
||
result = self.contract.create_invoice(year=2026, month=5)
|
||
self.assertIn('потребление', result)
|
||
invoice = self.env['account.move'].search([
|
||
('comm_contract_id', '=', self.contract.id),
|
||
])
|
||
self.assertEqual(len(invoice), 1)
|
||
# Расход = 130 - 100 = 30 единиц по 7 = 210.
|
||
self.assertAlmostEqual(invoice.amount_untaxed, 210.0)
|
||
|
||
def test_create_invoice_wizard(self):
|
||
self.env['comm.contractline'].create({
|
||
'contract_id': self.contract.id,
|
||
'product_id': self.product.id,
|
||
'price': 5000.0,
|
||
'period': 'month',
|
||
})
|
||
wizard = self.env['comm.createinv'].create({'year': 2026, 'month': 6})
|
||
wizard.fill_contracts()
|
||
self.assertIn(self.contract, wizard.contract_ids)
|
||
wizard.do_creation()
|
||
self.assertTrue(wizard.invoice_created)
|
||
self.assertTrue(self.env['account.move'].search([
|
||
('comm_contract_id', '=', self.contract.id),
|
||
]))
|
||
|
||
def test_wizard_bad_period_raises(self):
|
||
with self.assertRaises(ValidationError):
|
||
self.env['comm.createinv'].create({'year': 2000, 'month': 6})
|
||
|
||
def test_report_helper_available(self):
|
||
report = self.env['report.ruodoo_commservice.report_inv_1c']
|
||
values = report._get_report_values([])
|
||
self.assertIn('helper', values)
|
||
self.assertEqual(values['helper'].rubles(1234.56), values['helper'].rubles(1234.56))
|