# -*- coding: utf-8 -*- from odoo.tests import TransactionCase, tagged @tagged('post_install', '-at_install') class TestPersInfo(TransactionCase): """Персонифицированные сведения (NO_PERSSVFL 5.01): автозаполнение, XML.""" @classmethod def setUpClass(cls): super().setUpClass() cls.company = cls.env.company cls.company.write({ 'rsbu_tax_office_code': '5050', }) cls.company.partner_id.write({'inn': '5050164162', 'kpp': '505001001'}) user = cls.env['res.users'].search([], limit=1) cls.company.rsbu_signatory_id = user.id user.partner_id.write({'name': 'Коробков Сергей Васильевич'}) cls.emp1 = cls.env['hr.employee'].create({ 'name': 'Горский Алексей Алексеевич', 'company_id': cls.company.id, 'rsbu_snils': '195-652-650 11', 'rsbu_inn': '780604730641', 'rsbu_insured_category': 'НР'}) cls.emp2 = cls.env['hr.employee'].create({ 'name': 'Ефимова Анна Александровна', 'company_id': cls.company.id, 'rsbu_snils': '162-601-022 16', 'rsbu_inn': '742210150850', 'rsbu_insured_category': 'НР'}) cls.Summary = cls.env['rsbu.rsv.summary'] cls.Psv = cls.env['rsbu.pers.info'] def _summary(self, emp, month, payments): return self.Summary.create({ 'company_id': self.company.id, 'employee_id': emp.id, 'year': 2026, 'month': month, 'insured_category': 'НР', 'payments': payments, 'base': payments}) def test_01_autofill_from_summary(self): """Строки заполняются по сотрудникам с выплатами за месяц.""" self._summary(self.emp1, 9, 80000.0) self._summary(self.emp2, 9, 65000.0) psv = self.Psv.create({ 'year': 2026, 'month': 9, 'company_id': self.company.id}) psv.fill_lines() self.assertEqual(len(psv.line_ids), 2) l1 = psv.line_ids.filtered(lambda l: l.employee_id == self.emp1) self.assertAlmostEqual(l1.amount, 80000.0, 2) self.assertEqual(l1.snils, '195-652-650 11') def test_02_snils_normalized(self): """СНИЛС нормализуется к формату NNN-NNN-NNN-NN (дефисы).""" psv = self.Psv.create({ 'year': 2026, 'month': 9, 'company_id': self.company.id}) self.assertEqual(psv._snils('195-652-650 11'), '195-652-650-11') self.assertEqual(psv._snils('19565265011'), '195-652-650-11') def test_03_xml_valid_against_xsd(self): """Сгенерированный ПСВ проходит XSD 5.01.""" self._summary(self.emp1, 9, 80000.0) self._summary(self.emp2, 9, 65000.0) psv = self.Psv.create({ 'year': 2026, 'month': 9, 'company_id': self.company.id}) psv.fill_lines() fname = psv._psv_xml_filename() xml_bytes = psv._psv_build_xml(filename=fname) ok, errors = psv._psv_validate_xml(xml_bytes) self.assertTrue(ok, 'ПСВ не прошёл XSD: %s' % '; '.join(errors[:8])) self.assertIn(b'windows-1251', xml_bytes[:60]) self.assertTrue(fname.startswith('NO_PERSSVFL_')) from lxml import etree root = etree.fromstring(xml_bytes) self.assertEqual(root.get('ИдФайл'), fname) doc = root.find('Документ') self.assertEqual(doc.get('КНД'), '1151162') self.assertEqual(doc.get('Период'), '09') pers = doc.findall('ПерсСвФЛ') self.assertEqual(len(pers), 2) # СНИЛС в XML — с дефисами (как требует XSD). self.assertEqual(pers[0].get('СНИЛС'), '195-652-650-11')