title = TTi18n::getText( 'TimeSheet Summary Report' ); $this->file_name = 'timesheet_summary_report'; 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_timesheet_summary', $user_id, $company_id ) ) { return true; } return false; } /** * @return bool */ protected function _validateConfig() { $config = $this->getConfig(); //Make sure some time period is selected. if ( ( !isset( $config['filter']['time_period'] ) && !isset( $config['filter']['pay_period_id'] ) ) || ( isset( $config['filter']['time_period'] ) && isset( $config['filter']['time_period']['time_period'] ) && $config['filter']['time_period']['time_period'] == TTUUID::getZeroId() ) ) { $this->validator->isTrue( 'time_period', false, TTi18n::gettext( 'No time period defined for this report' ) ); } return true; } /** * @param $name * @param null $params * @return array|bool|mixed|null */ protected function _getOptions( $name, $params = null ) { $retval = null; switch ( $name ) { case 'output_format': $retval = parent::getOptions( 'default_output_format' ); 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' ), '-2035-user_tag' => TTi18n::gettext( 'Employee Tags' ), '-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' ), '-2080-punch_branch_id' => TTi18n::gettext( 'Punch Branch' ), '-2090-punch_department_id' => TTi18n::gettext( 'Punch Department' ), '-2000-currency_id' => TTi18n::gettext( 'Currency' ), '-2100-custom_filter' => TTi18n::gettext( 'Custom Filter' ), '-2300-punch_tag_id' => TTi18n::gettext( 'Punch Tag' ), '-4010-pay_period_time_sheet_verify_status_id' => TTi18n::gettext( 'TimeSheet Verification' ), '-4020-include_no_data_rows' => TTi18n::gettext( 'Include Blank Records' ), '-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' ), '-5040-page_break' => TTi18n::gettext( 'Page Break On' ), ]; if ( $this->getUserObject()->getCompanyObject()->getProductEdition() >= TT_PRODUCT_CORPORATE ) { $corporate_edition_setup_fields = [ '-2075-default_job_id' => TTi18n::gettext( 'Default Job' ), '-2076-default_job_item_id' => TTi18n::gettext( 'Default Task' ), '-2077-default_punch_tag_id' => TTi18n::gettext( 'Default Punch Tag' ), ]; $retval = array_merge( $retval, $corporate_edition_setup_fields ); } ksort( $retval ); break; case 'time_period': $retval = TTDate::getTimePeriodOptions(); break; case 'date_columns': $retval = TTDate::getReportDateOptions( null, TTi18n::getText( 'Date' ), 13, true ); break; case 'custom_columns': //Get custom fields for report data. $retval = $this->getCustomFieldColumns( 9000, $this->getUserObject()->getCompany(), ['branch', 'department', 'users'], ['users'] ); 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, 'TimesheetSummaryReport', '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, 'TimesheetSummaryReport', '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' ), 'TimesheetSummaryReport', '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' ), 'TimesheetSummaryReport', '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. '-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 #' ), '-1040-status' => TTi18n::gettext( 'Status' ), '-1050-title' => TTi18n::gettext( 'Title' ), '-1055-city' => TTi18n::gettext( 'City' ), '-1060-province' => TTi18n::gettext( 'Province/State' ), '-1070-country' => TTi18n::gettext( 'Country' ), '-1080-user_group' => TTi18n::gettext( 'Employee Group' ), '-1090-default_branch' => TTi18n::gettext( 'Default Branch' ), '-1091-default_branch_manual_id' => TTi18n::gettext( 'Default Branch Code' ), '-1100-default_department' => TTi18n::gettext( 'Default Department' ), '-1100-default_department_manual_id' => TTi18n::gettext( 'Default Department Code' ), '-1110-currency' => TTi18n::gettext( 'Currency' ), '-1111-current_currency' => TTi18n::gettext( 'Current Currency' ), //'-1110-verified_time_sheet' => TTi18n::gettext('Verified TimeSheet'), //'-1120-pending_request' => TTi18n::gettext('Pending Requests'), '-1400-permission_control' => TTi18n::gettext( 'Permission Group' ), '-1410-pay_period_schedule' => TTi18n::gettext( 'Pay Period Schedule' ), '-1420-policy_group' => TTi18n::gettext( 'Policy Group' ), '-1430-branch_name' => TTi18n::gettext( 'Branch' ), '-1431-branch_manual_id' => TTi18n::gettext( 'Branch Code' ), '-1440-department_name' => TTi18n::gettext( 'Department' ), '-1441-department_manual_id' => TTi18n::gettext( 'Department Code' ), //This can't be a secure SIN otherwise it doesn't make much sense putting it on here... But if its here then //supervisors can see it and it may be a security concern. //'-1480-sin' => TTi18n::gettext('SIN/SSN'), '-1490-note' => TTi18n::gettext( 'Note' ), '-1495-tag' => TTi18n::gettext( 'Tags' ), //Handled in date_columns above. //'-1450-pay_period' => TTi18n::gettext('Pay Period'), '-1510-verified_time_sheet' => TTi18n::gettext( 'Verified TimeSheet' ), '-1515-verified_time_sheet_date' => TTi18n::gettext( 'Verified TimeSheet Date' ), ]; if ( getTTProductEdition() >= TT_PRODUCT_CORPORATE ) { $retval['-1105-default_job'] = TTi18n::gettext( 'Default Job' ); $retval['-1106-default_job_manual_id'] = TTi18n::gettext( 'Default Job Code' ); $retval['-1107-default_job_item'] = TTi18n::gettext( 'Default Task' ); $retval['-1108-default_job_item_manual_id'] = TTi18n::gettext( 'Default Task Code' ); } $retval = array_merge( $retval, (array)$this->getOptions( 'date_columns' ), (array)$this->getOptions( 'report_static_custom_column' ) ); $retval = array_merge( $retval, $this->getStaticCustomFieldColumns( 9000, $this->getUserObject()->getCompany(), [ 'branch', 'department', 'users', 'user_title' ], ['users'] ) ); $retval = array_merge( $retval, $this->getStaticCustomFieldColumns( 9100, $this->getUserObject()->getCompany(), [ 'branch', 'department' ], null, [ 'branch' => [ 'name' => 'default_branch_', 'label' => TTi18n::getText( 'Default Branch' ).' ' ], 'department' => [ 'name' => 'default_department_', 'label' => TTi18n::getText( 'Default Department' ) .' ' ] ] ) ); //Add in Default Branch/Department custom fields as well. ksort( $retval ); break; case 'dynamic_columns': $retval = [ //Dynamic - Aggregate functions can be used '-2070-schedule_working' => TTi18n::gettext( 'Scheduled Time' ), '-2072-schedule_working_diff' => TTi18n::gettext( 'Scheduled Time Diff.' ), '-2080-schedule_absence' => TTi18n::gettext( 'Scheduled Absence' ), '-2085-worked_days' => TTi18n::gettext( 'Worked Days' ), '-3000-worked_time' => TTi18n::gettext( 'Total Worked Time' ), '-3010-regular_time' => TTi18n::gettext( 'Total Regular Time' ), '-3015-overtime_time' => TTi18n::gettext( 'Total OverTime' ), '-3020-absence_time' => TTi18n::gettext( 'Total Absence Time' ), '-3022-absence_taken_time' => TTi18n::gettext( 'Total Absence Time (Taken)' ), '-3025-premium_time' => TTi18n::gettext( 'Total Premium Time' ), '-3030-gross_time' => TTi18n::gettext( 'Total Paid Time' ), //'-3030-actual_time' => TTi18n::gettext('Total Actual Time'), //'-3035-actual_time_diff' => TTi18n::gettext('Actual Time Difference'), '-3090-lunch_time' => TTi18n::gettext( 'Lunch Time (Taken)' ), '-3091-break_time' => TTi18n::gettext( 'Break Time (Taken)' ), '-3210-regular_wage' => TTi18n::gettext( 'Total Regular Time Wage' ), '-3215-overtime_wage' => TTi18n::gettext( 'Total OverTime Wage' ), '-3220-absence_wage' => TTi18n::gettext( 'Total Absence Time Wage' ), '-3225-premium_wage' => TTi18n::gettext( 'Total Premium Time Wage' ), '-3200-gross_wage' => TTi18n::gettext( 'Gross Wage' ), '-3400-gross_wage_with_burden' => TTi18n::gettext( 'Gross Wage w/Burden' ), //'-3390-gross_hourly_rate' => TTi18n::gettext('Gross Hourly Rate'), ]; $retval = array_merge( $retval, $this->getOptions( 'paycode_columns' ), $this->getDynamicCustomFieldColumns( 9000, $this->getUserObject()->getCompany(), ['branch', 'department', 'users'], ['users'] ) ); ksort( $retval ); break; case 'paycode_columns': $retval = parent::__getOptions( $name, 3 ); 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 ) { if ( strpos( $column, '_wage' ) !== false || strpos( $column, '_hourly_rate' ) !== false ) { $retval[$column] = 'currency'; } else if ( strpos( $column, '_time' ) || strpos( $column, 'schedule_' ) ) { $retval[$column] = 'time_unit'; } } } $retval['verified_time_sheet_date'] = 'time_stamp'; 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: if ( strpos( $column, '_hourly_rate' ) !== false ) { $retval[$column] = 'avg'; } else { $retval[$column] = 'sum'; } } } } $retval['verified_time_sheet'] = 'first'; $retval['verified_time_sheet_date'] = 'first'; $retval['worked_days'] = 'numeric'; break; case 'templates': $retval = [ '-1050-by_employee+all_time' => TTi18n::gettext( 'Total Time by Employee' ), '-1150-by_date_by_full_name+all_time' => TTi18n::gettext( 'Total Time by Date/Employee' ), '-1200-by_full_name_by_date+all_time' => TTi18n::gettext( 'Total Time by Employee/Date' ), '-1250-by_branch+regular+all_time' => TTi18n::gettext( 'Total Time by Branch' ), '-1300-by_department+all_time' => TTi18n::gettext( 'Total Time by Department' ), '-1350-by_branch_by_department+all_time' => TTi18n::gettext( 'Total Time by Branch/Department' ), '-1400-by_pay_period+all_time' => TTi18n::gettext( 'Total Time by Pay Period' ), '-1450-by_pay_period_by_employee+all_time' => TTi18n::gettext( 'Total Time by Pay Period/Employee' ), '-1500-by_pay_period_by_branch+all_time' => TTi18n::gettext( 'Total Time by Pay Period/Branch' ), '-1550-by_pay_period_by_department+all_time' => TTi18n::gettext( 'Total Time by Pay Period/Department' ), '-1600-by_pay_period_by_branch_by_department+all_time' => TTi18n::gettext( 'Total Time by Pay Period/Branch/Department' ), '-1650-by_employee_by_pay_period+all_time' => TTi18n::gettext( 'Total Time by Employee/Pay Period' ), '-1700-by_branch_by_pay_period+all_time' => TTi18n::gettext( 'Total Time by Pay Branch/Pay Period' ), '-1850-by_department_by_pay_period+all_time' => TTi18n::gettext( 'Total Time by Pay Department/Pay Period' ), '-1900-by_branch_by_department_by_pay_period+all_time' => TTi18n::gettext( 'Total Time by Branch/Department/Pay Period' ), '-2100-by_employee+regular+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Employee' ), '-2150-by_date_by_full_name+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Date/Employee' ), '-2200-by_full_name_by_date+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Employee/Date' ), '-2250-by_branch+regular+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Branch' ), '-2300-by_department+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Department' ), '-2350-by_branch_by_department+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Branch/Department' ), '-2400-by_pay_period+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Pay Period' ), '-2450-by_pay_period_by_employee+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Pay Period/Employee' ), '-2500-by_pay_period_by_branch+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Pay Period/Branch' ), '-2550-by_pay_period_by_department+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Pay Period/Department' ), '-2600-by_pay_period_by_branch_by_department+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Pay Period/Branch/Department' ), '-2650-by_employee_by_pay_period+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Employee/Pay Period' ), '-2700-by_branch_by_pay_period+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Pay Branch/Pay Period' ), '-2850-by_department_by_pay_period+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Pay Department/Pay Period' ), '-2900-by_branch_by_department_by_pay_period+all_time+all_wage' => TTi18n::gettext( 'Total Time+Wage by Branch/Department/Pay Period' ), '-3000-by_pay_period_by_employee+verified_time_sheet' => TTi18n::gettext( 'Timesheet Verification by Pay Period/Employee' ), '-3010-by_verified_time_sheet_by_pay_period_by_employee+verified_time_sheet' => TTi18n::gettext( 'Timesheet Verification by Verification/Pay Period/Employee' ), ]; break; case 'template_config': $template = strtolower( Misc::trimSortPrefix( $params['template'] ) ); if ( isset( $template ) && $template != '' ) { switch ( $template ) { case 'by_pay_period_by_employee+verified_time_sheet': $retval['-1010-time_period']['time_period'] = 'last_pay_period'; $retval['columns'][] = 'pay_period'; $retval['columns'][] = 'first_name'; $retval['columns'][] = 'last_name'; $retval['columns'][] = 'verified_time_sheet'; $retval['columns'][] = 'verified_time_sheet_date'; $retval['group'][] = 'pay_period'; $retval['group'][] = 'first_name'; $retval['group'][] = 'last_name'; $retval['sort'][] = [ 'pay_period' => 'asc' ]; $retval['sort'][] = [ 'verified_time_sheet' => 'desc' ]; $retval['sort'][] = [ 'verified_time_sheet_date' => 'asc' ]; break; case 'by_verified_time_sheet_by_pay_period_by_employee+verified_time_sheet': $retval['-1010-time_period']['time_period'] = 'last_pay_period'; $retval['columns'][] = 'verified_time_sheet'; $retval['columns'][] = 'pay_period'; $retval['columns'][] = 'first_name'; $retval['columns'][] = 'last_name'; $retval['columns'][] = 'verified_time_sheet_date'; $retval['group'][] = 'verified_time_sheet'; $retval['group'][] = 'pay_period'; $retval['group'][] = 'first_name'; $retval['group'][] = 'last_name'; $retval['sort'][] = [ 'verified_time_sheet' => 'desc' ]; $retval['sort'][] = [ 'pay_period' => 'asc' ]; $retval['sort'][] = [ 'verified_time_sheet_date' => 'asc' ]; break; default: Debug::Text( ' Parsing template name: ' . $template, __FILE__, __LINE__, __METHOD__, 10 ); $retval['-1010-time_period']['time_period'] = 'last_pay_period'; //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 case 'all_time': $retval['columns'][] = 'worked_time'; $retval['columns'][] = 'regular_time'; $retval['columns'][] = 'overtime_time'; $retval['columns'][] = 'absence_time'; $retval['columns'][] = 'premium_time'; break; case 'all_wage': $retval['columns'][] = 'gross_wage'; $retval['columns'][] = 'regular_wage'; $retval['columns'][] = 'overtime_wage'; $retval['columns'][] = 'absence_wage'; $retval['columns'][] = 'premium_wage'; break; //Filter //Group By //SubTotal //Sort 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'][] = 'branch_name'; $retval['group'][] = 'branch_name'; $retval['sort'][] = [ 'branch_name' => 'asc' ]; break; case 'by_department': $retval['columns'][] = 'department_name'; $retval['group'][] = 'department_name'; $retval['sort'][] = [ 'department_name' => 'asc' ]; break; case 'by_branch_by_department': $retval['columns'][] = 'branch_name'; $retval['columns'][] = 'department_name'; $retval['group'][] = 'branch_name'; $retval['group'][] = 'department_name'; $retval['sub_total'][] = 'branch_name'; $retval['sort'][] = [ 'branch_name' => 'asc' ]; $retval['sort'][] = [ 'department_name' => 'asc' ]; break; case 'by_pay_period': $retval['columns'][] = 'pay_period'; $retval['group'][] = 'pay_period'; $retval['sort'][] = [ 'pay_period' => 'asc' ]; break; case 'by_pay_period_by_employee': $retval['columns'][] = 'pay_period'; $retval['columns'][] = 'first_name'; $retval['columns'][] = 'last_name'; $retval['group'][] = 'pay_period'; $retval['group'][] = 'first_name'; $retval['group'][] = 'last_name'; $retval['sub_total'][] = 'pay_period'; $retval['sort'][] = [ 'pay_period' => 'asc' ]; $retval['sort'][] = [ 'last_name' => 'asc' ]; $retval['sort'][] = [ 'first_name' => 'asc' ]; break; case 'by_pay_period_by_branch': $retval['columns'][] = 'pay_period'; $retval['columns'][] = 'branch_name'; $retval['group'][] = 'pay_period'; $retval['group'][] = 'branch_name'; $retval['sub_total'][] = 'pay_period'; $retval['sort'][] = [ 'pay_period' => 'asc' ]; $retval['sort'][] = [ 'branch_name' => 'asc' ]; break; case 'by_pay_period_by_department': $retval['columns'][] = 'pay_period'; $retval['columns'][] = 'department_name'; $retval['group'][] = 'pay_period'; $retval['group'][] = 'department_name'; $retval['sub_total'][] = 'pay_period'; $retval['sort'][] = [ 'pay_period' => 'asc' ]; $retval['sort'][] = [ 'department_name' => 'asc' ]; break; case 'by_pay_period_by_branch_by_department': $retval['columns'][] = 'pay_period'; $retval['columns'][] = 'branch_name'; $retval['columns'][] = 'department_name'; $retval['group'][] = 'pay_period'; $retval['group'][] = 'branch_name'; $retval['group'][] = 'department_name'; $retval['sub_total'][] = 'pay_period'; $retval['sub_total'][] = 'branch_name'; $retval['sort'][] = [ 'pay_period' => 'asc' ]; $retval['sort'][] = [ 'branch_name' => 'asc' ]; $retval['sort'][] = [ 'department_name' => 'asc' ]; break; case 'by_employee_by_pay_period': $retval['columns'][] = 'full_name'; $retval['columns'][] = 'pay_period'; $retval['group'][] = 'full_name'; $retval['group'][] = 'pay_period'; $retval['sub_total'][] = 'full_name'; $retval['sort'][] = [ 'full_name' => 'asc' ]; $retval['sort'][] = [ 'pay_period' => 'asc' ]; break; case 'by_branch_by_pay_period': $retval['columns'][] = 'branch_name'; $retval['columns'][] = 'pay_period'; $retval['group'][] = 'branch_name'; $retval['group'][] = 'pay_period'; $retval['sub_total'][] = 'branch_name'; $retval['sort'][] = [ 'branch_name' => 'asc' ]; $retval['sort'][] = [ 'pay_period' => 'asc' ]; break; case 'by_department_by_pay_period': $retval['columns'][] = 'department_name'; $retval['columns'][] = 'pay_period'; $retval['group'][] = 'department_name'; $retval['group'][] = 'pay_period'; $retval['sub_total'][] = 'department_name'; $retval['sort'][] = [ 'department_name' => 'asc' ]; $retval['sort'][] = [ 'pay_period' => 'asc' ]; break; case 'by_branch_by_department_by_pay_period': $retval['columns'][] = 'branch_name'; $retval['columns'][] = 'department_name'; $retval['columns'][] = 'pay_period'; $retval['group'][] = 'branch_name'; $retval['group'][] = 'department_name'; $retval['group'][] = 'pay_period'; $retval['sub_total'][] = 'branch_name'; $retval['sub_total'][] = 'department_name'; $retval['sort'][] = [ 'branch_name' => 'asc' ]; $retval['sort'][] = [ 'department_name' => 'asc' ]; $retval['sort'][] = [ 'pay_period' => 'asc' ]; break; case 'by_date_by_full_name': $retval['columns'][] = 'date_stamp'; $retval['columns'][] = 'full_name'; $retval['group'][] = 'date_stamp'; $retval['group'][] = 'full_name'; $retval['sub_total'][] = 'date_stamp'; $retval['sort'][] = [ 'date_stamp' => 'asc' ]; $retval['sort'][] = [ 'full_name' => 'asc' ]; break; case 'by_full_name_by_date': $retval['columns'][] = 'full_name'; $retval['columns'][] = 'date_stamp'; $retval['group'][] = 'full_name'; $retval['group'][] = 'date_stamp'; $retval['sub_total'][] = 'full_name'; $retval['sort'][] = [ 'full_name' => 'asc' ]; $retval['sort'][] = [ 'date_stamp' => 'asc' ]; break; } } } 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; } /** * //Get raw data for report * @param null $format * @return bool */ function _getData( $format = null ) { $this->tmp_data = [ 'user_date_total' => [], 'schedule' => [], 'worked_days' => [], 'user' => [], 'user_title' => [], 'default_branch' => [], 'default_department' => [], 'branch' => [], 'department' => [], 'verified_timesheet' => [] ]; $columns = $this->getColumnDataConfig(); $filter_data = $this->getFilterConfig(); $currency_convert_to_base = $this->getCurrencyConvertToBase(); $base_currency_obj = $this->getBaseCurrencyObject(); $this->handleReportCurrency( $currency_convert_to_base, $base_currency_obj, $filter_data ); $currency_options = $this->getOptions( 'currency' ); $filter_data['permission_children_ids'] = $this->getPermissionObject()->getPermissionChildren( 'punch', 'view', $this->getUserObject()->getID(), $this->getUserObject()->getCompany() ); $wage_permission_children_ids = $this->getPermissionObject()->getPermissionChildren( 'wage', 'view', $this->getUserObject()->getID(), $this->getUserObject()->getCompany() ); $pay_period_ids = []; $udtlf = TTnew( 'UserDateTotalListFactory' ); /** @var UserDateTotalListFactory $udtlf */ $udtlf->getTimesheetSummaryReportByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), $filter_data ); Debug::Text( ' Total Rows: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10 ); $this->getProgressBarObject()->start( $this->getAPIMessageID(), $udtlf->getRecordCount(), null, TTi18n::getText( 'Retrieving Data...' ) ); $include_no_data_rows_arr = []; if ( $udtlf->getRecordCount() > 0 ) { foreach ( $udtlf as $key => $udt_obj ) { $pay_period_ids[$udt_obj->getColumn( 'pay_period_id' )] = true; $user_id = $udt_obj->getColumn( 'user_id' ); $date_stamp = TTDate::strtotime( $udt_obj->getColumn( 'date_stamp' ) ); $branch_id = $udt_obj->getColumn( 'branch_id' ); $department_id = $udt_obj->getColumn( 'department_id' ); $currency_rate = $udt_obj->getColumn( 'currency_rate' ); $currency_id = $udt_obj->getColumn( 'currency_id' ); //With pay codes, paid time makes sense now and is associated with branch/departments too. $time_columns = $udt_obj->getTimeCategory( false, $columns ); //Exclude 'total' as its not used in reports anyways, and causes problems when grouping by branch/default branch. //Debug::Text('Column: '. $columns .' Total Time: '. $udt_obj->getColumn('total_time') .' Amount: '. $udt_obj->getColumn('total_time_amount') .' Object Type ID: '. $udt_obj->getColumn('object_type_id') .' Rate: '. $udt_obj->getColumn( 'hourly_rate' ), __FILE__, __LINE__, __METHOD__, 10); if ( ( isset( $filter_data['include_no_data_rows'] ) && $filter_data['include_no_data_rows'] == 1 ) || ( $date_stamp != '' && count( $time_columns ) > 0 && $udt_obj->getColumn( 'total_time' ) != 0 ) ) { $enable_wages = $this->getPermissionObject()->isPermissionChild( $user_id, $wage_permission_children_ids ); //Split time by user, date, branch, department as that is the lowest level we can split time. //We always need to split time as much as possible as it can always be combined together by grouping. //Unless we never add columns together that would ever span a single row is of course if ( !isset( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id] ) ) { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id] = [ //Use branch_id/department_id instead of names as we need to get additional branch/department information like manual_id/other_id fields below 'branch_id' => $udt_obj->getColumn( 'branch_id' ), 'department_id' => $udt_obj->getColumn( 'department_id' ), 'pay_period_start_date' => strtotime( $udt_obj->getColumn( 'pay_period_start_date' ) ), 'pay_period_end_date' => strtotime( $udt_obj->getColumn( 'pay_period_end_date' ) ), 'pay_period_transaction_date' => strtotime( $udt_obj->getColumn( 'pay_period_transaction_date' ) ), 'pay_period' => strtotime( $udt_obj->getColumn( 'pay_period_transaction_date' ) ), 'pay_period_id' => $udt_obj->getColumn( 'pay_period_id' ), ]; if ( !isset( $include_no_data_rows_arr[$udt_obj->getColumn( 'pay_period_id' )][$date_stamp] ) ) { $include_no_data_rows_arr[$udt_obj->getColumn( 'pay_period_id' )][$date_stamp] = [ 'branch_id' => TTUUID::getZeroID(), 'department_id' => TTUUID::getZeroID(), 'pay_period_start_date' => strtotime( $udt_obj->getColumn( 'pay_period_start_date' ) ), 'pay_period_end_date' => strtotime( $udt_obj->getColumn( 'pay_period_end_date' ) ), 'pay_period_transaction_date' => strtotime( $udt_obj->getColumn( 'pay_period_transaction_date' ) ), 'pay_period' => strtotime( $udt_obj->getColumn( 'pay_period_transaction_date' ) ), 'pay_period_id' => $udt_obj->getColumn( 'pay_period_id' ), ]; } } if ( TTUUID::isUUID( $udt_obj->getPayCode() ) && $udt_obj->getPayCode() != TTUUID::getZeroID() && $udt_obj->getPayCode() != TTUUID::getNotExistID() ) { //Make sure we don't set the currency based on worked_time that will always be currency_id=0 and have no pay_code_id associated. $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id]['currency_rate'] = $currency_rate; $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id]['currency'] = $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id]['current_currency'] = Option::getByKey( $currency_id, $currency_options ); if ( $currency_convert_to_base == true && is_object( $base_currency_obj ) ) { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id]['current_currency'] = Option::getByKey( $base_currency_obj->getId(), $currency_options ); } } foreach ( $time_columns as $column ) { //Debug::Text('bColumn: '. $column .' Total Time: '. $udt_obj->getColumn('total_time') .' Object Type ID: '. $udt_obj->getColumn('object_type_id') .' Rate: '. $udt_obj->getColumn( 'hourly_rate' ), __FILE__, __LINE__, __METHOD__, 10); if ( isset( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_time'] ) ) { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_time'] = bcadd( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_time'], $udt_obj->getColumn( 'total_time' ) ); } else { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_time'] = $udt_obj->getColumn( 'total_time' ); } //Gross wage (paid_wage) calculation must go here otherwise it gets doubled up. //Worked Time is required for printable TimeSheets. Therefore this report is handled differently from TimeSheetSummary. if ( $enable_wages == true && !in_array( $column, [ 'total', 'worked' ] ) && ( $udt_obj->getColumn( 'total_time_amount' ) != 0 || $udt_obj->getColumn( 'total_time_amount_with_burden' ) != 0 ) ) { //Exclude worked time from gross wage total. if ( isset( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage'] ) ) { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage'] = bcadd( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage'], $udt_obj->getColumn( 'total_time_amount' ) ); $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage_with_burden'] = bcadd( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage_with_burden'], $udt_obj->getColumn( 'total_time_amount_with_burden' ) ); } else { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage'] = $udt_obj->getColumn( 'total_time_amount' ); $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage_with_burden'] = $udt_obj->getColumn( 'total_time_amount_with_burden' ); } if ( isset( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_hourly_rate'] ) && $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage'] != 0 && $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_time'] != 0 ) { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_hourly_rate'] = bcdiv( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage'], TTDate::getHours( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_time'] ) ); $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_hourly_rate_with_burden'] = bcdiv( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_wage_with_burden'], TTDate::getHours( $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_time'] ) ); } else { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_hourly_rate'] = $udt_obj->getColumn( 'hourly_rate' ); $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id][$column . '_hourly_rate_with_burden'] = $udt_obj->getColumn( 'hourly_rate_with_burden' ); } } //Worked Days is tricky, since if they worked in multiple branches/departments in a single day, is that considered one worked day? //How do they find out how many days they worked in each branch/department though? It would add up to more days than they actually worked. //If we did some sort of partial day though, then due to rounding it could be thrown off, but either way it woulnd't be that helpful because //it would show they worked .33 of a day in one branch if they filtered by that branch. if ( $column == 'worked' && $udt_obj->getColumn( 'total_time' ) > 0 && !isset( $this->tmp_data['worked_days'][$user_id . $date_stamp] ) ) { $this->tmp_data['user_date_total'][$user_id][$date_stamp][$branch_id][$department_id]['worked_days'] = 1; $this->tmp_data['worked_days'][$user_id . $date_stamp] = true; } } } $this->getProgressBarObject()->set( $this->getAPIMessageID(), $key ); } } //Debug::Arr($this->tmp_data['user_date_total'], 'User Date Total Raw Data: ', __FILE__, __LINE__, __METHOD__, 10); if ( isset( $columns['schedule_working'] ) || isset( $columns['schedule_working_diff'] ) || isset( $columns['schedule_absence'] ) ) { $slf = TTnew( 'ScheduleListFactory' ); /** @var ScheduleListFactory $slf */ //$slf->getDayReportByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), $filter_data ); //$slf->getScheduleSummaryReportByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), $filter_data ); $slf->getSearchByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), $filter_data ); if ( $slf->getRecordCount() > 0 ) { foreach ( $slf as $s_obj ) { $status = strtolower( Option::getByKey( $s_obj->getColumn( 'status_id' ), $s_obj->getOptions( 'status' ) ) ); //Check if the user worked on any of the scheduled days, if not insert a dummy day so the scheduled time at least appears still. if ( !isset( $this->tmp_data['user_date_total'][TTUUID::castUUID( $s_obj->getUser() )][TTDate::strtotime( $s_obj->getColumn( 'date_stamp' ) )][$s_obj->getColumn( 'branch_id' )][$s_obj->getColumn( 'department_id' )] ) ) { $this->tmp_data['user_date_total'][TTUUID::castUUID( $s_obj->getUser() )][TTDate::strtotime( $s_obj->getColumn( 'date_stamp' ) )][$s_obj->getColumn( 'branch_id' )][$s_obj->getColumn( 'department_id' )] = [ 'branch_id' => $s_obj->getColumn( 'branch_id' ), 'department_id' => $s_obj->getColumn( 'department_id' ), 'pay_period_start_date' => strtotime( $s_obj->getColumn( 'pay_period_start_date' ) ), 'pay_period_end_date' => strtotime( $s_obj->getColumn( 'pay_period_end_date' ) ), 'pay_period_transaction_date' => strtotime( $s_obj->getColumn( 'pay_period_transaction_date' ) ), 'pay_period' => strtotime( $s_obj->getColumn( 'pay_period_transaction_date' ) ), 'pay_period_id' => $s_obj->getColumn( 'pay_period_id' ), ]; } //Make sure we handle multiple schedules on the same day. if ( isset( $this->tmp_data['schedule'][TTUUID::castUUID( $s_obj->getUser() )][TTDate::strtotime( $s_obj->getColumn( 'date_stamp' ) )][$s_obj->getColumn( 'branch_id' )][$s_obj->getColumn( 'department_id' )]['schedule_' . $status] ) ) { $this->tmp_data['schedule'][TTUUID::castUUID( $s_obj->getUser() )][TTDate::strtotime( $s_obj->getColumn( 'date_stamp' ) )][$s_obj->getColumn( 'branch_id' )][$s_obj->getColumn( 'department_id' )]['schedule_' . $status] = bcadd( $this->tmp_data['schedule'][TTUUID::castUUID( $s_obj->getUser() )][TTDate::strtotime( $s_obj->getColumn( 'date_stamp' ) )][$s_obj->getColumn( 'branch_id' )][$s_obj->getColumn( 'department_id' )]['schedule_' . $status], $s_obj->getColumn( 'total_time' ) ); } else { $this->tmp_data['schedule'][TTUUID::castUUID( $s_obj->getUser() )][TTDate::strtotime( $s_obj->getColumn( 'date_stamp' ) )][$s_obj->getColumn( 'branch_id' )][$s_obj->getColumn( 'department_id' )]['schedule_' . $status] = $s_obj->getColumn( 'total_time' ); } } } //Debug::Arr($this->tmp_data['schedule'], 'Schedule Raw Data: ', __FILE__, __LINE__, __METHOD__, 10); unset( $slf, $s_obj, $status ); } //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( array_merge( (array)$this->getColumnDataConfig(), [ 'title_id' => true, 'default_branch_id' => true, 'default_department_id' => true ] ) ); if ( $currency_convert_to_base == true && is_object( $base_currency_obj ) ) { $this->tmp_data['user'][$u_obj->getId()]['current_currency'] = Option::getByKey( $base_currency_obj->getId(), $currency_options ); $this->tmp_data['user'][$u_obj->getId()]['currency_rate'] = $u_obj->getColumn( 'currency_rate' ); } else { $this->tmp_data['user'][$u_obj->getId()]['current_currency'] = $u_obj->getColumn( 'currency' ); } //User doesn't have any UDT rows, add a blank one. if ( ( isset( $filter_data['include_no_data_rows'] ) && $filter_data['include_no_data_rows'] == 1 && !isset( $this->tmp_data['user_date_total'][$u_obj->getId()] ) ) ) { foreach ( $include_no_data_rows_arr as $tmp_pay_period_id => $tmp_date_stamps ) { foreach ( $tmp_date_stamps as $tmp_date_stamp => $tmp_pay_period_data ) { $this->tmp_data['user_date_total'][$u_obj->getId()][$tmp_date_stamp][0][0] = $tmp_pay_period_data; } } unset( $tmp_pay_period_id, $tmp_date_stamps, $tmp_date_stamp, $tmp_pay_period_data ); } $this->getProgressBarObject()->set( $this->getAPIMessageID(), $key ); } unset( $include_no_data_rows_arr ); $utlf = TTnew( 'UserTitleListFactory' ); /** @var UserTitleListFactory $utlf */ $utlf->getAPISearchByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), [] ); //Dont send filter data as permission_children_ids intended for users corrupts the filter Debug::Text( ' User Title Total Rows: ' . $utlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10 ); $user_title_column_config = array_merge( (array)Misc::removeKeyPrefix( 'user_title_', (array)$this->getColumnDataConfig() ), [ 'id' => true, 'name' => true, 'custom_field' => true ] ); //Always include title_id column so we can merge title data. $this->getProgressBarObject()->start( $this->getAPIMessageID(), $utlf->getRecordCount(), null, TTi18n::getText( 'Retrieving Titles...' ) ); foreach ( $utlf as $key => $ut_obj ) { $this->tmp_data['user_title'][$ut_obj->getId()] = Misc::addKeyPrefix( 'user_title_', (array)$ut_obj->getObjectAsArray( $user_title_column_config ) ); $this->getProgressBarObject()->set( $this->getAPIMessageID(), $key ); } //Debug::Arr($this->tmp_data['user'], 'User Raw Data: ', __FILE__, __LINE__, __METHOD__, 10); $blf = TTnew( 'BranchListFactory' ); /** @var BranchListFactory $blf */ $blf->getAPISearchByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), [] ); //Dont send filter data as permission_children_ids intended for users corrupts the filter Debug::Text( ' Branch Total Rows: ' . $blf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10 ); $this->getProgressBarObject()->start( $this->getAPIMessageID(), $blf->getRecordCount(), null, TTi18n::getText( 'Retrieving Data...' ) ); foreach ( $blf as $key => $b_obj ) { $this->tmp_data['default_branch'][$b_obj->getId()] = Misc::addKeyPrefix( 'default_branch_', (array)$b_obj->getObjectAsArray( [ 'id' => true, 'name' => true, 'manual_id' => true, 'custom_field' => true ] ) ); $this->tmp_data['branch'][$b_obj->getId()] = Misc::addKeyPrefix( 'branch_', (array)$b_obj->getObjectAsArray( [ 'id' => true, 'name' => true, 'manual_id' => true, 'custom_field' => true ] ) ); $this->getProgressBarObject()->set( $this->getAPIMessageID(), $key ); } //Debug::Arr($this->tmp_data['default_branch'], 'Default Branch Raw Data: ', __FILE__, __LINE__, __METHOD__, 10); $dlf = TTnew( 'DepartmentListFactory' ); /** @var DepartmentListFactory $dlf */ $dlf->getAPISearchByCompanyIdAndArrayCriteria( $this->getUserObject()->getCompany(), [] ); //Dont send filter data as permission_children_ids intended for users corrupts the filter Debug::Text( ' Department Total Rows: ' . $dlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10 ); $this->getProgressBarObject()->start( $this->getAPIMessageID(), $dlf->getRecordCount(), null, TTi18n::getText( 'Retrieving Data...' ) ); foreach ( $dlf as $key => $d_obj ) { $this->tmp_data['default_department'][$d_obj->getId()] = Misc::addKeyPrefix( 'default_department_', (array)$d_obj->getObjectAsArray( [ 'id' => true, 'name' => true, 'manual_id' => true, 'custom_field' => true ] ) ); $this->tmp_data['department'][$d_obj->getId()] = Misc::addKeyPrefix( 'department_', (array)$d_obj->getObjectAsArray( [ 'id' => true, 'name' => true, 'manual_id' => true, 'custom_field' => true ] ) ); $this->getProgressBarObject()->set( $this->getAPIMessageID(), $key ); } //Debug::Arr($this->tmp_data['default_department'], 'Default Department Raw Data: ', __FILE__, __LINE__, __METHOD__, 10); //Debug::Arr($this->tmp_data['department'], 'Department Raw Data: ', __FILE__, __LINE__, __METHOD__, 10); //Get verified timesheets for all pay periods considered in report. $pay_period_ids = array_keys( $pay_period_ids ); if ( isset( $pay_period_ids ) && count( $pay_period_ids ) > 0 ) { $pptsvlf = TTnew( 'PayPeriodTimeSheetVerifyListFactory' ); /** @var PayPeriodTimeSheetVerifyListFactory $pptsvlf */ $pptsvlf->getByPayPeriodIdAndCompanyId( $pay_period_ids, $this->getUserObject()->getCompany() ); if ( $pptsvlf->getRecordCount() > 0 ) { foreach ( $pptsvlf as $pptsv_obj ) { $this->tmp_data['verified_timesheet'][$pptsv_obj->getUser()][$pptsv_obj->getPayPeriod()] = [ 'status' => $pptsv_obj->getVerificationStatusShortDisplay(), 'created_date' => $pptsv_obj->getCreatedDate(), ]; } } } //Debug::Arr($this->tmp_data, 'TMP Data: ', __FILE__, __LINE__, __METHOD__, 10); return true; } /** * PreProcess data such as calculating additional columns from raw data etc... * @return bool */ function _preProcess() { $this->getProgressBarObject()->start( $this->getAPIMessageID(), count( $this->tmp_data['user_date_total'] ), null, TTi18n::getText( 'Pre-Processing Data...' ) ); //Merge time data with user data $key = 0; if ( isset( $this->tmp_data['user_date_total'] ) ) { $pptsvf = TTnew('PayPeriodTimeSheetVerifyFactory'); $column_keys = array_keys( (array)$this->getColumnDataConfig() ); foreach ( $this->tmp_data['user_date_total'] as $user_id => $level_1 ) { if ( isset( $this->tmp_data['user'][$user_id] ) ) { foreach ( $level_1 as $date_stamp => $level_2 ) { foreach ( $level_2 as $branch => $level_3 ) { foreach ( $level_3 as $department => $row ) { $date_columns = TTDate::getReportDates( null, $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'] ], $column_keys ); $processed_data = []; if ( isset( $this->tmp_data['verified_timesheet'][$user_id][$row['pay_period_id']] ) ) { $processed_data['verified_time_sheet'] = $this->tmp_data['verified_timesheet'][$user_id][$row['pay_period_id']]['status']; $processed_data['verified_time_sheet_date'] = $this->tmp_data['verified_timesheet'][$user_id][$row['pay_period_id']]['created_date']; } else { $processed_data['verified_time_sheet'] = $pptsvf->getVerificationStatusShortDisplay( null, $row['pay_period_id'] ); $processed_data['verified_time_sheet_date'] = false; } if ( !isset( $row['worked_time'] ) ) { $row['worked_time'] = 0; } if ( isset( $this->tmp_data['schedule'][$user_id][$date_stamp][$branch][$department]['schedule_working'] ) ) { $processed_data['schedule_working'] = $this->tmp_data['schedule'][$user_id][$date_stamp][$branch][$department]['schedule_working']; $processed_data['schedule_working_diff'] = ( $row['worked_time'] - $this->tmp_data['schedule'][$user_id][$date_stamp][$branch][$department]['schedule_working'] ); //We can only include scheduled_time once per user/date combination. Otherwise its duplicates the amounts and makes it incorrect. //So once its used unset it so it can't be used again. unset( $this->tmp_data['schedule'][$user_id][$date_stamp][$branch][$department]['schedule_working'] ); } else { $processed_data['schedule_working'] = 0; $processed_data['schedule_working_diff'] = $row['worked_time']; } if ( isset( $this->tmp_data['schedule'][$user_id][$date_stamp][$branch][$department]['schedule_absent'] ) ) { $processed_data['schedule_absent'] = $this->tmp_data['schedule'][$user_id][$date_stamp][$branch][$department]['schedule_absent']; unset( $this->tmp_data['schedule'][$user_id][$date_stamp][$branch][$department]['schedule_absent'] ); } else { $processed_data['schedule_absent'] = 0; } if ( isset( $this->tmp_data['user'][$user_id]['default_branch_id'] ) && isset( $this->tmp_data['default_branch'][$this->tmp_data['user'][$user_id]['default_branch_id']] ) ) { $tmp_default_branch = $this->tmp_data['default_branch'][$this->tmp_data['user'][$user_id]['default_branch_id']]; } else { $tmp_default_branch = []; } if ( isset( $this->tmp_data['user'][$user_id]['default_department_id'] ) && isset( $this->tmp_data['default_department'][$this->tmp_data['user'][$user_id]['default_department_id']] ) ) { $tmp_default_department = $this->tmp_data['default_department'][$this->tmp_data['user'][$user_id]['default_department_id']]; } else { $tmp_default_department = []; } if ( isset( $this->tmp_data['user'][$user_id]['title_id'] ) && isset( $this->tmp_data['user_title'][$this->tmp_data['user'][$user_id]['title_id']] ) ) { $tmp_user_title = $this->tmp_data['user_title'][$this->tmp_data['user'][$user_id]['title_id']]; } else { $tmp_user_title = []; } if ( isset( $this->tmp_data['branch'][$row['branch_id']] ) ) { $tmp_branch = $this->tmp_data['branch'][$row['branch_id']]; } else { $tmp_branch = []; } if ( isset( $this->tmp_data['department'][$row['department_id']] ) ) { $tmp_department = $this->tmp_data['department'][$row['department_id']]; } else { $tmp_department = []; } $this->data[] = array_merge( $this->tmp_data['user'][$user_id], $tmp_default_branch, $tmp_default_department, $tmp_branch, $tmp_department, $tmp_user_title, $row, $date_columns, $processed_data ); $this->getProgressBarObject()->set( $this->getAPIMessageID(), $key ); $key++; } } } } } unset( $this->tmp_data, $row, $date_columns, $processed_data, $level_1, $level_2, $level_3 ); } //Debug::Arr($this->data, 'preProcess Data: ', __FILE__, __LINE__, __METHOD__, 10); return true; } } ?>