# Part of the odoo-at-payroll project. License: LGPL-3. """Tests: Dokumentgenerierung aus Vorlagen. Rendering der eigenen Vorlagentexte (werte['key']-Platzhalter), Auto-Werte aus hr-Stammdaten, Pflichtfeld-Validierung, hr.version-Stichtagsauflösung, generisches Druck-Template und Anhang-Ablage (PDF wenn wkhtmltopdf verfügbar, sonst HTML-Fallback).""" import base64 import datetime from odoo.exceptions import AccessError, UserError from odoo.tests import TransactionCase, tagged @tagged('post_install', '-at_install') class DokumenteTest(TransactionCase): def setUp(self): super().setUp() self.company = self.env.company self.company.write({'name': 'Musterwerkstatt GmbH'}) employee = self.env['hr.employee'].create({ 'name': 'Dokument Test'}) version = self.env['hr.version'].search( [('employee_id', '=', employee.id)], limit=1) version.write({ 'date_version': datetime.date(2020, 1, 1), 'contract_date_start': datetime.date(2020, 1, 1), 'job_title': 'Techniker', 'private_street': 'Testgasse 1', 'private_zip': '1010', 'private_city': 'Wien', }) self.employee = employee self.version = version self.vorlage = self.env['l10n.at.payroll.dokument.vorlage'].create({ 'name': 'Testbescheinigung', 'thema': 'bescheinigung', 'kb_ref': 'lb-test', 'rechtsstatus': 'entwurf', 'inhalt_html': '

Firma: {{ werte[\'firma\'] }}

' '

Mitarbeiter: {{ werte[\'mitarbeiter\'] }}

' '

Funktion: {{ werte[\'funktion\'] }}

' '

EAD: {{ werte[\'ead\'] }}

' '

Zusatz: {{ werte[\'zusatz\'] }}

', 'feld_ids': [ (0, 0, {'sequence': 1, 'key': 'zusatz', 'quelle': 'manuell', 'pflicht': True, 'bezeichnung': 'Zusatzangabe'}), (0, 0, {'sequence': 2, 'key': 'firma', 'quelle': 'auto', 'pflicht': True}), (0, 0, {'sequence': 3, 'key': 'mitarbeiter', 'quelle': 'auto', 'pflicht': True}), (0, 0, {'sequence': 4, 'key': 'funktion', 'quelle': 'auto', 'pflicht': False}), (0, 0, {'sequence': 5, 'key': 'ead', 'quelle': 'auto', 'pflicht': False}), ], }) def _wizard(self): wizard = self.env['l10n.at.payroll.dokument.wizard'].create({ 'vorlage_id': self.vorlage.id, 'employee_id': self.employee.id, 'datum': datetime.date(2026, 1, 15), }) wizard.action_befuellen() return wizard def test_01_auto_werte(self): wizard = self._wizard() wizard.feld_wert_ids.filtered( lambda l: l.key == 'zusatz').wert = 'X' werte = wizard._at_werte() self.assertEqual(werte['firma'], 'Musterwerkstatt GmbH') self.assertEqual(werte['mitarbeiter'], 'Dokument Test') self.assertEqual(werte['funktion'], 'Techniker') self.assertTrue(werte['ead']) def test_02_vorschau_ersetzt_platzhalter(self): wizard = self._wizard() wizard.feld_wert_ids.filtered( lambda l: l.key == 'zusatz').wert = 'Projekt Alpha' wizard.action_vorschau() vorschau = wizard.vorschau_html self.assertIn('Musterwerkstatt GmbH', vorschau) self.assertIn('Dokument Test', vorschau) self.assertIn('Projekt Alpha', vorschau) self.assertNotIn('{{', vorschau) def test_03_pflichtfeld_leist_user_error(self): wizard = self._wizard() with self.assertRaises(UserError): wizard._at_werte() def test_04_version_am_stichtag(self): self.env['hr.version'].create({ 'employee_id': self.employee.id, 'date_version': datetime.date(2026, 3, 1), 'job_title': 'Senior Techniker', }) wizard = self._wizard() self.assertEqual(wizard.version_id.job_title, 'Techniker') wizard.datum = datetime.date(2026, 6, 1) wizard._compute_version_id() self.assertEqual(wizard.version_id.job_title, 'Senior Techniker') def test_05_pdf_ablegt_anhang(self): wizard = self._wizard() wizard.feld_wert_ids.filtered( lambda l: l.key == 'zusatz').wert = 'Fall 5' wizard.action_pdf() anh = self.env['ir.attachment'].search( [('res_model', '=', 'hr.employee'), ('res_id', '=', self.employee.id)]) self.assertEqual(len(anh), 1) self.assertIn(anh.mimetype, ('application/pdf', 'text/html')) if anh.mimetype == 'text/html': html = base64.b64decode(anh.datas).decode('utf-8') self.assertIn('Fall 5', html) def test_06_report_values_generic(self): wizard = self._wizard() report = self.env[ 'report.l10n_at_payroll_dokumente' '.report_dokument_generisch'] values = report._get_report_values( wizard.ids, data={'titel': 'T', 'body': '

Body

'}) self.assertEqual(str(values['body']), '

Body

') html_content, _typ = self.env['ir.actions.report']._render_qweb_html( 'l10n_at_payroll_dokumente.action_report_dokument_generisch', wizard.ids, data={'titel': 'T', 'body': values['body']}) self.assertIn('Body', str(html_content)) def test_07_access_hr_user_lesen_manager_schreiben(self): hr_user = self.env['res.users'].create({ 'name': 'Dokument Lesetest', 'login': 'dok_lesetest', 'group_ids': [(4, self.env.ref('hr.group_hr_user').id)], }) umgebung = self.env(user=hr_user.id) self.assertTrue( umgebung['l10n.at.payroll.dokument.vorlage'].browse( self.vorlage.id).name) kein_hr = self.env['res.users'].create({ 'name': 'Dokument Ohne HR', 'login': 'dok_ohne_hr', 'group_ids': [(4, self.env.ref('base.group_user').id)], }) ohne = self.env(user=kein_hr.id) with self.assertRaises(AccessError): ohne['l10n.at.payroll.dokument.vorlage'].browse( self.vorlage.id).name def test_08_pilot_vorlagen_installiert(self): for xmlid in ('vorlage_dienstvertrag_angestellte', 'vorlage_kuendigung_dienstgeber', 'vorlage_einvernehmliche_aufloesung', 'vorlage_vordienstzeiten'): vorlage = self.env.ref( 'l10n_at_payroll_dokumente.%s' % xmlid) self.assertTrue(vorlage.inhalt_html) self.assertEqual(vorlage.rechtsstatus, 'entwurf') kuendigung = self.env.ref( 'l10n_at_payroll_dokumente.vorlage_kuendigung_dienstgeber') wizard = self.env['l10n.at.payroll.dokument.wizard'].create({ 'vorlage_id': kuendigung.id, 'employee_id': self.employee.id, 'datum': datetime.date(2026, 9, 1), }) wizard.action_befuellen() wizard.feld_wert_ids.filtered( lambda l: l.key == 'anrede').wert = 'Sehr geehrter Herr' wizard.feld_wert_ids.filtered( lambda l: l.key == 'kuendigung_frist').wert = '6 Wochen' wizard.feld_wert_ids.filtered( lambda l: l.key == 'beendigungstermin').wert = '31.10.2026' wizard.feld_wert_ids.filtered( lambda l: l.key == 'ort_datum').wert = 'Wien, 1.9.2026' wizard.action_vorschau() self.assertIn('31.10.2026', wizard.vorschau_html) self.assertIn('Musterwerkstatt GmbH', wizard.vorschau_html)