Initial commit

This commit is contained in:
gsinghpal
2026-02-22 01:22:18 -05:00
commit 5200d5baf0
2394 changed files with 386834 additions and 0 deletions

View File

@@ -0,0 +1,483 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Payroll Entry Edit Form (Edit Paycheque Dialog - Clean Table Layout) -->
<record id="payroll_entry_edit_form" model="ir.ui.view">
<field name="name">payroll.entry.edit.form</field>
<field name="model">payroll.entry</field>
<field name="arch" type="xml">
<form string="Edit Paycheque">
<field name="currency_id" invisible="1"/>
<field name="wizard_id" invisible="1"/>
<sheet>
<!-- HEADER -->
<div class="o_form_sheet_bg" style="margin: -24px; margin-bottom: 16px; padding: 24px; background: var(--o-view-background-color);">
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
<div>
<span class="text-muted" style="font-size: 12px;">PAY TO</span>
<h2 style="margin: 4px 0 0 0;"><field name="employee_id" readonly="1" options="{'no_open': True}"/></h2>
</div>
<div style="display: flex; gap: 48px;">
<div>
<div class="text-muted" style="font-size: 12px;">Pay Date</div>
<div><field name="pay_date" readonly="1"/></div>
<div class="text-muted mt-2" style="font-size: 12px;">Paid From</div>
<div><field name="paid_from" readonly="1"/></div>
</div>
<div>
<div class="text-muted" style="font-size: 12px;">Pay Period</div>
<div><field name="pay_period_display" readonly="1"/></div>
<div class="text-muted mt-2" style="font-size: 12px;">Paid By</div>
<div><field name="payment_method"/></div>
</div>
<div style="text-align: right;">
<div class="text-muted" style="font-size: 12px;">NET PAY</div>
<h1 style="color: #28a745; margin: 0;"><field name="net_pay" widget="monetary"/></h1>
</div>
</div>
</div>
</div>
<!-- PAY SECTION -->
<h4 style="border-bottom: 2px solid var(--o-color-border); padding-bottom: 8px; margin-top: 24px;">PAY</h4>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 8px 0; font-weight: bold; border-bottom: 1px solid var(--o-color-border);">
<div>TYPE</div>
<div style="text-align: right;">Hours</div>
<div style="text-align: right;">Rate</div>
<div style="text-align: right;">Current</div>
<div style="text-align: right;">YTD</div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Regular Pay</div>
<div style="text-align: right;"><field name="regular_hours"/></div>
<div style="text-align: right;"><field name="hourly_rate" readonly="1" widget="monetary"/></div>
<div style="text-align: right;"><field name="regular_pay" readonly="1" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="regular_pay" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Vacation Pay</div>
<div style="text-align: right; opacity: 0.6;">-</div>
<div style="text-align: right;"><field name="vacation_pay_percent" readonly="1"/> %</div>
<div style="text-align: right;"><field name="vacation_pay" readonly="1" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="vacation_pay" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Stat Holiday Pay</div>
<div style="text-align: right;"><field name="stat_holiday_hours"/></div>
<div style="text-align: right;"><field name="hourly_rate" readonly="1" widget="monetary"/></div>
<div style="text-align: right;"><field name="stat_holiday_pay" readonly="1" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="stat_holiday_pay" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Stat pay - average daily wage</div>
<div style="text-align: right; opacity: 0.6;">-</div>
<div style="text-align: right; opacity: 0.6;">-</div>
<div style="text-align: right;"><field name="stat_pay_avg_daily_wage" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;">$ 0.00</div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center; font-weight: bold; border-top: 1px solid var(--o-color-border); margin-top: 8px;">
<div>Total</div>
<div style="text-align: right;"><field name="total_hours" readonly="1"/></div>
<div></div>
<div style="text-align: right;"><field name="gross_pay" readonly="1" widget="monetary"/></div>
<div style="text-align: right;"><field name="gross_pay" readonly="1" widget="monetary"/></div>
</div>
<!-- EMPLOYEE TAXES SECTION -->
<h4 style="border-bottom: 2px solid var(--o-color-border); padding-bottom: 8px; margin-top: 32px;">EMPLOYEE TAXES</h4>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 8px 0; font-weight: bold; border-bottom: 1px solid var(--o-color-border);">
<div>TYPE</div>
<div style="text-align: right;">Current</div>
<div style="text-align: right;">YTD</div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Income Tax</div>
<div style="text-align: right;"><field name="income_tax" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="income_tax" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Employment Insurance</div>
<div style="text-align: right;"><field name="employment_insurance" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="employment_insurance" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Canada Pension Plan</div>
<div style="text-align: right;"><field name="cpp" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="cpp" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Second Canada Pension Plan</div>
<div style="text-align: right;"><field name="cpp2" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="cpp2" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center; font-weight: bold; border-top: 1px solid var(--o-color-border); margin-top: 8px;">
<div>Total</div>
<div style="text-align: right;"><field name="total_employee_tax" readonly="1" widget="monetary"/></div>
<div style="text-align: right;"><field name="total_employee_tax" readonly="1" widget="monetary"/></div>
</div>
<!-- EMPLOYER TAXES SECTION -->
<h4 style="border-bottom: 2px solid var(--o-color-border); padding-bottom: 8px; margin-top: 32px;">EMPLOYER TAXES</h4>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 8px 0; font-weight: bold; border-bottom: 1px solid var(--o-color-border);">
<div>TYPE</div>
<div style="text-align: right;">Current</div>
<div style="text-align: right;">YTD</div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Employment Insurance Employer</div>
<div style="text-align: right;"><field name="employer_ei" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="employer_ei" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Canada Pension Plan Employer</div>
<div style="text-align: right;"><field name="employer_cpp" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="employer_cpp" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Second Canada Pension Plan Employer</div>
<div style="text-align: right;"><field name="employer_cpp2" widget="monetary"/></div>
<div style="text-align: right; opacity: 0.6;"><field name="employer_cpp2" readonly="1" widget="monetary"/></div>
</div>
<div style="display: grid; grid-template-columns: 3fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center; font-weight: bold; border-top: 1px solid var(--o-color-border); margin-top: 8px;">
<div>Total</div>
<div style="text-align: right;"><field name="total_employer_tax" readonly="1" widget="monetary"/></div>
<div style="text-align: right;"><field name="total_employer_tax" readonly="1" widget="monetary"/></div>
</div>
<!-- TIME OFF SECTION -->
<h4 style="border-bottom: 2px solid var(--o-color-border); padding-bottom: 8px; margin-top: 32px;">TIME OFF</h4>
<div style="display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 8px 0; font-weight: bold; border-bottom: 1px solid var(--o-color-border); font-size: 12px;">
<div></div>
<div style="text-align: right;">Hours accrued</div>
<div style="text-align: right;">Hours used</div>
<div style="text-align: right;">Hours available</div>
<div style="text-align: right;">Amount accrued</div>
<div style="text-align: right;">Amount used</div>
<div style="text-align: right;">Amount available</div>
</div>
<div style="display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 12px 0; align-items: center;">
<div>Vacation</div>
<div style="text-align: right;"><field name="vacation_hours_accrued"/></div>
<div style="text-align: right;"><field name="vacation_hours_used"/></div>
<div style="text-align: right;"><field name="vacation_hours_available" readonly="1"/></div>
<div style="text-align: right;"><field name="vacation_amount_accrued" readonly="1" widget="monetary"/></div>
<div style="text-align: right;"><field name="vacation_amount_used" widget="monetary"/></div>
<div style="text-align: right;"><field name="vacation_amount_available" readonly="1" widget="monetary"/></div>
</div>
<!-- MEMO -->
<h4 style="border-bottom: 2px solid var(--o-color-border); padding-bottom: 8px; margin-top: 32px;">MEMO</h4>
<field name="memo" placeholder="Add a memo..." style="width: 100%; min-height: 60px;"/>
</sheet>
<footer>
<button string="Save" type="object" name="action_save_entry" class="btn-primary"/>
<button string="Close" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<!-- Run Payroll Wizard Form View (QuickBooks-like with Entry and Preview states) -->
<record id="run_payroll_wizard_view_form" model="ir.ui.view">
<field name="name">run.payroll.wizard.form</field>
<field name="model">run.payroll.wizard</field>
<field name="arch" type="xml">
<form string="Run Payroll" create="0" edit="1" delete="0">
<field name="state" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="pay_schedule" invisible="1"/>
<field name="currency_id" invisible="1"/>
<field name="payslip_run_id" invisible="1"/>
<field name="available_period_ids" invisible="1"/>
<field name="display_name" invisible="1"/>
<sheet>
<!-- Page Title -->
<div class="oe_title mb-4">
<h1>
<span invisible="state != 'entry'">Run Payroll</span>
<span invisible="state != 'preview'">Preview Payroll</span>
</h1>
</div>
<!-- ============ ENTRY STATE ============ -->
<div invisible="state != 'entry'">
<!-- Header: Pay Period and Pay Date -->
<div style="display: flex; gap: 32px; margin-bottom: 24px; align-items: flex-end;">
<div>
<div class="text-muted" style="font-size: 12px; margin-bottom: 4px;">Pay period</div>
<field name="pay_period_id"
options="{'no_create': True, 'no_open': True}"
placeholder="Select pay period..."
style="min-width: 200px;"/>
</div>
<div>
<div class="text-muted" style="font-size: 12px; margin-bottom: 4px;">Pay date</div>
<field name="pay_date"/>
</div>
<div style="flex: 1;"></div>
<button name="action_load_attendance"
type="object"
string="Load Attendance Hours"
class="btn btn-outline-secondary"
icon="fa-clock-o"/>
</div>
<!-- Add Employee Button -->
<div style="margin-bottom: 16px;">
<button name="action_add_employee"
type="object"
string="+ Add an employee"
class="btn btn-link"
style="padding-left: 0;"/>
</div>
<!-- Employee Payroll Grid -->
<field name="entry_ids" nolabel="1">
<list editable="bottom" decoration-muted="regular_hours == 0">
<field name="employee_id" readonly="1"/>
<field name="employee_type" readonly="1" string=""/>
<field name="has_previous_payroll" column_invisible="1"/>
<field name="previous_payroll_amount" column_invisible="1"/>
<field name="previous_payroll_date" column_invisible="1"/>
<field name="regular_hours" string="Regular pay"/>
<field name="vacation_pay_percent" string="Vacation pay" readonly="1"/>
<field name="stat_holiday_hours" string="Stat holiday pay"/>
<field name="stat_pay_avg_daily_wage" string="Stat pay - aver..."/>
<field name="total_hours" string="Total hrs" readonly="1"/>
<field name="gross_pay" string="Gross pay" readonly="1"/>
<field name="net_pay" string="Net pay" readonly="1"/>
<field name="memo"/>
<field name="payment_method" string="Pay method"/>
<button name="action_open_edit_paycheque"
type="object"
icon="fa-ellipsis-v"
title="Edit paycheque"/>
</list>
</field>
<!-- Summary Footer -->
<div style="display: flex; padding: 16px 0; margin-top: 16px; border-top: 1px solid var(--o-color-border); font-weight: bold;">
<div style="width: 120px;">Total</div>
<div style="flex: 1;"></div>
<div style="width: 100px; text-align: right;">
<field name="total_regular_hours" readonly="1"/> hrs
</div>
<div style="flex: 1;"></div>
<div style="width: 120px; text-align: right;">
<field name="total_gross_pay" widget="monetary" readonly="1"/>
</div>
</div>
<!-- Action Buttons for Entry State -->
<div style="display: flex; justify-content: flex-end; gap: 12px; padding: 24px 0; margin-top: 24px; border-top: 1px solid var(--o-color-border);">
<button string="Cancel" class="btn btn-link" special="cancel"/>
<button name="action_save_for_later"
string="Save for later"
type="object"
class="btn btn-secondary"/>
<button name="action_preview_payroll"
string="Preview payroll"
type="object"
class="btn btn-primary"/>
</div>
</div>
<!-- ============ PREVIEW STATE ============ -->
<div invisible="state != 'preview'">
<!-- TOTAL PAYROLL COST Summary Box -->
<div style="display: flex; gap: 48px; margin-bottom: 32px; padding: 24px; border: 1px solid var(--o-color-border); border-radius: 8px; background: var(--o-view-background-color);">
<!-- Left: Total Cost -->
<div style="min-width: 220px;">
<div class="text-muted" style="font-size: 12px; margin-bottom: 4px;">TOTAL PAYROLL COST</div>
<h1 style="margin: 0 0 8px 0;"><field name="total_payroll_cost" widget="monetary" readonly="1"/></h1>
<div style="font-size: 13px;">
<span class="text-success" invisible="change_from_last &lt;= 0">
<i class="fa fa-arrow-up"/> Up <field name="change_from_last" readonly="1"/>% compared to last time
</span>
<span class="text-danger" invisible="change_from_last &gt;= 0">
<i class="fa fa-arrow-down"/> Down <field name="change_from_last" readonly="1"/>% compared to last time
</span>
</div>
<div style="margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--o-color-border);">
<div style="display: flex; justify-content: space-between; margin-bottom: 4px;">
<span class="text-muted">Gross pay</span>
<field name="total_gross_pay" widget="monetary" readonly="1"/>
</div>
<div style="display: flex; justify-content: space-between;">
<span class="text-muted">Employer taxes &amp; contributions</span>
<field name="total_employer_taxes" widget="monetary" readonly="1"/>
</div>
</div>
</div>
<!-- Right: Account Selection & Pay Details -->
<div style="flex: 1;">
<div style="margin-bottom: 16px;">
<div class="text-muted" style="font-size: 12px; margin-bottom: 4px;">Funding account</div>
<field name="bank_account_id"
options="{'no_create': True}"
placeholder="Select bank account..."
style="min-width: 250px;"/>
</div>
<field name="date_start" invisible="1"/>
<field name="date_end" invisible="1"/>
<div style="display: flex; gap: 48px;">
<div>
<div class="text-muted" style="font-size: 12px;">Pay period:</div>
<div><field name="period_display" readonly="1"/></div>
</div>
<div>
<div class="text-muted" style="font-size: 12px;">Pay date:</div>
<div><field name="pay_date" readonly="1"/></div>
</div>
</div>
</div>
</div>
<!-- Preview Employee Summary Grid -->
<field name="entry_ids" nolabel="1" readonly="1">
<list decoration-muted="regular_hours == 0">
<field name="employee_id" string="Name"/>
<field name="employee_type" string="" column_invisible="1"/>
<field name="total_hours" string="Total hours"/>
<field name="gross_pay" string="Gross pay"/>
<field name="total_employee_tax" string="Employee taxes &amp; deductions"/>
<field name="net_pay" string="Net pay"/>
<field name="total_employer_tax" string="Employer taxes &amp; contributions"/>
<field name="change_from_last_payroll" string="Change in gross pay"/>
<field name="memo" string="Memo"/>
</list>
</field>
<!-- Totals Row -->
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; gap: 8px; padding: 12px 0; font-weight: bold; border-top: 1px solid var(--o-color-border); margin-top: 8px;">
<div>Total</div>
<div style="text-align: right;"><field name="total_hours" readonly="1"/>h</div>
<div style="text-align: right;"><field name="total_gross_pay" widget="monetary" readonly="1"/></div>
<div style="text-align: right;"><field name="total_employee_taxes" widget="monetary" readonly="1"/></div>
<div style="text-align: right;"><field name="total_net_pay" widget="monetary" readonly="1"/></div>
<div style="text-align: right;"><field name="total_employer_taxes" widget="monetary" readonly="1"/></div>
<div></div>
<div></div>
</div>
<!-- Action Buttons for Preview State -->
<div style="display: flex; justify-content: space-between; gap: 12px; padding: 24px 0; margin-top: 24px; border-top: 1px solid var(--o-color-border);">
<button name="action_back_to_entry"
string="Back"
type="object"
class="btn btn-link"/>
<div style="display: flex; gap: 12px;">
<button name="action_submit_payroll"
string="Submit payroll"
type="object"
class="btn btn-primary"/>
</div>
</div>
</div>
</sheet>
</form>
</field>
</record>
<!-- Pay Period Tree View -->
<record id="payroll_pay_period_tree" model="ir.ui.view">
<field name="name">payroll.pay.period.tree</field>
<field name="model">payroll.pay.period</field>
<field name="arch" type="xml">
<list>
<field name="display_name"/>
<field name="schedule_type"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="pay_date"/>
<field name="state" widget="badge"
decoration-info="state == 'draft'"
decoration-warning="state == 'in_progress'"
decoration-success="state == 'paid'"/>
</list>
</field>
</record>
<!-- Pay Period Form View -->
<record id="payroll_pay_period_form" model="ir.ui.view">
<field name="name">payroll.pay.period.form</field>
<field name="model">payroll.pay.period</field>
<field name="arch" type="xml">
<form>
<header>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<group>
<field name="company_id"/>
<field name="schedule_type"/>
</group>
<group>
<field name="date_start"/>
<field name="date_end"/>
<field name="pay_date"/>
</group>
</group>
<group>
<field name="payslip_run_id"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- Pay Period Settings Form View -->
<record id="payroll_pay_period_settings_form" model="ir.ui.view">
<field name="name">payroll.pay.period.settings.form</field>
<field name="model">payroll.pay.period.settings</field>
<field name="arch" type="xml">
<form>
<sheet>
<group string="Pay Period Configuration">
<group>
<field name="company_id" invisible="1"/>
<field name="schedule_type"/>
<field name="first_period_start"/>
</group>
<group>
<field name="pay_day_offset"/>
<field name="auto_generate_periods"/>
<field name="periods_to_generate" invisible="not auto_generate_periods"/>
</group>
</group>
<footer>
<button name="action_generate_periods"
type="object"
string="Generate Periods"
class="btn-primary"/>
</footer>
</sheet>
</form>
</field>
</record>
<!-- Run Payroll Wizard Action (opens in full page with breadcrumbs) -->
<record id="action_run_payroll_wizard" model="ir.actions.act_window">
<field name="name">Run Payroll</field>
<field name="res_model">run.payroll.wizard</field>
<field name="view_mode">form</field>
<field name="target">current</field>
<field name="context">{'form_view_ref': 'fusion_payroll.run_payroll_wizard_view_form'}</field>
</record>
<!-- Server Action to Open Run Payroll with Pre-loaded Data -->
<record id="action_open_run_payroll" model="ir.actions.server">
<field name="name">Run Payroll</field>
<field name="model_id" ref="model_run_payroll_wizard"/>
<field name="state">code</field>
<field name="code">
action = model.action_open_run_payroll()
</field>
</record>
</odoo>