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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+