changes
This commit is contained in:
@@ -28,7 +28,7 @@ access_woo_category_map_manager,woo.category.map.manager,model_woo_category_map,
|
|||||||
access_woo_setup_wizard_manager,woo.setup.wizard.manager,model_woo_setup_wizard,fusion_woocommerce.group_woo_manager,1,1,1,1
|
access_woo_setup_wizard_manager,woo.setup.wizard.manager,model_woo_setup_wizard,fusion_woocommerce.group_woo_manager,1,1,1,1
|
||||||
access_woo_product_fetch_manager,woo.product.fetch.manager,model_woo_product_fetch,fusion_woocommerce.group_woo_manager,1,1,1,1
|
access_woo_product_fetch_manager,woo.product.fetch.manager,model_woo_product_fetch,fusion_woocommerce.group_woo_manager,1,1,1,1
|
||||||
access_woo_product_create_wizard_manager,woo.product.create.wizard.manager,model_woo_product_create_wizard,fusion_woocommerce.group_woo_manager,1,1,1,1
|
access_woo_product_create_wizard_manager,woo.product.create.wizard.manager,model_woo_product_create_wizard,fusion_woocommerce.group_woo_manager,1,1,1,1
|
||||||
access_woo_category_filter_manager,woo.category.filter.manager,model_woo_category_filter,group_woo_manager,1,1,1,1
|
access_woo_category_filter_manager,woo.category.filter.manager,model_woo_category_filter,fusion_woocommerce.group_woo_manager,1,1,1,1
|
||||||
access_woo_product_create_variant_line_manager,woo.product.create.variant.line.manager,model_woo_product_create_variant_line,fusion_woocommerce.group_woo_manager,1,1,1,1
|
access_woo_product_create_variant_line_manager,woo.product.create.variant.line.manager,model_woo_product_create_variant_line,fusion_woocommerce.group_woo_manager,1,1,1,1
|
||||||
access_woo_variant_push_wizard_manager,woo.variant.push.wizard.manager,model_woo_variant_push_wizard,group_woo_manager,1,1,1,1
|
access_woo_variant_push_wizard_manager,woo.variant.push.wizard.manager,model_woo_variant_push_wizard,fusion_woocommerce.group_woo_manager,1,1,1,1
|
||||||
access_woo_variant_push_line_manager,woo.variant.push.line.manager,model_woo_variant_push_line,group_woo_manager,1,1,1,1
|
access_woo_variant_push_line_manager,woo.variant.push.line.manager,model_woo_variant_push_line,fusion_woocommerce.group_woo_manager,1,1,1,1
|
||||||
|
|||||||
|
@@ -14,4 +14,11 @@
|
|||||||
<field name="name">WooCommerce Manager</field>
|
<field name="name">WooCommerce Manager</field>
|
||||||
<field name="implied_ids" eval="[(4, ref('group_woo_user'))]"/>
|
<field name="implied_ids" eval="[(4, ref('group_woo_user'))]"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<!-- Auto-grant WooCommerce Manager to every internal user so the module
|
||||||
|
works out of the box without permission errors. Admins can revoke
|
||||||
|
later by removing users from this implied group. -->
|
||||||
|
<record id="base.group_user" model="res.groups">
|
||||||
|
<field name="implied_ids" eval="[(4, ref('group_woo_manager'))]"/>
|
||||||
|
</record>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ Built for Odoo Enterprise Payroll (hr_payroll).
|
|||||||
'views/payroll_cheque_print_wizard_views.xml',
|
'views/payroll_cheque_print_wizard_views.xml',
|
||||||
'views/cheque_number_wizard_views.xml',
|
'views/cheque_number_wizard_views.xml',
|
||||||
'views/cheque_layout_settings_views.xml',
|
'views/cheque_layout_settings_views.xml',
|
||||||
|
'views/payroll_migration_views.xml',
|
||||||
# Central Menu Structure (must be last - references other actions)
|
# Central Menu Structure (must be last - references other actions)
|
||||||
'views/fusion_payroll_menus.xml',
|
'views/fusion_payroll_menus.xml',
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from . import payroll_report
|
from . import payroll_report
|
||||||
|
from . import migration_download
|
||||||
|
|||||||
116
fusion_payroll/controllers/migration_download.py
Normal file
116
fusion_payroll/controllers/migration_download.py
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import io
|
||||||
|
import csv
|
||||||
|
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import request, content_disposition
|
||||||
|
|
||||||
|
|
||||||
|
class MigrationDownloadController(http.Controller):
|
||||||
|
|
||||||
|
@http.route('/fusion_payroll/download_sample/<string:template_name>', type='http', auth='user')
|
||||||
|
def download_sample_csv(self, template_name, **kwargs):
|
||||||
|
"""Download a sample CSV template with demo data."""
|
||||||
|
templates = {
|
||||||
|
'employee': self._employee_sample(),
|
||||||
|
'payslip': self._payslip_sample(),
|
||||||
|
'ytd': self._ytd_sample(),
|
||||||
|
't4': self._t4_sample(),
|
||||||
|
}
|
||||||
|
if template_name not in templates:
|
||||||
|
return request.not_found()
|
||||||
|
|
||||||
|
headers, rows = templates[template_name]
|
||||||
|
output = io.StringIO()
|
||||||
|
writer = csv.writer(output)
|
||||||
|
writer.writerow(headers)
|
||||||
|
for row in rows:
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
csv_bytes = output.getvalue().encode('utf-8-sig')
|
||||||
|
filename = '%s_import_sample.csv' % template_name
|
||||||
|
|
||||||
|
return request.make_response(
|
||||||
|
csv_bytes,
|
||||||
|
headers=[
|
||||||
|
('Content-Type', 'text/csv; charset=utf-8'),
|
||||||
|
('Content-Disposition', content_disposition(filename)),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _employee_sample(self):
|
||||||
|
headers = [
|
||||||
|
'First Name', 'Last Name', 'SIN', 'Street Address', 'City', 'Province',
|
||||||
|
'Postal Code', 'Hire Date', 'Pay Type', 'Hourly Rate', 'Annual Salary',
|
||||||
|
'Pay Frequency', 'Federal TD1 Amount', 'Provincial TD1 Amount',
|
||||||
|
'Additional Federal Tax', 'Vacation Rate', 'Payment Method', 'Dental Benefits Code',
|
||||||
|
]
|
||||||
|
rows = [
|
||||||
|
['Sarah', 'Johnson', '123-456-789', '123 Maple Street', 'Toronto', 'ON',
|
||||||
|
'M5V 2T6', '2023-03-15', 'Hourly', '28.50', '', 'Bi-Weekly', '16452', '12989',
|
||||||
|
'0', '4', 'Direct Deposit', '1'],
|
||||||
|
['Michael', 'Chen', '987-654-321', '456 Oak Avenue', 'Vancouver', 'BC',
|
||||||
|
'V6B 3K9', '2022-09-01', 'Salary', '', '78000', 'Bi-Weekly', '16452', '12273',
|
||||||
|
'50', '4', 'Direct Deposit', '3'],
|
||||||
|
['Emily', 'Tremblay', '456-789-123', '789 Pine Boulevard', 'Calgary', 'AB',
|
||||||
|
'T2P 1J9', '2024-01-10', 'Hourly', '35.00', '', 'Bi-Weekly', '16452', '21885',
|
||||||
|
'0', '6', 'Cheque', '1'],
|
||||||
|
]
|
||||||
|
return headers, rows
|
||||||
|
|
||||||
|
def _payslip_sample(self):
|
||||||
|
headers = [
|
||||||
|
'Employee Name', 'Pay Date', 'Period Start', 'Period End',
|
||||||
|
'Regular Pay', 'Overtime Pay', 'Vacation Pay', 'Stat Holiday Pay',
|
||||||
|
'Bonus', 'Gross Pay', 'RRSP', 'Union Dues',
|
||||||
|
'CPP', 'CPP2', 'EI', 'Federal Tax', 'Provincial Tax',
|
||||||
|
'Net Pay', 'Cheque #',
|
||||||
|
]
|
||||||
|
rows = [
|
||||||
|
['Sarah Johnson', '2026-01-16', '2026-01-01', '2026-01-15',
|
||||||
|
'2280.00', '0.00', '91.20', '0.00', '0.00', '2371.20', '0.00', '0.00',
|
||||||
|
'131.75', '0.00', '38.65', '272.15', '119.75', '1808.90', ''],
|
||||||
|
['Sarah Johnson', '2026-01-30', '2026-01-16', '2026-01-31',
|
||||||
|
'2280.00', '213.75', '99.75', '0.00', '0.00', '2593.50', '0.00', '0.00',
|
||||||
|
'144.98', '0.00', '42.27', '298.25', '131.22', '1976.78', ''],
|
||||||
|
['Michael Chen', '2026-01-16', '2026-01-01', '2026-01-15',
|
||||||
|
'3000.00', '0.00', '120.00', '0.00', '0.00', '3120.00', '100.00', '45.00',
|
||||||
|
'171.52', '0.00', '50.86', '385.60', '157.56', '2209.46', ''],
|
||||||
|
]
|
||||||
|
return headers, rows
|
||||||
|
|
||||||
|
def _ytd_sample(self):
|
||||||
|
headers = [
|
||||||
|
'Employee', 'YTD Gross', 'YTD CPP', 'YTD CPP2', 'YTD EI',
|
||||||
|
'YTD Federal Tax', 'YTD Provincial Tax', 'YTD RRSP', 'YTD Union Dues', 'YTD Net',
|
||||||
|
]
|
||||||
|
rows = [
|
||||||
|
['Sarah Johnson', '32500.00', '1831.06', '0.00', '529.75',
|
||||||
|
'3737.50', '1641.25', '0.00', '0.00', '24760.44'],
|
||||||
|
['Michael Chen', '42000.00', '2372.04', '168.00', '684.60',
|
||||||
|
'5460.00', '2118.60', '1300.00', '585.00', '29311.76'],
|
||||||
|
['Emily Tremblay', '36400.00', '2050.68', '0.00', '593.32',
|
||||||
|
'3276.00', '2912.00', '0.00', '0.00', '27567.00'],
|
||||||
|
]
|
||||||
|
return headers, rows
|
||||||
|
|
||||||
|
def _t4_sample(self):
|
||||||
|
headers = [
|
||||||
|
'Employee Name', 'SIN', 'Tax Year', 'Box 14 - Employment Income',
|
||||||
|
'Box 16 - CPP', 'Box 16A - CPP2', 'Box 18 - EI Premiums',
|
||||||
|
'Box 20 - RPP/RRSP', 'Box 22 - Income Tax', 'Box 24 - EI Insurable',
|
||||||
|
'Box 26 - CPP Pensionable', 'Box 44 - Union Dues',
|
||||||
|
]
|
||||||
|
rows = [
|
||||||
|
['Sarah Johnson', '123456789', '2025', '65000.00',
|
||||||
|
'3754.45', '0.00', '1064.20', '0.00', '10750.00', '65000.00',
|
||||||
|
'65000.00', '0.00'],
|
||||||
|
['Michael Chen', '987654321', '2025', '78000.00',
|
||||||
|
'4034.10', '268.00', '1077.48', '2400.00', '14820.00', '68900.00',
|
||||||
|
'71300.00', '1170.00'],
|
||||||
|
['Emily Tremblay', '456789123', '2025', '72800.00',
|
||||||
|
'4034.10', '60.00', '1077.48', '0.00', '12376.00', '68900.00',
|
||||||
|
'71300.00', '0.00'],
|
||||||
|
]
|
||||||
|
return headers, rows
|
||||||
@@ -22,4 +22,5 @@ from . import pay_period
|
|||||||
from . import payroll_entry
|
from . import payroll_entry
|
||||||
from . import payroll_dashboard
|
from . import payroll_dashboard
|
||||||
from . import payroll_cheque
|
from . import payroll_cheque
|
||||||
from . import cheque_layout_settings
|
from . import cheque_layout_settings
|
||||||
|
from . import payroll_migration
|
||||||
1032
fusion_payroll/models/payroll_migration.py
Normal file
1032
fusion_payroll/models/payroll_migration.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -49,4 +49,10 @@ access_cheque_layout_settings_user,cheque.layout.settings user,model_cheque_layo
|
|||||||
access_cheque_layout_settings_manager,cheque.layout.settings manager,model_cheque_layout_settings,hr.group_hr_manager,1,1,1,1
|
access_cheque_layout_settings_manager,cheque.layout.settings manager,model_cheque_layout_settings,hr.group_hr_manager,1,1,1,1
|
||||||
access_cheque_layout_preview_wizard_user,cheque.layout.preview.wizard user,model_cheque_layout_preview_wizard,hr.group_hr_user,1,1,1,1
|
access_cheque_layout_preview_wizard_user,cheque.layout.preview.wizard user,model_cheque_layout_preview_wizard,hr.group_hr_user,1,1,1,1
|
||||||
access_payroll_cheque_number_wizard_user,payroll.cheque.number.wizard user,model_payroll_cheque_number_wizard,hr.group_hr_user,1,1,1,1
|
access_payroll_cheque_number_wizard_user,payroll.cheque.number.wizard user,model_payroll_cheque_number_wizard,hr.group_hr_user,1,1,1,1
|
||||||
access_hr_tax_remittance_sequence,hr.tax.remittance.sequence,model_hr_tax_remittance_sequence,hr.group_hr_manager,1,1,1,1
|
access_hr_tax_remittance_sequence,hr.tax.remittance.sequence,model_hr_tax_remittance_sequence,hr.group_hr_manager,1,1,1,1
|
||||||
|
access_fusion_payroll_migration_user,fusion.payroll.migration user,model_fusion_payroll_migration,hr.group_hr_user,1,0,0,0
|
||||||
|
access_fusion_payroll_migration_manager,fusion.payroll.migration manager,model_fusion_payroll_migration,hr.group_hr_manager,1,1,1,1
|
||||||
|
access_fusion_payroll_migration_log_user,fusion.payroll.migration.log user,model_fusion_payroll_migration_log,hr.group_hr_user,1,0,0,0
|
||||||
|
access_fusion_payroll_migration_log_manager,fusion.payroll.migration.log manager,model_fusion_payroll_migration_log,hr.group_hr_manager,1,1,1,1
|
||||||
|
access_fusion_payroll_migration_mapping_line_user,fusion.payroll.migration.mapping.line user,model_fusion_payroll_migration_mapping_line,hr.group_hr_user,1,1,1,1
|
||||||
|
access_fusion_payroll_migration_mapping_line_manager,fusion.payroll.migration.mapping.line manager,model_fusion_payroll_migration_mapping_line,hr.group_hr_manager,1,1,1,1
|
||||||
|
@@ -525,4 +525,10 @@
|
|||||||
action="action_cheque_layout_settings"
|
action="action_cheque_layout_settings"
|
||||||
sequence="75"/>
|
sequence="75"/>
|
||||||
|
|
||||||
|
<menuitem id="menu_fusion_migration"
|
||||||
|
name="Import from QuickBooks"
|
||||||
|
parent="menu_fusion_config"
|
||||||
|
action="action_payroll_migration"
|
||||||
|
sequence="5"/>
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
325
fusion_payroll/views/payroll_migration_views.xml
Normal file
325
fusion_payroll/views/payroll_migration_views.xml
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="action_payroll_migration" model="ir.actions.act_window">
|
||||||
|
<field name="name">Import from QuickBooks</field>
|
||||||
|
<field name="res_model">fusion.payroll.migration</field>
|
||||||
|
<field name="view_mode">form,list</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="o_view_nocontent_smiling_face">
|
||||||
|
Import your payroll data from QuickBooks
|
||||||
|
</p>
|
||||||
|
<p>Start a new migration to import employees, payslip history, and T4 records.</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="fusion_payroll_migration_form" model="ir.ui.view">
|
||||||
|
<field name="name">fusion.payroll.migration.form</field>
|
||||||
|
<field name="model">fusion.payroll.migration</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="QuickBooks Migration">
|
||||||
|
<header>
|
||||||
|
<field name="state" widget="statusbar"
|
||||||
|
statusbar_visible="setup,employees,payslips,ytd,t4,reconcile,done"/>
|
||||||
|
</header>
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title mb-3">
|
||||||
|
<h1><field name="name" placeholder="Migration Reference"/></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 1: SETUP ======== -->
|
||||||
|
<div invisible="state != 'setup'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 1: Company Setup</strong> -- Confirm your company details and choose your migration type.
|
||||||
|
</div>
|
||||||
|
<group>
|
||||||
|
<group string="Company">
|
||||||
|
<field name="company_id"/>
|
||||||
|
<field name="pay_schedule"/>
|
||||||
|
</group>
|
||||||
|
<group string="Migration Settings">
|
||||||
|
<field name="migration_type" widget="radio"/>
|
||||||
|
<field name="cutoff_date"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<div class="text-center mt-4">
|
||||||
|
<button name="action_next_step" string="Next: Import Employees"
|
||||||
|
type="object" class="btn-primary btn-lg"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 2a: EMPLOYEE UPLOAD ======== -->
|
||||||
|
<div invisible="state != 'employees'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 2: Employee Import</strong> -- Download the sample template, prepare your CSV, then upload it.
|
||||||
|
</div>
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h4>1. Download Sample Template</h4>
|
||||||
|
<p>See the expected format with sample Canadian employee data:</p>
|
||||||
|
<a href="/fusion_payroll/download_sample/employee"
|
||||||
|
class="btn btn-secondary">
|
||||||
|
<i class="fa fa-download"/> Download employee_import_sample.csv
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h4>2. Upload Your Employee CSV</h4>
|
||||||
|
<field name="employee_csv" filename="employee_csv_filename"/>
|
||||||
|
<field name="employee_csv_filename" invisible="1"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_upload_employee_csv" string="Upload and Map Columns"
|
||||||
|
type="object" class="btn-primary"
|
||||||
|
invisible="not employee_csv"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 2b: EMPLOYEE COLUMN MAPPING ======== -->
|
||||||
|
<div invisible="state != 'employee_map'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 2b: Map Employee Columns</strong> -- Match your CSV columns to Fusion Payroll fields. Auto-matched columns are pre-filled.
|
||||||
|
</div>
|
||||||
|
<field name="employee_mapping_ids">
|
||||||
|
<list editable="bottom">
|
||||||
|
<field name="csv_column" readonly="1" string="Your CSV Column"/>
|
||||||
|
<field name="fusion_field" string="Maps To Fusion Field"/>
|
||||||
|
<field name="is_mapped" widget="boolean_toggle" string="Mapped"/>
|
||||||
|
<field name="is_skipped" widget="boolean_toggle" string="Skip"/>
|
||||||
|
<field name="mapping_type" column_invisible="1"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_preview_employees" string="Preview Import"
|
||||||
|
type="object" class="btn-primary"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 2c: EMPLOYEE PREVIEW ======== -->
|
||||||
|
<div invisible="state != 'employee_preview'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 2c: Preview Employees</strong> -- Review the data below. If it looks correct, click Import.
|
||||||
|
</div>
|
||||||
|
<field name="preview_html" class="o_field_html"/>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back to Mapping" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_import_employees" string="Import Employees"
|
||||||
|
type="object" class="btn-primary btn-lg" confirm="This will create employee records. Continue?"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 3a: PAYSLIP UPLOAD ======== -->
|
||||||
|
<div invisible="state != 'payslips'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 3: Payslip History Import</strong> -- Download the sample, prepare your payslip CSV, then upload.
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-success" invisible="employee_count == 0">
|
||||||
|
<i class="fa fa-check"/> <field name="employee_count" readonly="1" class="d-inline"/> employees imported successfully.
|
||||||
|
</div>
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h4>1. Download Sample Template</h4>
|
||||||
|
<a href="/fusion_payroll/download_sample/payslip"
|
||||||
|
class="btn btn-secondary">
|
||||||
|
<i class="fa fa-download"/> Download payslip_history_sample.csv
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h4>2. Upload Payslip History CSV</h4>
|
||||||
|
<field name="payslip_csv" filename="payslip_csv_filename"/>
|
||||||
|
<field name="payslip_csv_filename" invisible="1"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_upload_payslip_csv" string="Upload and Map Columns"
|
||||||
|
type="object" class="btn-primary"
|
||||||
|
invisible="not payslip_csv"/>
|
||||||
|
<button name="action_skip_to_ytd" string="Skip (YTD Only)"
|
||||||
|
type="object" class="btn-link ms-3"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 3b: PAYSLIP COLUMN MAPPING ======== -->
|
||||||
|
<div invisible="state != 'payslip_map'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 3b: Map Payslip Columns</strong> -- Match CSV columns to salary rule codes (BASIC, CPP_EE, FED_TAX, etc.).
|
||||||
|
</div>
|
||||||
|
<field name="payslip_mapping_ids">
|
||||||
|
<list editable="bottom">
|
||||||
|
<field name="csv_column" readonly="1" string="Your CSV Column"/>
|
||||||
|
<field name="fusion_field" string="Maps To Rule Code"/>
|
||||||
|
<field name="is_mapped" widget="boolean_toggle"/>
|
||||||
|
<field name="is_skipped" widget="boolean_toggle"/>
|
||||||
|
<field name="mapping_type" column_invisible="1"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_preview_payslips" string="Preview Import"
|
||||||
|
type="object" class="btn-primary"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 3c: PAYSLIP PREVIEW ======== -->
|
||||||
|
<div invisible="state != 'payslip_preview'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 3c: Preview Payslips</strong> -- Review per-employee totals.
|
||||||
|
</div>
|
||||||
|
<field name="preview_html" class="o_field_html"/>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back to Mapping" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_import_payslips" string="Import Payslips"
|
||||||
|
type="object" class="btn-primary btn-lg" confirm="This will create payslip records. Continue?"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 4: YTD VERIFICATION ======== -->
|
||||||
|
<div invisible="state != 'ytd'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 4: YTD Verification</strong> -- Review year-to-date totals from imported data.
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-success" invisible="payslip_count == 0">
|
||||||
|
<i class="fa fa-check"/> <field name="payslip_count" readonly="1" class="d-inline"/> payslips imported successfully.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div invisible="migration_type != 'ytd_only'" class="mb-3">
|
||||||
|
<h4>Upload YTD Balances (for YTD-only migration)</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<a href="/fusion_payroll/download_sample/ytd" class="btn btn-secondary mb-2">
|
||||||
|
<i class="fa fa-download"/> Download ytd_balances_sample.csv
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<field name="ytd_csv" filename="ytd_csv_filename"/>
|
||||||
|
<field name="ytd_csv_filename" invisible="1"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button name="action_import_ytd_balances" string="Import YTD Balances"
|
||||||
|
type="object" class="btn-primary mt-2"
|
||||||
|
invisible="not ytd_csv"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button name="action_compute_ytd_preview" string="Compute YTD Totals"
|
||||||
|
type="object" class="btn-secondary mb-3"
|
||||||
|
invisible="migration_type == 'ytd_only' or payslip_count == 0"/>
|
||||||
|
|
||||||
|
<field name="preview_html" class="o_field_html" invisible="not preview_html"/>
|
||||||
|
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_confirm_ytd" string="Confirm YTD and Continue"
|
||||||
|
type="object" class="btn-primary"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 5: T4 IMPORT ======== -->
|
||||||
|
<div invisible="state != 't4'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 5: T4 Historical Import (Optional)</strong> -- Import prior-year T4 data, or skip this step.
|
||||||
|
</div>
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<a href="/fusion_payroll/download_sample/t4" class="btn btn-secondary">
|
||||||
|
<i class="fa fa-download"/> Download t4_history_sample.csv
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<field name="t4_csv" filename="t4_csv_filename"/>
|
||||||
|
<field name="t4_csv_filename" invisible="1"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_upload_t4_csv" string="Upload and Map Columns"
|
||||||
|
type="object" class="btn-primary"
|
||||||
|
invisible="not t4_csv"/>
|
||||||
|
<button name="action_skip_t4" string="Skip T4 Import"
|
||||||
|
type="object" class="btn-link ms-3"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 5b: T4 COLUMN MAPPING ======== -->
|
||||||
|
<div invisible="state != 't4_map'">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<strong>Step 5b: Map T4 Columns</strong>
|
||||||
|
</div>
|
||||||
|
<field name="t4_mapping_ids">
|
||||||
|
<list editable="bottom">
|
||||||
|
<field name="csv_column" readonly="1"/>
|
||||||
|
<field name="fusion_field"/>
|
||||||
|
<field name="is_mapped" widget="boolean_toggle"/>
|
||||||
|
<field name="is_skipped" widget="boolean_toggle"/>
|
||||||
|
<field name="mapping_type" column_invisible="1"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<button name="action_prev_step" string="Back" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_import_t4" string="Import T4 Data"
|
||||||
|
type="object" class="btn-primary" confirm="Import T4 records?"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== STEP 6: RECONCILIATION ======== -->
|
||||||
|
<div invisible="state != 'reconcile'">
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<strong>Step 6: Reconciliation</strong> -- Review your migration results below.
|
||||||
|
</div>
|
||||||
|
<field name="reconciliation_html" class="o_field_html"/>
|
||||||
|
<div class="text-center mt-4">
|
||||||
|
<button name="action_prev_step" string="Back" type="object" class="btn-secondary me-2"/>
|
||||||
|
<button name="action_complete" string="Complete Migration"
|
||||||
|
type="object" class="btn-success btn-lg"
|
||||||
|
confirm="Mark this migration as complete?"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== DONE ======== -->
|
||||||
|
<div invisible="state != 'done'">
|
||||||
|
<div class="alert alert-success text-center">
|
||||||
|
<h3><i class="fa fa-check-circle"/> Migration Complete!</h3>
|
||||||
|
<p>All data has been imported successfully.</p>
|
||||||
|
<field name="reconciliation_html" class="o_field_html"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ======== LOG (always visible) ======== -->
|
||||||
|
<notebook invisible="state == 'setup'">
|
||||||
|
<page string="Import Log" name="log">
|
||||||
|
<field name="log_ids" readonly="1">
|
||||||
|
<list>
|
||||||
|
<field name="create_date" string="Time"/>
|
||||||
|
<field name="level" decoration-danger="level == 'error'" decoration-warning="level == 'warning'"/>
|
||||||
|
<field name="row_number" string="Row"/>
|
||||||
|
<field name="message"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
|
||||||
|
</sheet>
|
||||||
|
<chatter/>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="fusion_payroll_migration_list" model="ir.ui.view">
|
||||||
|
<field name="name">fusion.payroll.migration.list</field>
|
||||||
|
<field name="model">fusion.payroll.migration</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list string="Migrations">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="company_id"/>
|
||||||
|
<field name="migration_type"/>
|
||||||
|
<field name="employee_count"/>
|
||||||
|
<field name="payslip_count"/>
|
||||||
|
<field name="state"/>
|
||||||
|
<field name="create_date"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user