Initial commit
This commit is contained in:
162
fusion_payroll/static/src/xml/payroll_report_templates.xml
Normal file
162
fusion_payroll/static/src/xml/payroll_report_templates.xml
Normal file
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="fusion_payroll.PayrollReportAction">
|
||||
<div class="o_action o_payroll_report_action">
|
||||
<!-- Loading Spinner -->
|
||||
<div t-if="state.loading" class="d-flex justify-content-center align-items-center" style="min-height: 400px;">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-else="" class="container-fluid py-3">
|
||||
<!-- Header -->
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<button class="btn btn-link p-0 me-3" t-on-click="goBack">
|
||||
<i class="fa fa-chevron-left"/> Back
|
||||
</button>
|
||||
<h2 class="mb-0">
|
||||
<t t-out="state.reportName"/>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<!-- Export Buttons -->
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-success dropdown-toggle" data-bs-toggle="dropdown">
|
||||
Export <i class="fa fa-caret-down ms-1"/>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item" href="#" t-on-click.prevent="exportXlsx">
|
||||
<i class="fa fa-file-excel-o me-2"/> Export to Excel
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="#" t-on-click.prevent="exportPdf">
|
||||
<i class="fa fa-file-pdf-o me-2"/> Export to PDF
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filters Row -->
|
||||
<div class="row mb-3" t-if="state.filterDateRange">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body py-2">
|
||||
<div class="row align-items-center">
|
||||
<!-- Date Filter Dropdown -->
|
||||
<div class="col-auto">
|
||||
<select class="form-select form-select-sm"
|
||||
t-on-change="onDateFilterChange"
|
||||
t-att-value="state.selectedDateFilter">
|
||||
<t t-foreach="state.dateFilterOptions" t-as="option" t-key="option[0]">
|
||||
<option t-att-value="option[0]"
|
||||
t-att-selected="option[0] === state.selectedDateFilter">
|
||||
<t t-out="option[1]"/>
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Date From -->
|
||||
<div class="col-auto">
|
||||
<input type="date"
|
||||
class="form-control form-control-sm"
|
||||
t-att-value="state.dateFrom"
|
||||
t-on-change="onDateFromChange"/>
|
||||
</div>
|
||||
|
||||
<!-- Date To -->
|
||||
<div class="col-auto">
|
||||
<input type="date"
|
||||
class="form-control form-control-sm"
|
||||
t-att-value="state.dateTo"
|
||||
t-on-change="onDateToChange"/>
|
||||
</div>
|
||||
|
||||
<!-- Apply Button (for custom dates) -->
|
||||
<div class="col-auto" t-if="state.showCustomDate">
|
||||
<button class="btn btn-primary btn-sm" t-on-click="applyFilters">
|
||||
Apply
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Customize Button -->
|
||||
<div class="col-auto ms-auto">
|
||||
<button class="btn btn-outline-secondary btn-sm">
|
||||
<i class="fa fa-sliders me-1"/> Customize
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Report Table -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm mb-0 o_payroll_report_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<t t-foreach="state.columns" t-as="column" t-key="column.field">
|
||||
<th t-att-class="column.sortable ? 'cursor-pointer user-select-none' : ''"
|
||||
t-on-click="() => this.sortByColumn(column)">
|
||||
<t t-out="column.name"/>
|
||||
<t t-if="column.sortable">
|
||||
<i t-if="state.sortColumn === column.field"
|
||||
t-att-class="'fa ms-1 ' + (state.sortDirection === 'asc' ? 'fa-sort-asc' : 'fa-sort-desc')"/>
|
||||
<i t-else="" class="fa fa-sort ms-1 text-muted"/>
|
||||
</t>
|
||||
</th>
|
||||
</t>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-if="state.lines.length === 0">
|
||||
<tr>
|
||||
<td t-att-colspan="state.columns.length" class="text-center text-muted py-4">
|
||||
There are no results matching the criteria.
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-foreach="state.lines" t-as="line" t-key="line.id">
|
||||
<tr t-att-class="this.getLineClass(line)"
|
||||
t-on-click="() => line.model and line.res_id and this.openRecord(line)"
|
||||
style="cursor: pointer;">
|
||||
<t t-foreach="state.columns" t-as="column" t-key="column.field">
|
||||
<td t-att-class="column.type === 'monetary' or column.type === 'float' ? 'text-end' : ''">
|
||||
<!-- Unfoldable indicator -->
|
||||
<t t-if="column_index === 0 and line.unfoldable">
|
||||
<i t-att-class="'fa me-1 ' + (state.expandedLines[line.id] ? 'fa-caret-down' : 'fa-caret-right')"
|
||||
t-on-click.stop="() => this.toggleLine(line.id)"/>
|
||||
</t>
|
||||
<t t-out="this.formatValue(line.values?.[column.field], column.type)"/>
|
||||
</td>
|
||||
</t>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
185
fusion_payroll/static/src/xml/report_hub.xml
Normal file
185
fusion_payroll/static/src/xml/report_hub.xml
Normal file
@@ -0,0 +1,185 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="fusion_payroll.ReportHub">
|
||||
<div class="o_action o_fusion_report_hub">
|
||||
<div class="container-fluid py-4">
|
||||
<!-- Header -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<h1 class="mb-1">
|
||||
<i class="fa fa-bar-chart me-2 text-primary"/>Payroll Reports
|
||||
</h1>
|
||||
<p class="text-muted mb-0">Select a report to view payroll data and analytics</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reports Grid -->
|
||||
<div class="row g-3">
|
||||
<!-- Left Column -->
|
||||
<div class="col-md-6">
|
||||
<!-- Paycheque History -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_paycheque_history')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-file-text-o fa-lg text-primary me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Paycheque History</h6>
|
||||
<small class="text-muted">View all paycheques by date</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Deductions and Contributions -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_deductions')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-minus-circle fa-lg text-primary me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Deductions and Contributions</h6>
|
||||
<small class="text-muted">Employee and company deductions</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payroll Summary by Employee -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_summary_employee')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-users fa-lg text-primary me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Payroll Summary by Employee</h6>
|
||||
<small class="text-muted">Pivot by employee</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payroll Item List -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_employee_directory')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-address-book fa-lg text-primary me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Payroll Item List</h6>
|
||||
<small class="text-muted">Employee pay rates and status</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payroll Details -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_payroll_details')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-list-alt fa-lg text-primary me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Payroll Details</h6>
|
||||
<small class="text-muted">Detailed breakdown per pay period</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payroll Summary -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_summary')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-table fa-lg text-primary me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Payroll Summary</h6>
|
||||
<small class="text-muted">Summary with all components</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Time Off -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_time_off')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-calendar-check-o fa-lg text-primary me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Time Off</h6>
|
||||
<small class="text-muted">Vacation and leave balances</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column -->
|
||||
<div class="col-md-6">
|
||||
<!-- Payroll Tax Liability -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_tax_liability')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-balance-scale fa-lg text-success me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Payroll Tax Liability</h6>
|
||||
<small class="text-muted">Tax amounts owed vs paid</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payroll Tax Payments -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_tax_payments')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-credit-card fa-lg text-success me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Payroll Tax Payments</h6>
|
||||
<small class="text-muted">History of remittance payments</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Total Payroll Cost -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_total_cost')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-calculator fa-lg text-success me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Total Payroll Cost</h6>
|
||||
<small class="text-muted">All payroll costs breakdown</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Total Pay -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_total_pay')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-money fa-lg text-success me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Total Pay</h6>
|
||||
<small class="text-muted">Pay by type per employee</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payroll Tax and Wage Summary -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_tax_wage_summary')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-pie-chart fa-lg text-success me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Payroll Tax and Wage Summary</h6>
|
||||
<small class="text-muted">Wages and tax amounts</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Workers' Compensation -->
|
||||
<div class="card mb-2" style="cursor: pointer;" t-on-click="() => this.openReport('fusion_payroll.action_payroll_report_workers_comp')">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<i class="fa fa-shield fa-lg text-success me-3"/>
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="mb-0">Workers' Compensation</h6>
|
||||
<small class="text-muted">WCB wages by province</small>
|
||||
</div>
|
||||
<i class="fa fa-chevron-right text-muted"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
Reference in New Issue
Block a user