diff --git a/odoo/cli/scaffold.py b/odoo/cli/scaffold.py index ea861dffec1..aa1fdac629a 100644 --- a/odoo/cli/scaffold.py +++ b/odoo/cli/scaffold.py @@ -32,10 +32,20 @@ class Scaffold(Command): sys.exit(parser.print_help()) args = parser.parse_args(args=cmdargs) + if args.template.id == 'l10n_payroll': + name_split = args.name.split('-') + params = { + 'name': name_split[0], + 'code': name_split[1] + } + else: + params = {'name': args.name} + args.template.render_to( snake(args.name), directory(args.dest, create=True), - {'name': args.name}) + params=params, + ) def epilog(self): return "Built-in templates available are: %s" % ', '.join( @@ -109,11 +119,14 @@ class template(object): """ # overwrite with local for path, content in self.files(): + path = env.from_string(path).render(params) local = os.path.relpath(path, self.path) # strip .template extension root, ext = os.path.splitext(local) if ext == '.template': local = root + if self.id == "l10n_payroll": + modname = f"l10n_{params['code']}_hr_payroll" dest = os.path.join(directory, modname, local) destdir = os.path.dirname(dest) if not os.path.exists(destdir): @@ -126,6 +139,7 @@ class template(object): env.from_string(content.decode('utf-8'))\ .stream(params or {})\ .dump(f, encoding='utf-8') + f.write(b'\n') def die(message, code=1): print(message, file=sys.stderr) diff --git a/odoo/cli/templates/l10n_payroll/__init__.py.template b/odoo/cli/templates/l10n_payroll/__init__.py.template new file mode 100644 index 00000000000..d6210b1285d --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/__init__.py.template @@ -0,0 +1,3 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/odoo/cli/templates/l10n_payroll/__manifest__.py.template b/odoo/cli/templates/l10n_payroll/__manifest__.py.template new file mode 100644 index 00000000000..741c03f432b --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/__manifest__.py.template @@ -0,0 +1,36 @@ +{%- set countryPascal = name|pascal -%} +{%- set codeUpper = code|upper -%} +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': '{{countryPascal}} - Payroll', + 'countries': ['{{code}}'], + 'category': 'Human Resources/Payroll', + 'depends': ['hr_payroll'], + 'version': '1.0', + 'description': """ +''Country-ish'' Payroll Rules. +============================== + + * Employee Details + * Employee Contracts + * Passport based Contract + * Allowances/Deductions + * Allow to configure Basic/Gross/Net Salary + * Employee Payslip + * Integrated with Leaves Management + """, + 'data': [ + 'data/hr_salary_rule_category_data.xml', + 'data/hr_payroll_structure_type_data.xml', + 'views/hr_payroll_report.xml', + 'data/hr_payroll_structure_data.xml', + 'data/hr_rule_parameters_data.xml', + 'data/hr_salary_rule_data.xml', + 'views/report_payslip_templates.xml', + ], + 'demo': [ + 'data/l10n_{{code}}_hr_payroll_demo.xml', + ], + 'license': 'OEEL-1', +} diff --git a/odoo/cli/templates/l10n_payroll/data/hr_payroll_structure_data.xml.template b/odoo/cli/templates/l10n_payroll/data/hr_payroll_structure_data.xml.template new file mode 100644 index 00000000000..064bdaa3731 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/data/hr_payroll_structure_data.xml.template @@ -0,0 +1,14 @@ +{%- set countryPascal = name|pascal -%} +{%- set codeUpper = code|upper -%} + + + {{countryPascal}}: Regular Pay + {{codeUpper}}MONTHLY + + + + + + + + diff --git a/odoo/cli/templates/l10n_payroll/data/hr_payroll_structure_type_data.xml.template b/odoo/cli/templates/l10n_payroll/data/hr_payroll_structure_type_data.xml.template new file mode 100644 index 00000000000..0856aa42e19 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/data/hr_payroll_structure_type_data.xml.template @@ -0,0 +1,8 @@ +{%- set countryPascal = name|pascal -%} + + + {{countryPascal}}: Employee + + + + diff --git a/odoo/cli/templates/l10n_payroll/data/hr_rule_parameters_data.xml.template b/odoo/cli/templates/l10n_payroll/data/hr_rule_parameters_data.xml.template new file mode 100644 index 00000000000..b26fd8dd778 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/data/hr_rule_parameters_data.xml.template @@ -0,0 +1,51 @@ +{%- set countryPascal = name|pascal -%} +{%- set codeUpper = code|upper -%} + + + {{countryPascal}}: Pension Contribution Employee Rate + l10n_{{code}}_social_employee_rate + + + + -9.76 + + + + + + {{countryPascal}}: Pension Contribution Employer Rate + l10n_{{code}}_social_employer_rate + + + + 9.76 + + + + + + {{countryPascal}}: Tax Brackets + l10n_{{code}}_tax_brackets + + + + [ + ( 0, 10000, 0, 5), + (10000, 30000, 500, 10), + (30000, 'inf', 2000, 5), + ] + + + + + + {{countryPascal}}: Chilcare Relief + l10n_{{code}}_childcare_relief + + + + [92.67, 92.67, 166.67, 225] + + + + diff --git a/odoo/cli/templates/l10n_payroll/data/hr_salary_rule_category_data.xml.template b/odoo/cli/templates/l10n_payroll/data/hr_salary_rule_category_data.xml.template new file mode 100644 index 00000000000..f29a8d78e1a --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/data/hr_salary_rule_category_data.xml.template @@ -0,0 +1,35 @@ +{%- set countryPascal = name|pascal -%} +{%- set codeUpper = code|upper -%} + + + {{countryPascal}}: Social Security Employee + SOCIAL.EMPLOYEE + + + + + {{countryPascal}}: Social Security Employer + SOCIAL.EMPLOYER + + + + {{countryPascal}}: Social Security Employee (TOTAL) + SOCIALTOTAL.EMPLOYEE + + + + {{countryPascal}}: Social Security Employer (TOTAL) + SOCIALTOTAL.EMPLOYER + + + + {{countryPascal}}: Taxable Amount + TAXABLE + + + + {{countryPascal}}: Withholding Taxes + TAX + + + diff --git a/odoo/cli/templates/l10n_payroll/data/hr_salary_rule_data.xml.template b/odoo/cli/templates/l10n_payroll/data/hr_salary_rule_data.xml.template new file mode 100644 index 00000000000..185a9971d61 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/data/hr_salary_rule_data.xml.template @@ -0,0 +1,131 @@ +{%- set countryPascal = name|pascal -%} + + + + + {{countryPascal}}: Social Contribution + SOCIAL.EMPLOYEE + 50 + none + code + +result_rate = payslip.rule_parameter('l10n_{{code}}_social_employee_rate') +result = categories.BASIC + + + + + + + + {{countryPascal}}: Social Contribution (Employer) + SOCIAL.EMPLOYER + 50 + none + code + +result_rate = payslip.rule_parameter('l10n_{{code}}_social_employer_rate') +result = categories.BASIC + + + + + + + + + {{countryPascal}}: Social Security Total (Employee) + SOCIAL.EMPLOYEE.TOTAL + 70 + none + code + +result = categories['SOCIAL.EMPLOYEE'] + + + + + + + + + {{countryPascal}}: Social Security Total (Employer) + SOCIAL.EMPLOYER.TOTAL + 70 + none + code + +result = categories['SOCIAL.EMPLOYER'] + + + + + + + + + {{countryPascal}}: Taxable Amount + TAXABLE + 115 + none + code + +result = categories.GROSS + + + + + + + + + {{countryPascal}}: Withholding Taxes + TAX + 150 + none + code + +taxable = categories.TAXABLE +brackets = payslip.rule_parameter('l10n_{{code}}_tax_brackets') +for low, high, prev, rate in brackets: + if high == 'inf': + high = float('inf') + else: + if low <= taxable < high: + result = -(prev + (taxable - low) * rate / 100) + + + + + + + + + {{countryPascal}}: Childcare relief + CHILD + 165 + none + code + +children = payslip.dict.employee_id.children +amounts = payslip.rule_parameter('l10n_{{code}}_childcare_relief') +if not children: + result = 0 +elif children == 1: + result = amounts[0] +elif children == 2: + result = amounts[0] + amounts[1] +elif children == 3: + result = amounts[0] + amounts[1] + amounts[2] +elif children >= 4: + result = amounts[0] + amounts[1] + amounts[2] + (children - 3) * amounts[3] + + + + + + + diff --git a/odoo/cli/templates/l10n_payroll/data/l10n_{{code}}_hr_payroll_demo.xml.template b/odoo/cli/templates/l10n_payroll/data/l10n_{{code}}_hr_payroll_demo.xml.template new file mode 100644 index 00000000000..9ff8c38274d --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/data/l10n_{{code}}_hr_payroll_demo.xml.template @@ -0,0 +1,147 @@ +{%- set countryPascal = name|pascal -%} +{%- set codeUpper = code|upper -%} + + + My ''country-ish'' Company + + 34A, Vilijos g. + 02243 + Vilnius + + + + + + + + + + + + + RD {{codeUpper}} + + + + + Experienced Developer {{codeUpper}} + + 5 + + + + + Błażej Czarnecki + + + + male + + + + Antonina Kaczmarczyk + Wczasowa 84A/39 + Magdalenka + 15584 + + 0048 025 446 527 + antonina.kaczmarczyk@example.com + + + + + + antoninakaczmarczyk + antoninakaczmarczyk + --
+A. Kaczmarczyk
+ + + +
+ + + {{codeUpper}} Offices + Bogusławskiego Wojciecha, 61/70 + Zgorzelec + 26200 + + + + + + Antonina Kaczmarczyk + Księżycowa 14/69 + Kamienica Królewska + 55616 + + 0048 391 443 088 + antonina.kaczmarczyk@example.com + + private + + + + {{codeUpper}}20002904010518489266398616 + + + + + + + Antonina Kaczmarczyk (fpo) + female + single + Software Developer + + + Mariusz Kaczmarczyk + 0048(07)4975784 + 1991-07-28 + 25 + {{countryPascal}} + + master + Civil Engineering + Université Catholique de Louvain-la-Neuve + + + + 8752027365496 + + + + + + + CDI - Antonina Kaczmarczyk - Experienced Developer + + + + + 3000 + close + + + + + + + + + CDI - Antonina Kaczmarczyk - Experienced Developer + + + + + 3600 + open + + + + + + + + + +
diff --git a/odoo/cli/templates/l10n_payroll/models/__init__.py.template b/odoo/cli/templates/l10n_payroll/models/__init__.py.template new file mode 100644 index 00000000000..01172209c03 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/models/__init__.py.template @@ -0,0 +1,5 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import hr_payslip +from . import hr_contract +from . import hr_payslip_worked_days diff --git a/odoo/cli/templates/l10n_payroll/models/hr_contract.py.template b/odoo/cli/templates/l10n_payroll/models/hr_contract.py.template new file mode 100644 index 00000000000..74a347136c6 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/models/hr_contract.py.template @@ -0,0 +1,9 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class HrContract(models.Model): + _inherit = 'hr.payslip' + + l10n_{{code}}_field = fields.Char() diff --git a/odoo/cli/templates/l10n_payroll/models/hr_payslip.py.template b/odoo/cli/templates/l10n_payroll/models/hr_payslip.py.template new file mode 100644 index 00000000000..cc1f868290a --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/models/hr_payslip.py.template @@ -0,0 +1,29 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class HrPayslip(models.Model): + _inherit = 'hr.payslip' + + def _get_data_files_to_update(self): + # Note: file order should be maintained + return super()._get_data_files_to_update() + [( + 'l10n_{{code}}_hr_payroll', [ + 'data/hr_salary_rule_category_data.xml', + 'data/hr_payroll_structure_type_data.xml', + 'data/hr_payroll_structure_data.xml', + 'data/hr_rule_parameters_data.xml', + 'data/hr_salary_rule_data.xml', + ])] + + def _get_base_local_dict(self): + res = super()._get_base_local_dict() + res.update({ + 'compute_some_property': compute_some_property, + }) + return res + +def compute_some_property(payslip, parameter): + gross = payslip.result_rules.GROSS + return gross * parameter diff --git a/odoo/cli/templates/l10n_payroll/models/hr_payslip_worked_days.py.template b/odoo/cli/templates/l10n_payroll/models/hr_payslip_worked_days.py.template new file mode 100644 index 00000000000..0530d60fda2 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/models/hr_payslip_worked_days.py.template @@ -0,0 +1,20 @@ +{%- set codeUpper = code|upper -%} +# Part of Odoo. See LICENSE file for full copyright and licensing details. + + +from odoo import models + + +class HrPayslipWorkedDays(models.Model): + _inherit = 'hr.payslip.worked_days' + + def _compute_amount(self): + super()._compute_amount() + for worked_day in self: + if worked_day.payslip_id.state in ['draft', 'verify'] \ + and not worked_day.payslip_id.edited \ + and worked_day.payslip_id.wage_type == "monthly" \ + and worked_day.payslip_id.struct_id.country_id.code == "{{codeUpper}}" \ + and worked_day.is_paid \ + and worked_day.work_entry_type_id.code == "LEAVE110": + worked_day.amount *= 0.80 diff --git a/odoo/cli/templates/l10n_payroll/views/hr_payroll_report.xml.template b/odoo/cli/templates/l10n_payroll/views/hr_payroll_report.xml.template new file mode 100644 index 00000000000..8440b4a83a7 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/views/hr_payroll_report.xml.template @@ -0,0 +1,16 @@ +{%- set countryPascal = name|pascal -%} + + + {{countryPascal}}: Payslip + hr.payslip + qweb-pdf + l10n_{{code}}_hr_payroll.report_payslip_{{code}}_lang + l10n_{{code}}_hr_payroll.report_payslip_{{code}}_lang + 'Payslip - %s' % (object.employee_id.name) + + report + + + + + diff --git a/odoo/cli/templates/l10n_payroll/views/report_payslip_templates.xml.template b/odoo/cli/templates/l10n_payroll/views/report_payslip_templates.xml.template new file mode 100644 index 00000000000..4bbc2952c51 --- /dev/null +++ b/odoo/cli/templates/l10n_payroll/views/report_payslip_templates.xml.template @@ -0,0 +1,14 @@ + + + + +