1165 lines
51 KiB
PHP
1165 lines
51 KiB
PHP
<?php
|
|
/*********************************************************************************
|
|
*
|
|
* TimeTrex is a Workforce Management program developed by
|
|
* TimeTrex Software Inc. Copyright (C) 2003 - 2021 TimeTrex Software Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU Affero General Public License version 3 as published by
|
|
* the Free Software Foundation with the addition of the following permission
|
|
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
|
|
* WORK IN WHICH THE COPYRIGHT IS OWNED BY TIMETREX, TIMETREX DISCLAIMS THE
|
|
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
* details.
|
|
*
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License along
|
|
* with this program; if not, see http://www.gnu.org/licenses or write to the Free
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301 USA.
|
|
*
|
|
*
|
|
* You can contact TimeTrex headquarters at Unit 22 - 2475 Dobbin Rd. Suite
|
|
* #292 West Kelowna, BC V4T 2E9, Canada or at email address info@timetrex.com.
|
|
*
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of this program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU Affero General Public License version 3.
|
|
*
|
|
*
|
|
* In accordance with Section 7(b) of the GNU Affero General Public License
|
|
* version 3, these Appropriate Legal Notices must retain the display of the
|
|
* "Powered by TimeTrex" logo. If the display of the logo is not reasonably
|
|
* feasible for technical reasons, the Appropriate Legal Notices must display
|
|
* the words "Powered by TimeTrex".
|
|
*
|
|
********************************************************************************/
|
|
|
|
|
|
/**
|
|
* @package Modules\Report
|
|
*/
|
|
class T4ASummaryReport extends Report {
|
|
|
|
protected $user_ids = [];
|
|
|
|
/**
|
|
* T4ASummaryReport constructor.
|
|
*/
|
|
function __construct() {
|
|
$this->title = TTi18n::getText( 'T4A Summary Report' );
|
|
$this->file_name = 't4a_summary';
|
|
|
|
parent::__construct();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param string $user_id UUID
|
|
* @param string $company_id UUID
|
|
* @return bool
|
|
*/
|
|
protected function _checkPermissions( $user_id, $company_id ) {
|
|
if ( $this->getPermissionObject()->Check( 'report', 'enabled', $user_id, $company_id )
|
|
&& $this->getPermissionObject()->Check( 'report', 'view_t4_summary', $user_id, $company_id ) ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param $name
|
|
* @param null $params
|
|
* @return array|bool|null
|
|
*/
|
|
protected function _getOptions( $name, $params = null ) {
|
|
$retval = null;
|
|
switch ( $name ) {
|
|
case 'output_format':
|
|
$retval = array_merge( parent::getOptions( 'default_output_format' ),
|
|
[
|
|
'-1100-pdf_form' => TTi18n::gettext( 'Employee (One Employee/Page)' ),
|
|
'-1110-pdf_form_government' => TTi18n::gettext( 'Government (Multiple Employees/Page)' ),
|
|
'-1120-efile_xml' => TTi18n::gettext( 'eFile' ),
|
|
]
|
|
);
|
|
break;
|
|
case 'default_setup_fields':
|
|
$retval = [
|
|
'template',
|
|
'time_period',
|
|
'columns',
|
|
];
|
|
|
|
break;
|
|
case 'setup_fields':
|
|
$retval = [
|
|
//Static Columns - Aggregate functions can't be used on these.
|
|
'-1000-template' => TTi18n::gettext( 'Template' ),
|
|
'-1010-time_period' => TTi18n::gettext( 'Time Period' ),
|
|
'-2000-legal_entity_id' => TTi18n::gettext( 'Legal Entity' ),
|
|
'-2010-user_status_id' => TTi18n::gettext( 'Employee Status' ),
|
|
'-2020-user_group_id' => TTi18n::gettext( 'Employee Group' ),
|
|
'-2025-policy_group_id' => TTi18n::gettext( 'Policy Group' ),
|
|
'-2030-user_title_id' => TTi18n::gettext( 'Employee Title' ),
|
|
'-2040-include_user_id' => TTi18n::gettext( 'Employee Include' ),
|
|
'-2050-exclude_user_id' => TTi18n::gettext( 'Employee Exclude' ),
|
|
'-2060-default_branch_id' => TTi18n::gettext( 'Default Branch' ),
|
|
'-2070-default_department_id' => TTi18n::gettext( 'Default Department' ),
|
|
'-3000-custom_filter' => TTi18n::gettext( 'Custom Filter' ),
|
|
|
|
'-5000-columns' => TTi18n::gettext( 'Display Columns' ),
|
|
'-5010-group' => TTi18n::gettext( 'Group By' ),
|
|
'-5020-sub_total' => TTi18n::gettext( 'SubTotal By' ),
|
|
'-5030-sort' => TTi18n::gettext( 'Sort By' ),
|
|
];
|
|
break;
|
|
case 'time_period':
|
|
$retval = TTDate::getTimePeriodOptions( false ); //Exclude Pay Period options.
|
|
break;
|
|
case 'date_columns':
|
|
//$retval = TTDate::getReportDateOptions( NULL, TTi18n::getText('Date'), 13, TRUE );
|
|
$retval = [];
|
|
break;
|
|
case 'report_custom_column':
|
|
if ( getTTProductEdition() >= TT_PRODUCT_PROFESSIONAL ) {
|
|
$rcclf = TTnew( 'ReportCustomColumnListFactory' ); /** @var ReportCustomColumnListFactory $rcclf */
|
|
// Because the Filter type is just only a filter criteria and not need to be as an option of Display Columns, Group By, Sub Total, Sort By dropdowns.
|
|
// So just get custom columns with Selection and Formula.
|
|
$custom_column_labels = $rcclf->getByCompanyIdAndTypeIdAndFormatIdAndScriptArray( $this->getUserObject()->getCompany(), $rcclf->getOptions( 'display_column_type_ids' ), null, 'T4ASummaryReport', 'custom_column' );
|
|
if ( is_array( $custom_column_labels ) ) {
|
|
$retval = Misc::addSortPrefix( $custom_column_labels, 9500 );
|
|
}
|
|
}
|
|
break;
|
|
case 'report_custom_filters':
|
|
if ( getTTProductEdition() >= TT_PRODUCT_PROFESSIONAL ) {
|
|
$rcclf = TTnew( 'ReportCustomColumnListFactory' ); /** @var ReportCustomColumnListFactory $rcclf */
|
|
$retval = $rcclf->getByCompanyIdAndTypeIdAndFormatIdAndScriptArray( $this->getUserObject()->getCompany(), $rcclf->getOptions( 'filter_column_type_ids' ), null, 'T4ASummaryReport', 'custom_column' );
|
|
}
|
|
break;
|
|
case 'report_dynamic_custom_column':
|
|
if ( getTTProductEdition() >= TT_PRODUCT_PROFESSIONAL ) {
|
|
$rcclf = TTnew( 'ReportCustomColumnListFactory' ); /** @var ReportCustomColumnListFactory $rcclf */
|
|
$report_dynamic_custom_column_labels = $rcclf->getByCompanyIdAndTypeIdAndFormatIdAndScriptArray( $this->getUserObject()->getCompany(), $rcclf->getOptions( 'display_column_type_ids' ), $rcclf->getOptions( 'dynamic_format_ids' ), 'T4ASummaryReport', 'custom_column' );
|
|
if ( is_array( $report_dynamic_custom_column_labels ) ) {
|
|
$retval = Misc::addSortPrefix( $report_dynamic_custom_column_labels, 9700 );
|
|
}
|
|
}
|
|
break;
|
|
case 'report_static_custom_column':
|
|
if ( getTTProductEdition() >= TT_PRODUCT_PROFESSIONAL ) {
|
|
$rcclf = TTnew( 'ReportCustomColumnListFactory' ); /** @var ReportCustomColumnListFactory $rcclf */
|
|
$report_static_custom_column_labels = $rcclf->getByCompanyIdAndTypeIdAndFormatIdAndScriptArray( $this->getUserObject()->getCompany(), $rcclf->getOptions( 'display_column_type_ids' ), $rcclf->getOptions( 'static_format_ids' ), 'T4ASummaryReport', 'custom_column' );
|
|
if ( is_array( $report_static_custom_column_labels ) ) {
|
|
$retval = Misc::addSortPrefix( $report_static_custom_column_labels, 9700 );
|
|
}
|
|
}
|
|
break;
|
|
case 'formula_columns':
|
|
$retval = TTMath::formatFormulaColumns( array_merge( array_diff( $this->getOptions( 'static_columns' ), (array)$this->getOptions( 'report_static_custom_column' ) ), $this->getOptions( 'dynamic_columns' ) ) );
|
|
break;
|
|
case 'filter_columns':
|
|
$retval = TTMath::formatFormulaColumns( array_merge( $this->getOptions( 'static_columns' ), $this->getOptions( 'dynamic_columns' ), (array)$this->getOptions( 'report_dynamic_custom_column' ) ) );
|
|
break;
|
|
case 'static_columns':
|
|
$retval = [
|
|
//Static Columns - Aggregate functions can't be used on these.
|
|
'-0900-legal_entity_legal_name' => TTi18n::gettext( 'Legal Entity Name' ),
|
|
'-0910-legal_entity_trade_name' => TTi18n::gettext( 'Legal Entity Trade Name' ),
|
|
|
|
'-1000-first_name' => TTi18n::gettext( 'First Name' ),
|
|
'-1001-middle_name' => TTi18n::gettext( 'Middle Name' ),
|
|
'-1002-last_name' => TTi18n::gettext( 'Last Name' ),
|
|
'-1005-full_name' => TTi18n::gettext( 'Full Name' ),
|
|
'-1030-employee_number' => TTi18n::gettext( 'Employee #' ),
|
|
'-1035-sin' => TTi18n::gettext( 'SIN/SSN' ),
|
|
'-1040-status' => TTi18n::gettext( 'Status' ),
|
|
'-1050-title' => TTi18n::gettext( 'Title' ),
|
|
'-1060-province' => TTi18n::gettext( 'Province/State' ),
|
|
'-1070-country' => TTi18n::gettext( 'Country' ),
|
|
'-1080-group' => TTi18n::gettext( 'Group' ),
|
|
'-1090-default_branch' => TTi18n::gettext( 'Default Branch' ),
|
|
'-1100-default_department' => TTi18n::gettext( 'Default Department' ),
|
|
'-1110-currency' => TTi18n::gettext( 'Currency' ),
|
|
'-1400-permission_control' => TTi18n::gettext( 'Permission Group' ),
|
|
'-1410-pay_period_schedule' => TTi18n::gettext( 'Pay Period Schedule' ),
|
|
'-1420-policy_group' => TTi18n::gettext( 'Policy Group' ),
|
|
];
|
|
|
|
$retval = array_merge( $retval, $this->getOptions( 'date_columns' ), (array)$this->getOptions( 'report_static_custom_column' ) );
|
|
ksort( $retval );
|
|
break;
|
|
case 'dynamic_columns':
|
|
$retval = [
|
|
//Dynamic - Aggregate functions can be used
|
|
'-2110-income_tax' => TTi18n::gettext( 'Income Tax (22)' ),
|
|
'-2115-pension' => TTi18n::gettext( 'Pension/Superannuation (16)' ),
|
|
'-2120-lump_sum_payment' => TTi18n::gettext( 'Lump Sum Payment (18)' ),
|
|
'-2130-self_employed_commission' => TTi18n::gettext( 'Self-Employed Commission (20)' ),
|
|
'-2135-annuities' => TTi18n::gettext( 'Annuities (24)' ),
|
|
'-2140-service_fees' => TTi18n::gettext( 'Service Fees (24)' ),
|
|
'-2200-other_box_0' => TTi18n::gettext( 'Other Box 1' ),
|
|
'-2210-other_box_1' => TTi18n::gettext( 'Other Box 2' ),
|
|
'-2220-other_box_2' => TTi18n::gettext( 'Other Box 3' ),
|
|
'-2220-other_box_3' => TTi18n::gettext( 'Other Box 4' ),
|
|
'-2220-other_box_4' => TTi18n::gettext( 'Other Box 5' ),
|
|
'-2220-other_box_5' => TTi18n::gettext( 'Other Box 6' ),
|
|
];
|
|
break;
|
|
case 'columns':
|
|
$retval = array_merge( $this->getOptions( 'static_columns' ), $this->getOptions( 'dynamic_columns' ), (array)$this->getOptions( 'report_dynamic_custom_column' ) );
|
|
ksort( $retval );
|
|
break;
|
|
case 'column_format':
|
|
//Define formatting function for each column.
|
|
$columns = array_merge( $this->getOptions( 'dynamic_columns' ), (array)$this->getOptions( 'report_custom_column' ) );
|
|
if ( is_array( $columns ) ) {
|
|
foreach ( $columns as $column => $name ) {
|
|
$retval[$column] = 'currency';
|
|
}
|
|
}
|
|
break;
|
|
case 'aggregates':
|
|
$retval = [];
|
|
$dynamic_columns = array_keys( Misc::trimSortPrefix( array_merge( $this->getOptions( 'dynamic_columns' ), (array)$this->getOptions( 'report_dynamic_custom_column' ) ) ) );
|
|
if ( is_array( $dynamic_columns ) ) {
|
|
foreach ( $dynamic_columns as $column ) {
|
|
switch ( $column ) {
|
|
default:
|
|
$retval[$column] = 'sum';
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 'type':
|
|
$retval = [
|
|
'-1010-O' => TTi18n::getText( 'Original' ),
|
|
'-1020-A' => TTi18n::getText( 'Amended' ),
|
|
'-1030-C' => TTi18n::getText( 'Cancel' ),
|
|
];
|
|
break;
|
|
case 'templates':
|
|
$retval = [
|
|
//'-1010-by_month' => TTi18n::gettext('by Month'),
|
|
'-1020-by_employee' => TTi18n::gettext( 'by Employee' ),
|
|
'-1030-by_branch' => TTi18n::gettext( 'by Branch' ),
|
|
'-1040-by_department' => TTi18n::gettext( 'by Department' ),
|
|
'-1050-by_branch_by_department' => TTi18n::gettext( 'by Branch/Department' ),
|
|
|
|
//'-1060-by_month_by_employee' => TTi18n::gettext('by Month/Employee'),
|
|
//'-1070-by_month_by_branch' => TTi18n::gettext('by Month/Branch'),
|
|
//'-1080-by_month_by_department' => TTi18n::gettext('by Month/Department'),
|
|
//'-1090-by_month_by_branch_by_department' => TTi18n::gettext('by Month/Branch/Department'),
|
|
];
|
|
|
|
break;
|
|
case 'template_config':
|
|
$template = strtolower( Misc::trimSortPrefix( $params['template'] ) );
|
|
if ( isset( $template ) && $template != '' ) {
|
|
switch ( $template ) {
|
|
case 'default':
|
|
//Proper settings to generate the form.
|
|
//$retval['-1010-time_period']['time_period'] = 'last_quarter';
|
|
|
|
$retval['columns'] = $this->getOptions( 'columns' );
|
|
|
|
$retval['group'][] = 'date_quarter_month';
|
|
|
|
$retval['sort'][] = [ 'date_quarter_month' => 'asc' ];
|
|
|
|
$retval['other']['grand_total'] = true;
|
|
|
|
break;
|
|
default:
|
|
Debug::Text( ' Parsing template name: ' . $template, __FILE__, __LINE__, __METHOD__, 10 );
|
|
$retval['columns'] = [];
|
|
$retval['-1010-time_period']['time_period'] = 'last_year';
|
|
|
|
//Parse template name, and use the keywords separated by '+' to determine settings.
|
|
$template_keywords = explode( '+', $template );
|
|
if ( is_array( $template_keywords ) ) {
|
|
foreach ( $template_keywords as $template_keyword ) {
|
|
Debug::Text( ' Keyword: ' . $template_keyword, __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
switch ( $template_keyword ) {
|
|
//Columns
|
|
|
|
//Filter
|
|
//Group By
|
|
//SubTotal
|
|
//Sort
|
|
case 'by_month':
|
|
$retval['columns'][] = 'date_month';
|
|
|
|
$retval['group'][] = 'date_month';
|
|
|
|
$retval['sort'][] = [ 'date_month' => 'asc' ];
|
|
break;
|
|
case 'by_employee':
|
|
$retval['columns'][] = 'first_name';
|
|
$retval['columns'][] = 'last_name';
|
|
|
|
$retval['group'][] = 'first_name';
|
|
$retval['group'][] = 'last_name';
|
|
|
|
$retval['sort'][] = [ 'last_name' => 'asc' ];
|
|
$retval['sort'][] = [ 'first_name' => 'asc' ];
|
|
break;
|
|
case 'by_branch':
|
|
$retval['columns'][] = 'default_branch';
|
|
|
|
$retval['group'][] = 'default_branch';
|
|
|
|
$retval['sort'][] = [ 'default_branch' => 'asc' ];
|
|
break;
|
|
case 'by_department':
|
|
$retval['columns'][] = 'default_department';
|
|
|
|
$retval['group'][] = 'default_department';
|
|
|
|
$retval['sort'][] = [ 'default_department' => 'asc' ];
|
|
break;
|
|
case 'by_branch_by_department':
|
|
$retval['columns'][] = 'default_branch';
|
|
$retval['columns'][] = 'default_department';
|
|
|
|
$retval['group'][] = 'default_branch';
|
|
$retval['group'][] = 'default_department';
|
|
|
|
$retval['sub_total'][] = 'default_branch';
|
|
|
|
$retval['sort'][] = [ 'default_branch' => 'asc' ];
|
|
$retval['sort'][] = [ 'default_department' => 'asc' ];
|
|
break;
|
|
case 'by_month_by_employee':
|
|
$retval['columns'][] = 'date_month';
|
|
$retval['columns'][] = 'first_name';
|
|
$retval['columns'][] = 'last_name';
|
|
|
|
$retval['group'][] = 'date_month';
|
|
$retval['group'][] = 'first_name';
|
|
$retval['group'][] = 'last_name';
|
|
|
|
$retval['sub_total'][] = 'date_month';
|
|
|
|
$retval['sort'][] = [ 'date_month' => 'asc' ];
|
|
$retval['sort'][] = [ 'last_name' => 'asc' ];
|
|
$retval['sort'][] = [ 'first_name' => 'asc' ];
|
|
break;
|
|
case 'by_month_by_branch':
|
|
$retval['columns'][] = 'date_month';
|
|
$retval['columns'][] = 'default_branch';
|
|
|
|
$retval['group'][] = 'date_month';
|
|
$retval['group'][] = 'default_branch';
|
|
|
|
$retval['sub_total'][] = 'date_month';
|
|
|
|
$retval['sort'][] = [ 'date_month' => 'asc' ];
|
|
$retval['sort'][] = [ 'default_branch' => 'asc' ];
|
|
break;
|
|
case 'by_month_by_department':
|
|
$retval['columns'][] = 'date_month';
|
|
$retval['columns'][] = 'default_department';
|
|
|
|
$retval['group'][] = 'date_month';
|
|
$retval['group'][] = 'default_department';
|
|
|
|
$retval['sub_total'][] = 'date_month';
|
|
|
|
$retval['sort'][] = [ 'date_month' => 'asc' ];
|
|
$retval['sort'][] = [ 'default_department' => 'asc' ];
|
|
break;
|
|
case 'by_month_by_branch_by_department':
|
|
$retval['columns'][] = 'date_month';
|
|
$retval['columns'][] = 'default_branch';
|
|
$retval['columns'][] = 'default_department';
|
|
|
|
$retval['group'][] = 'date_month';
|
|
$retval['group'][] = 'default_branch';
|
|
$retval['group'][] = 'default_department';
|
|
|
|
$retval['sub_total'][] = 'date_month';
|
|
$retval['sub_total'][] = 'default_branch';
|
|
|
|
$retval['sort'][] = [ 'date_month' => 'asc' ];
|
|
$retval['sort'][] = [ 'default_branch' => 'asc' ];
|
|
$retval['sort'][] = [ 'default_department' => 'asc' ];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$retval['columns'] = array_merge( $retval['columns'], array_keys( Misc::trimSortPrefix( $this->getOptions( 'dynamic_columns' ) ) ) );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//Set the template dropdown as well.
|
|
$retval['-1000-template'] = $template;
|
|
|
|
//Add sort prefixes so Flex can maintain order.
|
|
if ( isset( $retval['filter'] ) ) {
|
|
$retval['-5000-filter'] = $retval['filter'];
|
|
unset( $retval['filter'] );
|
|
}
|
|
if ( isset( $retval['columns'] ) ) {
|
|
$retval['-5010-columns'] = $retval['columns'];
|
|
unset( $retval['columns'] );
|
|
}
|
|
if ( isset( $retval['group'] ) ) {
|
|
$retval['-5020-group'] = $retval['group'];
|
|
unset( $retval['group'] );
|
|
}
|
|
if ( isset( $retval['sub_total'] ) ) {
|
|
$retval['-5030-sub_total'] = $retval['sub_total'];
|
|
unset( $retval['sub_total'] );
|
|
}
|
|
if ( isset( $retval['sort'] ) ) {
|
|
$retval['-5040-sort'] = $retval['sort'];
|
|
unset( $retval['sort'] );
|
|
}
|
|
Debug::Arr( $retval, ' Template Config for: ' . $template, __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
break;
|
|
default:
|
|
//Call report parent class options function for options valid for all reports.
|
|
$retval = $this->__getOptions( $name );
|
|
break;
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
function getFormObject() {
|
|
if ( !isset( $this->form_obj['gf'] ) || !is_object( $this->form_obj['gf'] ) ) {
|
|
//
|
|
//Get all data for the form.
|
|
//
|
|
require_once( Environment::getBasePath() . '/classes/GovernmentForms/GovernmentForms.class.php' );
|
|
|
|
$gf = new GovernmentForms();
|
|
|
|
$this->form_obj['gf'] = $gf;
|
|
|
|
return $this->form_obj['gf'];
|
|
}
|
|
|
|
return $this->form_obj['gf'];
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
function clearFormObject() {
|
|
unset( $this->form_obj['gf'] );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
function getT4AObject() {
|
|
if ( !isset( $this->form_obj['t4a'] ) || !is_object( $this->form_obj['t4a'] ) ) {
|
|
$this->form_obj['t4a'] = $this->getFormObject()->getFormObject( 'T4A', 'CA' );
|
|
|
|
return $this->form_obj['t4a'];
|
|
}
|
|
|
|
return $this->form_obj['t4a'];
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
function clearT4AObject() {
|
|
unset( $this->form_obj['t4a'] );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
function getT4ASumObject() {
|
|
if ( !isset( $this->form_obj['t4asum'] ) || !is_object( $this->form_obj['t4asum'] ) ) {
|
|
$this->form_obj['t4asum'] = $this->getFormObject()->getFormObject( 'T4ASum', 'CA' );
|
|
|
|
return $this->form_obj['t4asum'];
|
|
}
|
|
|
|
return $this->form_obj['t4asum'];
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
function clearT4ASumObject() {
|
|
unset( $this->form_obj['t4asum'] );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
function getT619Object() {
|
|
if ( !isset( $this->form_obj['t619'] ) || !is_object( $this->form_obj['t619'] ) ) {
|
|
$this->form_obj['t619'] = $this->getFormObject()->getFormObject( 'T619', 'CA' );
|
|
|
|
return $this->form_obj['t619'];
|
|
}
|
|
|
|
return $this->form_obj['t619'];
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
function clearT619SumObject() {
|
|
unset( $this->form_obj['t619'] );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
function formatFormConfig() {
|
|
$default_include_exclude_arr = [ 'include_pay_stub_entry_account' => [], 'exclude_pay_stub_entry_account' => [] ];
|
|
|
|
$default_arr = [
|
|
'pension' => $default_include_exclude_arr,
|
|
'lump_sum_payment' => $default_include_exclude_arr,
|
|
'income_tax' => $default_include_exclude_arr,
|
|
'annuities' => $default_include_exclude_arr,
|
|
'self_employed_commission' => $default_include_exclude_arr,
|
|
'service_fees' => $default_include_exclude_arr,
|
|
'other_box' => [
|
|
0 => $default_include_exclude_arr,
|
|
1 => $default_include_exclude_arr,
|
|
2 => $default_include_exclude_arr,
|
|
3 => $default_include_exclude_arr,
|
|
4 => $default_include_exclude_arr,
|
|
5 => $default_include_exclude_arr,
|
|
6 => $default_include_exclude_arr,
|
|
],
|
|
];
|
|
|
|
$retarr = array_merge( $default_arr, (array)$this->getFormConfig() );
|
|
|
|
return $retarr;
|
|
}
|
|
|
|
/**
|
|
* Get raw data for report
|
|
* @param null $format
|
|
* @return bool
|
|
*/
|
|
function _getData( $format = null ) {
|
|
$this->tmp_data = [ 'pay_stub_entry' => [], 'user' => [], 'legal_entity' => [] ];
|
|
|
|
$filter_data = $this->getFilterConfig();
|
|
$form_data = $this->formatFormConfig();
|
|
|
|
$pself = TTnew( 'PayStubEntryListFactory' ); /** @var PayStubEntryListFactory $pself */
|
|
$pself->getAPIReportByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), $filter_data );
|
|
$this->getProgressBarObject()->start( $this->getAPIMessageID(), $pself->getRecordCount(), null, TTi18n::getText( 'Retrieving Data...' ) );
|
|
if ( $pself->getRecordCount() > 0 ) {
|
|
foreach ( $pself as $key => $pse_obj ) {
|
|
$user_id = $this->user_ids[] = $pse_obj->getColumn( 'user_id' );
|
|
$pay_stub_entry_name_id = $pse_obj->getPayStubEntryNameId();
|
|
|
|
if ( !isset( $this->tmp_data['pay_stub_entry'][$user_id] ) ) {
|
|
$this->tmp_data['pay_stub_entry'][$user_id] = [
|
|
'date_stamp' => strtotime( $pse_obj->getColumn( 'pay_stub_transaction_date' ) ),
|
|
'pay_period_start_date' => strtotime( $pse_obj->getColumn( 'pay_stub_start_date' ) ),
|
|
'pay_period_end_date' => strtotime( $pse_obj->getColumn( 'pay_stub_end_date' ) ),
|
|
'pay_period_transaction_date' => strtotime( $pse_obj->getColumn( 'pay_stub_transaction_date' ) ),
|
|
'pay_period' => strtotime( $pse_obj->getColumn( 'pay_stub_transaction_date' ) ),
|
|
];
|
|
}
|
|
|
|
|
|
if ( isset( $this->tmp_data['pay_stub_entry'][$user_id]['psen_ids'][$pay_stub_entry_name_id] ) ) {
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['psen_ids'][$pay_stub_entry_name_id] = bcadd( $this->tmp_data['pay_stub_entry'][$user_id]['psen_ids'][$pay_stub_entry_name_id], $pse_obj->getColumn( 'amount' ) );
|
|
} else {
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['psen_ids'][$pay_stub_entry_name_id] = $pse_obj->getColumn( 'amount' );
|
|
}
|
|
|
|
$this->getProgressBarObject()->set( $this->getAPIMessageID(), $key );
|
|
}
|
|
|
|
if ( isset( $this->tmp_data['pay_stub_entry'] ) && is_array( $this->tmp_data['pay_stub_entry'] ) ) {
|
|
foreach ( $this->tmp_data['pay_stub_entry'] as $user_id => $data_b ) {
|
|
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['pension'] = Misc::calculateMultipleColumns( $data_b['psen_ids'], $form_data['pension']['include_pay_stub_entry_account'], $form_data['pension']['exclude_pay_stub_entry_account'] );
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['lump_sum_payment'] = Misc::calculateMultipleColumns( $data_b['psen_ids'], $form_data['lump_sum_payment']['include_pay_stub_entry_account'], $form_data['lump_sum_payment']['exclude_pay_stub_entry_account'] );
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['income_tax'] = Misc::calculateMultipleColumns( $data_b['psen_ids'], $form_data['income_tax']['include_pay_stub_entry_account'], $form_data['income_tax']['exclude_pay_stub_entry_account'] );
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['annuities'] = Misc::calculateMultipleColumns( $data_b['psen_ids'], $form_data['annuities']['include_pay_stub_entry_account'], $form_data['annuities']['exclude_pay_stub_entry_account'] );
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['self_employed_commission'] = Misc::calculateMultipleColumns( $data_b['psen_ids'], $form_data['self_employed_commission']['include_pay_stub_entry_account'], $form_data['self_employed_commission']['exclude_pay_stub_entry_account'] );
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['service_fees'] = Misc::calculateMultipleColumns( $data_b['psen_ids'], $form_data['service_fees']['include_pay_stub_entry_account'], $form_data['service_fees']['exclude_pay_stub_entry_account'] );
|
|
|
|
for ( $n = 0; $n <= 5; $n++ ) {
|
|
if ( isset( $form_data['other_box'][$n] ) ) {
|
|
$this->tmp_data['pay_stub_entry'][$user_id]['other_box_' . $n] = Misc::calculateMultipleColumns( $data_b['psen_ids'], $form_data['other_box'][$n]['include_pay_stub_entry_account'], $form_data['other_box'][$n]['exclude_pay_stub_entry_account'] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->user_ids = array_unique( $this->user_ids ); //Used to get the total number of employees.
|
|
|
|
//Debug::Arr($this->user_ids, 'User IDs: ', __FILE__, __LINE__, __METHOD__, 10);
|
|
//Debug::Arr($this->form_data, 'Form Raw Data: ', __FILE__, __LINE__, __METHOD__, 10);
|
|
//Debug::Arr($this->tmp_data, 'Tmp Raw Data: ', __FILE__, __LINE__, __METHOD__, 10);
|
|
|
|
//Get user data for joining.
|
|
$ulf = TTnew( 'UserListFactory' ); /** @var UserListFactory $ulf */
|
|
$ulf->getAPISearchByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), $filter_data );
|
|
//Debug::Text(' User Total Rows: '. $ulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
|
|
$this->getProgressBarObject()->start( $this->getAPIMessageID(), $ulf->getRecordCount(), null, TTi18n::getText( 'Retrieving Data...' ) );
|
|
foreach ( $ulf as $key => $u_obj ) {
|
|
$this->tmp_data['user'][$u_obj->getId()] = (array)$u_obj->getObjectAsArray( $this->getColumnDataConfig() );
|
|
$this->tmp_data['user'][$u_obj->getId()]['user_id'] = $u_obj->getId();
|
|
$this->tmp_data['user'][$u_obj->getId()]['legal_entity_id'] = $u_obj->getLegalEntity();
|
|
$this->getProgressBarObject()->set( $this->getAPIMessageID(), $key );
|
|
}
|
|
|
|
//Get legal entity data for joining.
|
|
$lelf = TTnew( 'LegalEntityListFactory' ); /** @var LegalEntityListFactory $lelf */
|
|
$lelf->getAPISearchByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), $filter_data );
|
|
//Debug::Text( ' User Total Rows: ' . $lelf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10 );
|
|
$this->getProgressBarObject()->start( $this->getAPIMessageID(), $lelf->getRecordCount(), null, TTi18n::getText( 'Retrieving Legal Entity Data...' ) );
|
|
if ( $lelf->getRecordCount() > 0 ) {
|
|
foreach ( $lelf as $key => $le_obj ) {
|
|
if ( $format == 'html' || $format == 'pdf' ) {
|
|
$this->tmp_data['legal_entity'][$le_obj->getId()] = Misc::addKeyPrefix( 'legal_entity_', (array)$le_obj->getObjectAsArray( Misc::removeKeyPrefix( 'legal_entity_', $this->getColumnDataConfig() ) ) );
|
|
$this->tmp_data['legal_entity'][$le_obj->getId()]['legal_entity_id'] = $le_obj->getId();
|
|
} else {
|
|
$this->form_data['legal_entity'][$le_obj->getId()] = $le_obj;
|
|
}
|
|
$this->getProgressBarObject()->set( $this->getAPIMessageID(), $key );
|
|
}
|
|
}
|
|
//Debug::Arr($this->tmp_data['user'], 'User Raw Data: ', __FILE__, __LINE__, __METHOD__, 10);
|
|
|
|
$this->tmp_data['remittance_agency'] = [];
|
|
|
|
$filter_data['agency_id'] = [ '10:CA:00:00:0010' ]; //CA federal
|
|
$ralf = TTnew( 'PayrollRemittanceAgencyListFactory' ); /** @var PayrollRemittanceAgencyListFactory $ralf */
|
|
$ralf->getAPISearchByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), $filter_data );
|
|
//Debug::Text( ' Remittance Agency Total Rows: ' . $ralf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10 );
|
|
$this->getProgressBarObject()->start( $this->getAPIMessageID(), $lelf->getRecordCount(), null, TTi18n::getText( 'Retrieving Remittance Agency Data...' ) );
|
|
if ( $ralf->getRecordCount() > 0 ) {
|
|
foreach ( $ralf as $key => $ra_obj ) {
|
|
$this->form_data['remittance_agency'][$ra_obj->getLegalEntity()] = $ra_obj;
|
|
$this->getProgressBarObject()->set( $this->getAPIMessageID(), $key );
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* PreProcess data such as calculating additional columns from raw data etc...
|
|
* @param null $format
|
|
* @return bool
|
|
*/
|
|
function _preProcess( $format = null ) {
|
|
//Merge time data with user data
|
|
$key = 0;
|
|
if ( isset( $this->tmp_data['pay_stub_entry'] ) ) {
|
|
$this->getProgressBarObject()->start( $this->getAPIMessageID(), count( $this->tmp_data['pay_stub_entry'] ), null, TTi18n::getText( 'Pre-Processing Data...' ) );
|
|
|
|
//$sort_columns = $this->getSortConfig();
|
|
|
|
foreach ( $this->tmp_data['pay_stub_entry'] as $user_id => $row ) {
|
|
if ( isset( $this->tmp_data['user'][$user_id] ) ) {
|
|
$date_columns = TTDate::getReportDates( null, $row['date_stamp'], false, $this->getUserObject(), [ 'pay_period_start_date' => $row['pay_period_start_date'], 'pay_period_end_date' => $row['pay_period_end_date'], 'pay_period_transaction_date' => $row['pay_period_transaction_date'] ] );
|
|
$processed_data = [ 'user_id' => $user_id ];
|
|
|
|
$tmp_legal_array = [];
|
|
if ( isset( $this->tmp_data['legal_entity'][$this->tmp_data['user'][$user_id]['legal_entity_id']] ) ) {
|
|
$tmp_legal_array = $this->tmp_data['legal_entity'][$this->tmp_data['user'][$user_id]['legal_entity_id']];
|
|
}
|
|
|
|
$this->data[] = array_merge( $this->tmp_data['user'][$user_id], $row, $date_columns, $processed_data, $tmp_legal_array );
|
|
|
|
$this->getProgressBarObject()->set( $this->getAPIMessageID(), $key );
|
|
$key++;
|
|
}
|
|
}
|
|
unset( $row, $date_columns, $processed_data, $tmp_legal_array );
|
|
}
|
|
|
|
//Total data per employee for the T4 forms. Just include the columns that are necessary for the form.
|
|
if ( is_array( $this->data ) && !( $format == 'html' || $format == 'pdf' ) ) {
|
|
$t4_dollar_columns = [ 'income', 'tax', 'employee_cpp', 'ei_earnings', 'cpp_earnings', 'employee_ei', 'union_dues', 'rpp', 'charity', 'pension_adjustment', 'employer_ei', 'employer_cpp', 'other_box_0', 'other_box_1', 'other_box_2', 'other_box_3', 'other_box_4' ];
|
|
|
|
Debug::Text( 'Calculating Form Data...', __FILE__, __LINE__, __METHOD__, 10 );
|
|
foreach ( $this->data as $row ) {
|
|
if ( !isset( $this->form_data['user'][$row['legal_entity_id']][$row['user_id']] ) ) {
|
|
$this->form_data['user'][$row['legal_entity_id']][$row['user_id']] = [ 'user_id' => $row['user_id'] ];
|
|
}
|
|
|
|
foreach ( $row as $key => $value ) {
|
|
if ( in_array( $key, $t4_dollar_columns ) ) {
|
|
if ( !isset( $this->form_data['user'][$row['legal_entity_id']][$row['user_id']][$key] ) ) {
|
|
$this->form_data['user'][$row['legal_entity_id']][$row['user_id']][$key] = 0;
|
|
}
|
|
$this->form_data['user'][$row['legal_entity_id']][$row['user_id']][$key] = bcadd( $this->form_data['user'][$row['legal_entity_id']][$row['user_id']][$key], $value );
|
|
} else {
|
|
$this->form_data['user'][$row['legal_entity_id']][$row['user_id']][$key] = $value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param null $format
|
|
* @return array|bool
|
|
*/
|
|
function _outputPDFForm( $format = null ) {
|
|
Debug::Text( 'Generating Form... Format: ' . $format, __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
$setup_data = $this->getFormConfig();
|
|
$filter_data = $this->getFilterConfig();
|
|
// Debug::Arr($setup_data, 'Setup Data: ', __FILE__, __LINE__, __METHOD__, 10);
|
|
// Debug::Arr($filter_data, 'Filter Data: ', __FILE__, __LINE__, __METHOD__, 10);
|
|
// Debug::Arr($this->data, 'Data: ', __FILE__, __LINE__, __METHOD__, 10);
|
|
|
|
$current_company = $this->getUserObject()->getCompanyObject();
|
|
if ( !is_object( $current_company ) ) {
|
|
Debug::Text( 'Invalid company object...', __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( !isset( $setup_data['status_id'] ) || ( is_numeric( $setup_data['status_id'] ) && $setup_data['status_id'] == 0 ) ) {
|
|
$setup_data['status_id'] = 'O'; //Original
|
|
}
|
|
|
|
if ( stristr( $format, 'government' ) ) {
|
|
$form_type = 'government';
|
|
} else {
|
|
$form_type = 'employee';
|
|
}
|
|
$file_arr = [];
|
|
$file_name = null;
|
|
if ( isset( $this->form_data['user'] ) && is_array( $this->form_data['user'] ) ) {
|
|
$file_name = 't4a_summary.ext';
|
|
|
|
$this->sortFormData(); //Make sure forms are sorted.
|
|
|
|
foreach ( $this->form_data['user'] as $legal_entity_id => $user_rows ) {
|
|
if ( isset( $this->form_data['legal_entity'][$legal_entity_id] ) == false ) {
|
|
Debug::Text( 'Missing Legal Entity: ' . $legal_entity_id, __FILE__, __LINE__, __METHOD__, 10 );
|
|
continue;
|
|
}
|
|
|
|
if ( isset( $this->form_data['remittance_agency'][$legal_entity_id] ) == false ) {
|
|
Debug::Text( 'Missing Remittance Agency: ' . $legal_entity_id, __FILE__, __LINE__, __METHOD__, 10 );
|
|
continue;
|
|
}
|
|
|
|
$x = 0; //Progress bar only.
|
|
$this->getProgressBarObject()->start( $this->getAPIMessageID(), count( $user_rows ), null, TTi18n::getText( 'Generating Forms...' ) );
|
|
|
|
$legal_entity_obj = $this->form_data['legal_entity'][$legal_entity_id];
|
|
$company_name = $legal_entity_obj->getTradeName(); //T4As show Operating/Trade name on the forms.
|
|
|
|
if ( is_object( $this->form_data['remittance_agency'][$legal_entity_id] ) ) {
|
|
$contact_user_obj = $this->form_data['remittance_agency'][$legal_entity_id]->getContactUserObject();
|
|
}
|
|
if ( !isset( $contact_user_obj ) || !is_object( $contact_user_obj ) ) {
|
|
$contact_user_obj = $this->getUserObject();
|
|
}
|
|
|
|
if ( $format == 'efile_xml' || $format == 'payment_services' ) {
|
|
$t619 = $this->getT619Object();
|
|
$t619->setStatus( $setup_data['status_id'] );
|
|
$t619->transmitter_number = $this->form_data['remittance_agency'][$legal_entity_id]->getSecondaryIdentification();
|
|
|
|
$t619->transmitter_name = $legal_entity_obj->getTradeName();
|
|
$t619->transmitter_address1 = $legal_entity_obj->getAddress1();
|
|
$t619->transmitter_address2 = $legal_entity_obj->getAddress2();
|
|
$t619->transmitter_city = $legal_entity_obj->getCity();
|
|
$t619->transmitter_province = $legal_entity_obj->getProvince();
|
|
$t619->transmitter_postal_code = $legal_entity_obj->getPostalCode();
|
|
|
|
$t619->contact_name = $contact_user_obj->getFullName();
|
|
$t619->contact_phone = $contact_user_obj->getWorkPhone();
|
|
$t619->contact_email = ( $contact_user_obj->getWorkEmail() != '' ) ? $contact_user_obj->getWorkEmail() : ( ( $contact_user_obj->getHomeEmail() != '' ) ? $contact_user_obj->getHomeEmail() : ( Misc::getEmailLocalPart() . '@' . Misc::getEmailDomain() ) ); //If no email address is specified, just do the DoNotReply one instead, otherwise it could cause an error generating the eFile format.
|
|
$t619->company_name = $company_name;
|
|
$this->getFormObject()->addForm( $t619 );
|
|
}
|
|
|
|
$t4a = $this->getT4AObject();
|
|
if ( isset( $setup_data['include_t4a_back'] ) && $setup_data['include_t4a_back'] == 1 ) {
|
|
$t4a->setShowInstructionPage( true );
|
|
}
|
|
Debug::Text( 'Form Type: ' . $form_type, __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
$t4a->setType( $form_type );
|
|
$t4a->setStatus( $setup_data['status_id'] );
|
|
$t4a->year = TTDate::getYear( $filter_data['start_date'] );
|
|
if ( isset( $this->form_data['remittance_agency'][$legal_entity_id] ) ) {
|
|
$t4a->payroll_account_number = $this->form_data['remittance_agency'][$legal_entity_id]->getPrimaryIdentification();//( isset( $setup_data['payroll_account_number'] ) AND $setup_data['payroll_account_number'] != '' ) ? $setup_data['payroll_account_number'] : $current_company->getBusinessNumber();
|
|
$t4a->company_name = $company_name;
|
|
}
|
|
|
|
$report_meta_data = [];
|
|
foreach ( $user_rows as $user_row_key => $row ) {
|
|
if ( !isset( $row['user_id'] ) ) {
|
|
Debug::Text( 'User ID not set!', __FILE__, __LINE__, __METHOD__, 10 );
|
|
continue;
|
|
}
|
|
|
|
$ulf = TTnew( 'UserListFactory' ); /** @var UserListFactory $ulf */
|
|
$ulf->getById( TTUUID::castUUID( $row['user_id'] ) );
|
|
if ( $ulf->getRecordCount() == 1 ) {
|
|
$user_obj = $ulf->getCurrent();
|
|
|
|
$employment_province = $user_obj->getProvince();
|
|
//If employees address is out of the country, use the company province instead.
|
|
if ( strtolower( $user_obj->getCountry() ) != 'ca' ) {
|
|
$employment_province = $legal_entity_obj->getProvince();
|
|
Debug::Text( ' Using Company Province of Employment: ' . $employment_province, __FILE__, __LINE__, __METHOD__, 10 );
|
|
}
|
|
|
|
//Determine the province of employment...
|
|
$cdlf = TTnew( 'CompanyDeductionListFactory' ); /** @var CompanyDeductionListFactory $cdlf */
|
|
if ( isset( $setup_data['tax']['include_pay_stub_entry_account'] ) ) {
|
|
$cdlf->getByCompanyIDAndUserIdAndCalculationIdAndPayStubEntryAccountID( $current_company->getId(), $user_obj->getId(), 200, $setup_data['tax']['include_pay_stub_entry_account'] );
|
|
if ( $setup_data['tax']['include_pay_stub_entry_account'] != 0
|
|
&& $cdlf->getRecordCount() > 0
|
|
) {
|
|
//Loop through all Tax/Deduction records to find one
|
|
foreach ( $cdlf as $cd_obj ) {
|
|
if ( $cd_obj->getStatus() == 10 && strtolower( $cd_obj->getCountry() ) == 'ca' ) {
|
|
$employment_province = $cd_obj->getProvince();
|
|
Debug::Text( ' Deduction Province of Employment: ' . $employment_province, __FILE__, __LINE__, __METHOD__, 10 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
unset( $cdlf, $cd_obj );
|
|
Debug::Text( ' Final Province of Employment: ' . $employment_province, __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
$ee_data = [
|
|
'id' => (string)TTUUID::convertStringToUUID( md5( $row['user_id'] . $t4a->year ) . microtime( true ) ),
|
|
'user_id' => (string)$row['user_id'],
|
|
'first_name' => $user_obj->getFirstName(),
|
|
'middle_name' => $user_obj->getMiddleName(),
|
|
'last_name' => $user_obj->getLastName(),
|
|
'address1' => $user_obj->getAddress1(),
|
|
'address2' => $user_obj->getAddress2(),
|
|
'city' => $user_obj->getCity(),
|
|
'province' => ( ( $user_obj->getCountry() == 'CA' || $user_obj->getCountry() == 'US' ) ? ( ( $user_obj->getProvince() != '00' ) ? $user_obj->getProvince() : null ) : 'ZZ' ),
|
|
'country' => Option::getByKey( $user_obj->getCountry(), $current_company->getOptions( 'country' ) ),
|
|
'country_code' => $user_obj->getCountry(),
|
|
'employment_province' => ( $employment_province != '00' ) ? $employment_province : null,
|
|
'postal_code' => $user_obj->getPostalCode(),
|
|
'sin' => $user_obj->getSIN(),
|
|
'employee_number' => $user_obj->getEmployeeNumber(),
|
|
|
|
//If lines with dollar amounts change, update $amount_boxes below.
|
|
'l16' => $row['pension'],
|
|
'l18' => $row['lump_sum_payment'],
|
|
'l22' => $row['income_tax'],
|
|
'l20' => $row['self_employed_commission'],
|
|
'l24' => $row['annuities'],
|
|
'l48' => $row['service_fees'],
|
|
'other_box_0_code' => null,
|
|
'other_box_0' => null,
|
|
'other_box_1_code' => null,
|
|
'other_box_1' => null,
|
|
'other_box_2_code' => null,
|
|
'other_box_2' => null,
|
|
'other_box_3_code' => null,
|
|
'other_box_3' => null,
|
|
'other_box_4_code' => null,
|
|
'other_box_4' => null,
|
|
'other_box_5_code' => null,
|
|
'other_box_5' => null,
|
|
];
|
|
|
|
//Boxes that contain dollar amounts, so we can determine if the T4a is "blank" or not. **This should exclude L22 as in theory they will always have that**
|
|
$amount_boxes = [ 'l16', 'l18', 'l20', 'l24', 'l48', 'other_box_0', 'other_box_1', 'other_box_2', 'other_box_3', 'other_box_4', 'other_box_5' ];
|
|
|
|
|
|
if ( isset( $row['other_box_0'] ) && $row['other_box_0'] > 0 && isset( $setup_data['other_box'][0]['box'] ) && $setup_data['other_box'][0]['box'] != '' ) {
|
|
$ee_data['other_box_0_code'] = $setup_data['other_box'][0]['box'];
|
|
$ee_data['other_box_0'] = $row['other_box_0'];
|
|
}
|
|
|
|
if ( isset( $row['other_box_1'] ) && $row['other_box_1'] > 0 && isset( $setup_data['other_box'][1]['box'] ) && $setup_data['other_box'][1]['box'] != '' ) {
|
|
$ee_data['other_box_1_code'] = $setup_data['other_box'][1]['box'];
|
|
$ee_data['other_box_1'] = $row['other_box_1'];
|
|
}
|
|
|
|
if ( isset( $row['other_box_2'] ) && $row['other_box_2'] > 0 && isset( $setup_data['other_box'][2]['box'] ) && $setup_data['other_box'][2]['box'] != '' ) {
|
|
$ee_data['other_box_2_code'] = $setup_data['other_box'][2]['box'];
|
|
$ee_data['other_box_2'] = $row['other_box_2'];
|
|
}
|
|
|
|
if ( isset( $row['other_box_3'] ) && $row['other_box_3'] > 0 && isset( $setup_data['other_box'][3]['box'] ) && $setup_data['other_box'][3]['box'] != '' ) {
|
|
$ee_data['other_box_3_code'] = $setup_data['other_box'][3]['box'];
|
|
$ee_data['other_box_3'] = $row['other_box_3'];
|
|
}
|
|
|
|
if ( isset( $row['other_box_4'] ) && $row['other_box_4'] > 0 && isset( $setup_data['other_box'][4]['box'] ) && $setup_data['other_box'][4]['box'] != '' ) {
|
|
$ee_data['other_box_4_code'] = $setup_data['other_box'][4]['box'];
|
|
$ee_data['other_box_4'] = $row['other_box_4'];
|
|
}
|
|
|
|
if ( isset( $row['other_box_5'] ) && $row['other_box_5'] > 0 && isset( $setup_data['other_box'][5]['box'] ) && $setup_data['other_box'][5]['box'] != '' ) {
|
|
$ee_data['other_box_5_code'] = $setup_data['other_box'][5]['box'];
|
|
$ee_data['other_box_5'] = $row['other_box_5'];
|
|
}
|
|
|
|
//Make sure there is actually data on the T4a, otherwise skip the employee.
|
|
$tmp_total_amount_boxes = 0;
|
|
foreach ( $amount_boxes as $amount_box ) {
|
|
if ( isset( $ee_data[$amount_box] ) && is_numeric( $ee_data[$amount_box] ) ) {
|
|
$tmp_total_amount_boxes += $ee_data[$amount_box];
|
|
}
|
|
}
|
|
|
|
if ( $tmp_total_amount_boxes != 0 ) {
|
|
if ( $format == 'payment_services' ) {
|
|
$report_meta_data['t4a'][] = [ 'remote_id' => $row['user_id'], 'first_name' => $user_obj->getFirstName(), 'last_name' => $user_obj->getLastName(), 'sin' => $user_obj->getSIN(), 'l22' => $ee_data['l22'] ];
|
|
}
|
|
|
|
$t4a->addRecord( $ee_data );
|
|
|
|
if ( $format == 'pdf_form_publish_employee' ) {
|
|
// generate PDF for every employee and assign to each government document records
|
|
$this->getFormObject()->addForm( $t4a );
|
|
GovernmentDocumentFactory::addDocument( $user_obj->getId(), 20, 102, TTDate::getEndYearEpoch( $filter_data['start_date'] ), ( ( $t4a->countRecords() == 1 ) ? $this->getFormObject()->output( 'PDF', false ) : null ), ( ( $t4a->countRecords() == 1 ) ? $this->getFormObject()->serialize() : null ) );
|
|
$this->getFormObject()->clearForms();
|
|
}
|
|
} else {
|
|
Debug::Text( ' No amounts on T4A skipping: ' . $user_obj->getFullName(), __FILE__, __LINE__, __METHOD__, 10 );
|
|
unset( $user_rows[$user_row_key] ); //Remove user data from array so it doesn't get added to totals or counted as an employee.
|
|
}
|
|
unset( $ee_data );
|
|
}
|
|
|
|
$this->getProgressBarObject()->set( $this->getAPIMessageID(), $x );
|
|
$x++;
|
|
}
|
|
|
|
if ( $format != 'pdf_form_publish_employee' ) {
|
|
$this->getFormObject()->addForm( $t4a );
|
|
|
|
if ( $t4a->countRecords() > 0 && ( $form_type == 'government' || $format == 'efile_xml' || $format == 'payment_services' ) ) {
|
|
//Handle T4ASummary
|
|
$t4as = $this->getT4ASumObject();
|
|
$t4as->setStatus( $setup_data['status_id'] );
|
|
$t4as->year = $t4a->year;
|
|
$t4as->payroll_account_number = $t4a->payroll_account_number;
|
|
|
|
$t4as->company_name = $legal_entity_obj->getTradeName(); //T4As show Operating/Trade name on the forms.
|
|
$t4as->company_address1 = $legal_entity_obj->getAddress1();
|
|
$t4as->company_address2 = $legal_entity_obj->getAddress2();
|
|
$t4as->company_city = $legal_entity_obj->getCity();
|
|
$t4as->company_province = $legal_entity_obj->getProvince();
|
|
$t4as->company_postal_code = $legal_entity_obj->getPostalCode();
|
|
|
|
$t4as->l76 = $contact_user_obj->getFullName(); //Contact name.
|
|
$t4as->l78 = $contact_user_obj->getWorkPhone();
|
|
|
|
$total_row = Misc::ArrayAssocSum( $this->form_data['user'][$legal_entity_id] );
|
|
|
|
$t4as->l88 = $t4a->countRecords();
|
|
$t4as->l16 = ( isset( $total_row['pension'] ) ) ? $total_row['pension'] : null;
|
|
$t4as->l22 = ( isset( $total_row['income_tax'] ) ) ? $total_row['income_tax'] : null;
|
|
$t4as->l18 = ( isset( $total_row['lump_sum_payment'] ) ) ? $total_row['lump_sum_payment'] : null;
|
|
$t4as->l20 = ( isset( $total_row['self_employed_commission'] ) ) ? $total_row['self_employed_commission'] : null;
|
|
$t4as->l24 = ( isset( $total_row['annuities'] ) ) ? $total_row['annuities'] : null;
|
|
$t4as->l48 = ( isset( $total_row['service_fees'] ) ) ? $total_row['service_fees'] : null;
|
|
|
|
if ( isset( $setup_data['other_box'] ) ) {
|
|
foreach ( $setup_data['other_box'] as $key => $other_box_data ) {
|
|
//Debug::Text('zFound other box total for T4A Sum: '. $key .' Code: '. $other_box_data['box'], __FILE__, __LINE__, __METHOD__, 10);
|
|
if ( in_array( (int)$other_box_data['box'], [ 28, 30, 32, 34, 40, 42 ] ) ) {
|
|
//Debug::Text('Found other box total for T4A Sum: '. $key .' Code: '. $other_box_data['box'], __FILE__, __LINE__, __METHOD__, 10);
|
|
$object_var = 'l' . (int)$other_box_data['box'];
|
|
$t4as->$object_var = $total_row['other_box_' . $key];
|
|
unset( $object_var );
|
|
}
|
|
}
|
|
}
|
|
unset( $other_box_data, $key );
|
|
|
|
$total_other_deductions = Misc::MoneyRound( Misc::sumMultipleColumns( $total_row, [ 'other_box_0', 'other_box_1', 'other_box_2', 'other_box_3', 'other_box_4' ] ) );
|
|
$t4as->l101 = $total_other_deductions;
|
|
|
|
if ( isset( $setup_data['remittances_paid'] ) && $setup_data['remittances_paid'] != '' ) {
|
|
$t4as->l82 = (float)$setup_data['remittances_paid'];
|
|
} else {
|
|
$t4as->l82 = $total_row['income_tax'];
|
|
}
|
|
|
|
if ( $format == 'payment_services' ) {
|
|
$report_meta_data['t4as'] = [ 'total_employees' => $t4a->countRecords(), 'l22' => $t4as->l22 ];
|
|
}
|
|
|
|
$this->getFormObject()->addForm( $t4as );
|
|
}
|
|
|
|
if ( $t4a->countRecords() > 0 ) {
|
|
if ( $format == 'efile_xml' || $format == 'payment_services' ) {
|
|
$output_format = 'XML';
|
|
$file_name = 't4a_efile_' . date( 'Y_m_d' ) . '_' . Misc::sanitizeFileName( $this->form_data['legal_entity'][$legal_entity_id]->getTradeName() ) . '.xml';
|
|
$mime_type = 'applications/octet-stream'; //Force file to download.
|
|
} else {
|
|
$output_format = 'PDF';
|
|
$file_name = 't4a_' . Misc::sanitizeFileName( $this->form_data['legal_entity'][$legal_entity_id]->getTradeName() ) . '.pdf';
|
|
$mime_type = $this->file_mime_type;
|
|
}
|
|
|
|
$file_output = $this->getFormObject()->output( $output_format );
|
|
|
|
//reset the file objects.
|
|
$this->clearFormObject();
|
|
$this->clearT4AObject();
|
|
$this->clearT619SumObject();
|
|
$this->clearT4ASumObject();
|
|
|
|
if ( !is_array( $file_output ) ) {
|
|
if ( $format == 'payment_services' ) {
|
|
$tmp_output['xml'] = $file_output;
|
|
$tmp_output['metadata'] = $report_meta_data;
|
|
$file_output = $tmp_output;
|
|
}
|
|
|
|
$file_arr[] = [ 'file_name' => $file_name, 'mime_type' => $mime_type, 'data' => $file_output ];
|
|
unset( $file_output );
|
|
} else {
|
|
return $file_output;
|
|
}
|
|
} else {
|
|
return false; //No records.
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( $format == 'pdf_form_publish_employee' ) {
|
|
$user_generic_status_batch_id = GovernmentDocumentFactory::saveUserGenericStatus( $this->getUserObject()->getId() );
|
|
return $user_generic_status_batch_id;
|
|
} else {
|
|
if ( isset( $file_name ) && $file_name != '' ) {
|
|
$zip_filename = explode( '.', $file_name );
|
|
if ( isset( $zip_filename[( count( $zip_filename ) - 1 )] ) ) {
|
|
$zip_filename = str_replace( '.', '', str_replace( $zip_filename[( count( $zip_filename ) - 1 )], '', $file_name ) ) . '.zip';
|
|
} else {
|
|
$zip_filename = str_replace( '.', '', $file_name ) . '.zip';
|
|
}
|
|
|
|
return Misc::zip( $file_arr, $zip_filename, true );
|
|
}
|
|
|
|
Debug::Text( ' Returning FALSE!', __FILE__, __LINE__, __METHOD__, 10 );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Short circuit this function, as no postprocessing is required for exporting the data.
|
|
* @param null $format
|
|
* @return bool
|
|
*/
|
|
function _postProcess( $format = null ) {
|
|
if ( ( $format == 'pdf_form' || $format == 'pdf_form_government' ) || ( $format == 'pdf_form_print' || $format == 'pdf_form_print_government' ) || $format == 'efile_xml' || $format == 'payment_services' || $format == 'pdf_form_publish_employee' ) {
|
|
Debug::Text( 'Skipping postProcess! Format: ' . $format, __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
return true;
|
|
} else {
|
|
return parent::_postProcess( $format );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param null $format
|
|
* @return array|bool
|
|
*/
|
|
function _output( $format = null ) {
|
|
if ( ( $format == 'pdf_form' || $format == 'pdf_form_government' ) || ( $format == 'pdf_form_print' || $format == 'pdf_form_print_government' ) || $format == 'efile_xml' || $format == 'payment_services' || $format == 'pdf_form_publish_employee' ) {
|
|
return $this->_outputPDFForm( $format );
|
|
} else {
|
|
return parent::_output( $format );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Formats report data for exporting to TimeTrex payment service.
|
|
* @param $prae_obj
|
|
* @param $pra_obj
|
|
* @param $rs_obj
|
|
* @param $pra_user_obj
|
|
* @return array|bool
|
|
*/
|
|
function getPaymentServicesData( $prae_obj, $pra_obj, $rs_obj, $pra_user_obj ) {
|
|
$output_data = $this->getOutput( 'payment_services' );
|
|
Debug::Arr( $output_data, 'Raw Report data!', __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
if ( $this->hasData() && isset( $output_data['data'] ) && isset( $output_data['data']['metadata']['t4as']['total_employees'] ) && $output_data['data']['metadata']['t4as']['total_employees'] > 0 ) {
|
|
$batch_id = date( 'M d', $prae_obj->getEndDate() );
|
|
|
|
$retarr = [
|
|
'object' => __CLASS__,
|
|
'user_success_message' => TTi18n::gettext( 'T4As submitted successfully' ),
|
|
|
|
'agency_report_data' => [
|
|
'type_id' => 'R', //R=Report
|
|
'total_employees' => (int)$output_data['data']['metadata']['t4as']['total_employees'],
|
|
'subject_wages' => null,
|
|
'taxable_wages' => null,
|
|
'amount_withheld' => $output_data['data']['metadata']['t4as']['l22'],
|
|
'amount_due' => 0,
|
|
'due_date' => $prae_obj->getDueDate(),
|
|
'extra_data' => $output_data['data']['metadata'],
|
|
'xml_data' => $output_data['data']['xml'],
|
|
|
|
'remote_batch_id' => $batch_id,
|
|
|
|
//Generate a consistent remote_id based on the exact time period, the remittance agency event, and batch ID.
|
|
//This helps to prevent duplicate records from be created, as well as work across separate or split up batches that may be processed.
|
|
// This needs to take into account different start/end date periods, so we don't try to overwrite records from last year.
|
|
'remote_id' => TTUUID::convertStringToUUID( md5( $prae_obj->getId() . $prae_obj->getStartDate() . $prae_obj->getEndDate() ) ),
|
|
|
|
],
|
|
];
|
|
|
|
return $retarr;
|
|
}
|
|
|
|
Debug::Text( 'No report data!', __FILE__, __LINE__, __METHOD__, 10 );
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
?>
|