function _getData($format = NULL) { $this->tmp_data = array('pay_stub_entry' => array()); $columns = $this->getColumnDataConfig(); $filter_data = $this->getFilterConfig(); $form_data = $this->formatFormConfig(); require_once Environment::getBasePath() . '/classes/payroll_deduction/PayrollDeduction.class.php'; $pd_obj = new PayrollDeduction('US', 'WA'); //State doesn't matter. $pd_obj->setDate($filter_data['end_date']); $social_security_wage_limit = $pd_obj->getSocialSecurityMaximumEarnings(); $medicare_additional_threshold_limit = $pd_obj->getMedicareAdditionalEmployerThreshold(); Debug::Text('Social Security Wage Limit: ' . $social_security_wage_limit . ' Medicare Threshold: ' . $medicare_additional_threshold_limit . ' Date: ' . TTDate::getDate('DATE', $filter_data['end_date']), __FILE__, __LINE__, __METHOD__, 10); //Need to get totals up to the beginning of this quarter so we can determine if any employees have exceeded the social security limit. $pself = TTnew('PayStubEntryListFactory'); $ytd_filter_data = $filter_data; $ytd_filter_data['end_date'] = $ytd_filter_data['start_date'] - 1; $ytd_filter_data['start_date'] = TTDate::getBeginYearEpoch($ytd_filter_data['start_date']); $pself->getAPIReportByCompanyIdAndArrayCriteria($this->getUserObject()->getCompany(), $ytd_filter_data); //Debug::Arr($ytd_filter_data, 'YTD Filter Data: Row Count: '. $pself->getRecordCount(), __FILE__, __LINE__, __METHOD__,10); if ($pself->getRecordCount() > 0) { foreach ($pself as $pse_obj) { $user_id = $pse_obj->getColumn('user_id'); //Make sure we don't add this to the unique user_id list. //Always use middle day epoch, otherwise multiple entries could exist for the same day. $date_stamp = TTDate::getMiddleDayEpoch(TTDate::strtotime($pse_obj->getColumn('pay_stub_transaction_date'))); $branch = $pse_obj->getColumn('default_branch'); $department = $pse_obj->getColumn('default_department'); $pay_stub_entry_name_id = $pse_obj->getPayStubEntryNameId(); if (!isset($this->tmp_data['pay_stub_entry'][$user_id][$date_stamp])) { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp] = array('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][$date_stamp]['psen_ids'][$pay_stub_entry_name_id])) { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['psen_ids'][$pay_stub_entry_name_id] = bcadd($this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['psen_ids'][$pay_stub_entry_name_id], $pse_obj->getColumn('amount')); } else { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['psen_ids'][$pay_stub_entry_name_id] = $pse_obj->getColumn('amount'); } } if (isset($this->tmp_data['pay_stub_entry']) and is_array($this->tmp_data['pay_stub_entry'])) { foreach ($this->tmp_data['pay_stub_entry'] as $user_id => $data_a) { foreach ($data_a as $date_stamp => $data_b) { if (!isset($this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'])) { $this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] = 0; } $this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] += Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['social_security_wages']['include_pay_stub_entry_account'], $form_data['social_security_wages']['exclude_pay_stub_entry_account']); //Include tips in this amount as well. $this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] += Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['social_security_tips']['include_pay_stub_entry_account'], $form_data['social_security_tips']['exclude_pay_stub_entry_account']); //Handle additional medicare wages in excess of 200,000 if (!isset($this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'])) { $this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'] = 0; } $this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'] += Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['medicare_wages']['include_pay_stub_entry_account'], $form_data['medicare_wages']['exclude_pay_stub_entry_account']); } } } //Debug::Arr($this->tmp_data['ytd_pay_stub_entry'], 'YTD Tmp Raw Data: ', __FILE__, __LINE__, __METHOD__,10); } unset($pse_obj, $user_id, $date_stamp, $branch, $department, $pay_stub_entry_name_id, $this->tmp_data['pay_stub_entry']); //Get just the data for the quarter now. $pself->getAPIReportByCompanyIdAndArrayCriteria($this->getUserObject()->getCompany(), $filter_data); if ($pself->getRecordCount() > 0) { foreach ($pself as $pse_obj) { $user_id = $this->user_ids[] = $pse_obj->getColumn('user_id'); //Always use middle day epoch, otherwise multiple entries could exist for the same day. $date_stamp = TTDate::getMiddleDayEpoch(TTDate::strtotime($pse_obj->getColumn('pay_stub_transaction_date'))); $branch = $pse_obj->getColumn('default_branch'); $department = $pse_obj->getColumn('default_department'); $pay_stub_entry_name_id = $pse_obj->getPayStubEntryNameId(); if (!isset($this->tmp_data['pay_stub_entry'][$user_id][$date_stamp])) { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp] = array('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][$date_stamp]['psen_ids'][$pay_stub_entry_name_id])) { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['psen_ids'][$pay_stub_entry_name_id] = bcadd($this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['psen_ids'][$pay_stub_entry_name_id], $pse_obj->getColumn('amount')); } else { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['psen_ids'][$pay_stub_entry_name_id] = $pse_obj->getColumn('amount'); } } if (isset($this->tmp_data['pay_stub_entry']) and is_array($this->tmp_data['pay_stub_entry'])) { foreach ($this->tmp_data['pay_stub_entry'] as $user_id => $data_a) { foreach ($data_a as $date_stamp => $data_b) { $quarter_month = TTDate::getYearQuarterMonthNumber($date_stamp); //Debug::Text('Quarter Month: '. $quarter_month .' Epoch: '. TTDate::getDate('DATE', $date_stamp), __FILE__, __LINE__, __METHOD__,10); $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['wages'] = Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['wages']['include_pay_stub_entry_account'], $form_data['wages']['exclude_pay_stub_entry_account']); $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['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']); //FIXME: If employees are excluded from Social Security, it will still include total wages //resulting in the 941 form being incorrect in its calculation. //Add Form Setup tab field to select the Social Security tax/deductions? //However there can often be two of them, is just the employee one enough? We could use the employees and include/exclude accounts from that at least then. $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages'] = Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['social_security_wages']['include_pay_stub_entry_account'], $form_data['social_security_wages']['exclude_pay_stub_entry_account']); //Handle social security wage limit. if (!isset($this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'])) { $this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] = 0; } if ($this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] < $social_security_wage_limit) { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages'] = Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['social_security_wages']['include_pay_stub_entry_account'], $form_data['social_security_wages']['exclude_pay_stub_entry_account']); $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_tips'] = Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['social_security_tips']['include_pay_stub_entry_account'], $form_data['social_security_tips']['exclude_pay_stub_entry_account']); if ($this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] + $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages'] + $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_tips'] > $social_security_wage_limit) { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages'] = $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages'] - ($this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] + $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages'] + $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_tips'] - $social_security_wage_limit); $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_tips'] = 0; $this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] = $social_security_wage_limit; } else { $this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages']; $this->tmp_data['ytd_pay_stub_entry'][$user_id]['social_security_wages'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_tips']; } } else { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages'] = 0; $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_tips'] = 0; } $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_wages'] = Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['medicare_wages']['include_pay_stub_entry_account'], $form_data['medicare_wages']['exclude_pay_stub_entry_account']); $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_additional_wages'] = 0; //Handle medicare additional wage limit, only consider wages earned above the threshold to be "medicare_additional_wages" if (!isset($this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'])) { $this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'] = 0; } if ($this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'] > $medicare_additional_threshold_limit) { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_additional_wages'] = $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_wages']; } else { if ($this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'] + $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_wages'] > $medicare_additional_threshold_limit) { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_additional_wages'] = $this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'] + $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_wages'] - $medicare_additional_threshold_limit; } else { $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_additional_wages'] = 0; } } //Debug::Text('User ID: '. $user_id .' DateStamp: '. $date_stamp .' YTD Medicare Additional Wages: '. $this->tmp_data['ytd_pay_stub_entry'][$user_id]['medicare_wages'] .' This Pay Stub: '. $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_additional_wages'], __FILE__, __LINE__, __METHOD__,10); $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['sick_wages'] = Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['sick_wages']['include_pay_stub_entry_account'], $form_data['sick_wages']['exclude_pay_stub_entry_account']); $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['eic'] = Misc::calculateMultipleColumns($data_b['psen_ids'], $form_data['eic']['include_pay_stub_entry_account'], $form_data['eic']['exclude_pay_stub_entry_account']); //Separate data used for reporting, grouping, sorting, from data specific used for the Form. if (!isset($this->form_data['pay_period'][$quarter_month][$date_stamp])) { $this->form_data['pay_period'][$quarter_month][$date_stamp] = Misc::preSetArrayValues(array(), array('l2', 'l3', 'l5a', 'l5b', 'l5c', 'l5d', 'l7', 'l9', 'l5a2', 'l5b2', 'l5c2', 'l5d', 'l8', 'l10'), 0); } $this->form_data['pay_period'][$quarter_month][$date_stamp]['l2'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['wages']; $this->form_data['pay_period'][$quarter_month][$date_stamp]['l3'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['income_tax']; $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5a'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_wages']; $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5b'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['social_security_tips']; $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5c'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_wages']; $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5d'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['medicare_additional_wages']; //$this->form_data['pay_period'][$quarter_month][$date_stamp]['l9'] += $this->tmp_data['pay_stub_entry'][$user_id][$date_stamp]['eic']; $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5f'] = 0; //Not implemented currently. //Calculated fields, make sure we don't use += on these. $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5a2'] = bcmul($this->form_data['pay_period'][$quarter_month][$date_stamp]['l5a'], $this->getF941Object()->social_security_rate); $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5b2'] = bcmul($this->form_data['pay_period'][$quarter_month][$date_stamp]['l5b'], $this->getF941Object()->social_security_rate); $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5c2'] = bcmul($this->form_data['pay_period'][$quarter_month][$date_stamp]['l5c'], $this->getF941Object()->medicare_rate); $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5d2'] = bcmul($this->form_data['pay_period'][$quarter_month][$date_stamp]['l5d'], $this->getF941Object()->medicare_additional_rate); $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5e'] = bcadd($this->form_data['pay_period'][$quarter_month][$date_stamp]['l5a2'], bcadd($this->form_data['pay_period'][$quarter_month][$date_stamp]['l5b2'], bcadd($this->form_data['pay_period'][$quarter_month][$date_stamp]['l5c2'], $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5d2']))); $this->form_data['pay_period'][$quarter_month][$date_stamp]['l6'] = bcadd($this->form_data['pay_period'][$quarter_month][$date_stamp]['l3'], bcadd($this->form_data['pay_period'][$quarter_month][$date_stamp]['l5e'], $this->form_data['pay_period'][$quarter_month][$date_stamp]['l5f'])); //Calculate amounts for Schedule B. $this->form_data['pay_period'][$quarter_month][$date_stamp]['l10'] = $this->form_data['pay_period'][$quarter_month][$date_stamp]['l6']; //Add L6 -> L9 if they are implemented later. } } //Total all pay periods by month_id if (isset($this->form_data['pay_period'])) { foreach ($this->form_data['pay_period'] as $month_id => $pp_data) { $this->form_data['quarter'][$month_id] = Misc::ArrayAssocSum($pp_data, NULL, 8); } //Total all quarters. if (isset($this->form_data['quarter'])) { $this->form_data['total'] = Misc::ArrayAssocSum($this->form_data['quarter'], NULL, 6); } } } } $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'); $ulf->getAPISearchByCompanyIdAndArrayCriteria($this->getUserObject()->getCompany(), $filter_data); Debug::Text(' User Total Rows: ' . $ulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); $this->getProgressBarObject()->start($this->getAMFMessageID(), $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->getProgressBarObject()->set($this->getAMFMessageID(), $key); } //Debug::Arr($this->tmp_data['user'], 'User Raw Data: ', __FILE__, __LINE__, __METHOD__,10); return TRUE; }