TTi18n::gettext( 'Government (Multiple Employees/Page)' ), 'employee' => TTi18n::gettext( 'Employee (One Employee/Page)' ), ]; break; } return $retval; } function getPayrollDeductionObject() { if ( !isset( $this->payroll_deduction_obj ) ) { require_once( Environment::getBasePath() . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'payroll_deduction' . DIRECTORY_SEPARATOR . 'PayrollDeduction.class.php' ); $this->payroll_deduction_obj = new PayrollDeduction( 'US', null ); $this->payroll_deduction_obj->setDate( TTDate::getTimeStamp( $this->year, 12, 31 ) ); } return $this->payroll_deduction_obj; } function getSocialSecurityMaximumEarnings() { return $this->getPayrollDeductionObject()->getSocialSecurityMaximumEarnings(); } function getSocialSecurityMaximumContribution( $type = 'employee' ) { return $this->getPayrollDeductionObject()->getSocialSecurityMaximumContribution( $type ); } //Set the type of form to display/print. Typically this would be: // government or employee. function getType() { if ( isset( $this->type ) ) { return $this->type; } return false; } function setType( $value ) { $this->type = trim( $value ); return true; } function getShowInstructionPage() { if ( isset( $this->show_instruction_page ) ) { return $this->show_instruction_page; } return false; } function setShowInstructionPage( $value ) { $this->show_instruction_page = (bool)trim( $value ); return true; } public function getTemplateSchema( $name = null ) { $template_schema = [ [ //'page' => 1, //'template_page' => array( // array( 'template_page' => 2, 'x'=> 0, 'y' => 0), // array( 'template_page' => 2, 'x'=> 0, 'y' => 350), //Place two templates on the same page. // ), 'only_template_page' => [ 2, 3, 10, 4, 6, 8 ], 'value' => $this->year, 'on_background' => true, 'coordinates' => [ 'x' => 260, 'y' => 340, 'h' => 20, 'w' => 120, 'halign' => 'C', 'fill_color' => [ 255, 255, 255 ], ], 'font' => [ 'size' => 18, 'type' => 'B', ], ], [ //Instructions section 'only_template_page' => 5, 'value' => $this->year, 'on_background' => true, 'coordinates' => [ 'x' => 69, 'y' => 121, 'h' => 10, 'w' => 23, 'halign' => 'C', 'fill_color' => [ 255, 255, 255 ], ], 'font' => [ 'size' => 9, 'type' => '', ], ], [ //Instructions section 'only_template_page' => 5, 'value' => $this->year, 'on_background' => true, 'coordinates' => [ 'x' => 169, 'y' => 186, 'h' => 10, 'w' => 23, 'halign' => 'C', 'fill_color' => [ 255, 255, 255 ], ], 'font' => [ 'size' => 9, 'type' => '', ], ], [ //Instructions section 'only_template_page' => 5, 'value' => $this->year, 'on_background' => true, 'coordinates' => [ 'x' => 102, 'y' => 207, 'h' => 10, 'w' => 23, 'halign' => 'C', 'fill_color' => [ 255, 255, 255 ], ], 'font' => [ 'size' => 9, 'type' => '', ], ], [ //Instructions section 'only_template_page' => 5, 'value' => $this->year, 'on_background' => true, 'coordinates' => [ 'x' => 371, 'y' => 242, 'h' => 10, 'w' => 23, 'halign' => 'C', 'fill_color' => [ 255, 255, 255 ], ], 'font' => [ 'size' => 9, 'type' => '', ], ], [ //Instructions section 'only_template_page' => 7, 'value' => $this->year, 'on_background' => true, 'coordinates' => [ 'x' => 464, 'y' => 148, 'h' => 6, 'w' => 19, 'halign' => 'C', 'fill_color' => [ 255, 255, 255 ], ], 'font' => [ 'size' => 7, 'type' => '', ], ], //Finish initializing page 1. 'ssn' => [ 'function' => [ 'draw' => [ 'formatSSN', 'drawNormal' ] ], 'coordinates' => [ 'x' => 153, 'y' => 47, 'h' => 15, 'w' => 127, 'halign' => 'C', ], ], 'ein' => [ 'function' => [ 'prefilter' => [ 'stripNonNumeric', 'isNumeric' ], 'draw' => [ 'formatEIN', 'drawNormal' ] ], 'coordinates' => [ 'x' => 38, 'y' => 70, 'h' => 15, 'w' => 280, 'halign' => 'L', ], ], 'trade_name' => [ 'coordinates' => [ 'x' => 48, //Make sure there is enough spacing to fit in double windowed envelope with buffer. 'y' => 102, //Make sure there is enough spacing to fit in double windowed envelope with buffer. 'h' => 15, 'w' => 280, 'halign' => 'L', ], ], 'company_address' => [ 'function' => [ 'draw' => [ 'filterCompanyAddress', 'drawNormal' ] ], 'coordinates' => [ 'x' => 48, 'y' => 117, 'h' => 48, 'w' => 280, 'halign' => 'L', ], 'font' => [ 'size' => 8, 'type' => '', ], 'multicell' => true, ], 'control_number' => [ 'function' => [ 'draw' => [ 'filterControlNumber', 'drawNormal' ] ], 'coordinates' => [ 'x' => 38, 'y' => 165, 'h' => 15, 'w' => 127, 'halign' => 'L', ], ], 'first_name' => [ 'coordinates' => [ 'x' => 48, 'y' => 189, 'h' => 15, 'w' => 122, 'halign' => 'L', ], ], 'middle_name' => [ 'function' => [ 'draw' => [ 'filterMiddleName', 'drawNormal' ] ], 'coordinates' => [ 'x' => 152, 'y' => 189, 'h' => 15, 'w' => 10, 'halign' => 'L', ], ], 'last_name' => [ 'coordinates' => [ 'x' => 185, 'y' => 189, 'h' => 15, 'w' => 127, 'halign' => 'L', ], ], 'address' => [ 'function' => [ 'draw' => [ 'filterAddress', 'drawNormal' ] ], 'coordinates' => [ 'x' => 48, //Make sure there is enough spacing to fit in double windowed envelope with buffer. 'y' => 225, //Make sure there is enough spacing to fit in double windowed envelope with buffer. 'h' => 68, 'w' => 280, 'halign' => 'L', ], 'font' => [ 'size' => 8, 'type' => '', ], 'multicell' => true, ], 'l1' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 335, 'y' => 70, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l2' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 459, 'y' => 70, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l3' => [ 'function' => [ 'precalc' => 'preCalcL3', 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 335, 'y' => 94, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l4' => [ 'function' => [ 'precalc' => 'preCalcL4', 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 459, 'y' => 94, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l5' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 335, 'y' => 118, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l6' => [ 'function' => [ 'precalc' => 'preCalcL6', 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 459, 'y' => 118, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l7' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 335, 'y' => 142, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l8' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 459, 'y' => 142, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l9' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 335, 'y' => 166, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l10' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 459, 'y' => 166, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l11' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 335, 'y' => 189, 'h' => 15, 'w' => 115, 'halign' => 'R', ], ], 'l12a_code' => [ 'coordinates' => [ 'x' => 460, 'y' => 189, 'h' => 15, 'w' => 30, 'halign' => 'C', ], ], 'l12a' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 491, 'y' => 189, 'h' => 15, 'w' => 83, 'halign' => 'R', ], ], 'l12b_code' => [ 'coordinates' => [ 'x' => 460, 'y' => 214, 'h' => 15, 'w' => 30, 'halign' => 'C', ], ], 'l12b' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 491, 'y' => 214, 'h' => 15, 'w' => 83, 'halign' => 'R', ], ], 'l12c_code' => [ 'coordinates' => [ 'x' => 460, 'y' => 238, 'h' => 15, 'w' => 30, 'halign' => 'C', ], ], 'l12c' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 491, 'y' => 238, 'h' => 15, 'w' => 83, 'halign' => 'R', ], ], 'l12d_code' => [ 'coordinates' => [ 'x' => 460, 'y' => 262, 'h' => 15, 'w' => 30, 'halign' => 'C', ], ], 'l12d' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 491, 'y' => 262, 'h' => 15, 'w' => 83, 'halign' => 'R', ], ], 'l13a' => [ 'function' => [ 'draw' => 'drawCheckBox' ], 'coordinates' => [ [ 'x' => 348, 'y' => 216, 'h' => 11, 'w' => 10, 'halign' => 'C', ], ], ], 'l13b' => [ 'function' => [ 'draw' => 'drawCheckBox' ], 'coordinates' => [ [ 'x' => 384, 'y' => 216, 'h' => 11, 'w' => 10, 'halign' => 'C', ], ], ], 'l13c' => [ 'function' => [ 'draw' => 'drawCheckBox' ], 'coordinates' => [ [ 'x' => 420, 'y' => 216, 'h' => 11, 'w' => 10, 'halign' => 'C', ], ], ], 'l14a_name' => [ 'coordinates' => [ 'x' => 331, 'y' => 238, 'h' => 12, 'w' => 87, 'halign' => 'L', ], ], 'l14a' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 418, 'y' => 238, 'h' => 12, 'w' => 35, 'halign' => 'R', ], ], 'l14b_name' => [ 'coordinates' => [ 'x' => 331, 'y' => 250, 'h' => 12, 'w' => 87, 'halign' => 'L', ], ], 'l14b' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 418, 'y' => 250, 'h' => 12, 'w' => 35, 'halign' => 'R', ], ], 'l14c_name' => [ 'coordinates' => [ 'x' => 331, 'y' => 262, 'h' => 12, 'w' => 87, 'halign' => 'L', ], ], 'l14c' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 418, 'y' => 262, 'h' => 12, 'w' => 35, 'halign' => 'R', ], ], 'l14d_name' => [ 'coordinates' => [ 'x' => 331, 'y' => 274, 'h' => 12, 'w' => 87, 'halign' => 'L', ], ], 'l14d' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 418, 'y' => 274, 'h' => 12, 'w' => 35, 'halign' => 'R', ], ], //State (Line 1) 'l15a_state' => [ 'coordinates' => [ 'x' => 38, 'y' => 298, 'h' => 12, 'w' => 27, 'halign' => 'C', ], ], 'l15a_state_id' => [ 'coordinates' => [ 'x' => 65, 'y' => 298, 'h' => 12, 'w' => 130, 'halign' => 'C', ], ], 'l16a' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 196, 'y' => 298, 'h' => 12, 'w' => 85, 'halign' => 'R', ], ], 'l17a' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 281, 'y' => 298, 'h' => 12, 'w' => 79, 'halign' => 'R', ], ], 'l18a' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 360, 'y' => 298, 'h' => 12, 'w' => 86, 'halign' => 'R', ], ], 'l19a' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 446, 'y' => 298, 'h' => 12, 'w' => 80, 'halign' => 'R', ], ], 'l20a_district' => [ 'coordinates' => [ 'x' => 526, 'y' => 298, 'h' => 12, 'w' => 50, 'halign' => 'R', ], ], //State (Line 2) 'l15b_state' => [ 'coordinates' => [ 'x' => 38, 'y' => 320, 'h' => 12, 'w' => 27, 'halign' => 'C', ], ], 'l15b_state_id' => [ 'coordinates' => [ 'x' => 65, 'y' => 320, 'h' => 12, 'w' => 130, 'halign' => 'C', ], ], 'l16b' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 196, 'y' => 320, 'h' => 12, 'w' => 85, 'halign' => 'R', ], ], 'l17b' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 281, 'y' => 320, 'h' => 12, 'w' => 79, 'halign' => 'R', ], ], 'l18b' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 360, 'y' => 320, 'h' => 12, 'w' => 86, 'halign' => 'R', ], ], 'l19b' => [ 'function' => [ 'draw' => [ 'MoneyFormat', 'drawNormal' ] ], 'coordinates' => [ 'x' => 446, 'y' => 320, 'h' => 12, 'w' => 80, 'halign' => 'R', ], ], 'l20b_district' => [ 'function' => [ 'draw' => [ 'filterDistrict', 'drawNormal' ] ], 'coordinates' => [ 'x' => 526, 'y' => 320, 'h' => 12, 'w' => 50, 'halign' => 'R', ], ], ]; if ( isset( $template_schema[$name] ) ) { return $name; } else { return $template_schema; } } function preCalcL3( $value, $key, &$array ) { if ( $value > $this->getSocialSecurityMaximumEarnings() ) { //Debug::Text( 'Social security earnings exceeds maximum...', __FILE__, __LINE__, __METHOD__, 10 ); //This is normal for high earning employees. $value = $this->getSocialSecurityMaximumEarnings(); } return $value; } function preCalcL4( $value, $key, &$array ) { if ( $value === false || $value <= 0 ) { $value = false; $array['l3'] = false; //If no Social Security Tax was withheld, assume exempt and change Social Security wages to 0. Debug::Text( 'No social security tax withheld, setting wages to 0...', __FILE__, __LINE__, __METHOD__, 10 ); } else if ( $value > $this->getSocialSecurityMaximumContribution() ) { Debug::Text( 'Social security contributions exceeds maximum... User: '. $array['user_id'], __FILE__, __LINE__, __METHOD__, 10 ); //This is NOT normal, and should never happen unless an error was made. $value = $this->getSocialSecurityMaximumContribution(); } return $value; } function preCalcL6( $value, $key, &$array ) { if ( $value === false || $value <= 0 ) { $value = false; $array['l5'] = false; //If no Medicare Tax was withheld, assume exempt change Medicare wages to 0. Debug::Text( 'No medicare tax withheld, setting wages to 0: ', __FILE__, __LINE__, __METHOD__, 10 ); } return $value; } function filterMiddleName( $value ) { //Return just initial $value = substr( $value, 0, 1 ); return $value; } function filterCompanyAddress( $value ) { //Debug::Text('Filtering company address: '. $value, __FILE__, __LINE__, __METHOD__, 10); //Combine company address for multicell display. $retarr[] = $this->company_address1; if ( $this->company_address2 != '' ) { $retarr[] = $this->company_address2; } $retarr[] = $this->company_city . ', ' . $this->company_state . ' ' . $this->company_zip_code; return implode( "\n", $retarr ); } function filterAddress( $value ) { //Combine company address for multicell display. $retarr[] = $this->address1; if ( $this->address2 != '' ) { $retarr[] = $this->address2; } $retarr[] = $this->city . ', ' . $this->state . ' ' . $this->zip_code; return implode( "\n", $retarr ); } function filterDistrict( $value ) { //Strip off any codes specified in the locality name. $value = strtoupper( trim( preg_replace( '/\[.*\]/', '', $value ) ) ); //Strip off the square brackets [] return $value; } function filterControlNumber( $value ) { $value = str_pad( $value, 4, 0, STR_PAD_LEFT ); return $value; } function _getStateName( $state ) { $map = [ 'AL' => 'Alabama', 'AK' => 'Alaska', 'AZ' => 'Arizona', 'AR' => 'Arkansas', 'CA' => 'California', 'CO' => 'Colorado', 'CT' => 'Connecticut', 'DE' => 'Delaware', 'DC' => 'D.C.', 'FL' => 'Florida', 'GA' => 'Georgia', 'HI' => 'Hawaii', 'ID' => 'Idaho', 'IL' => 'Illinois', 'IN' => 'Indiana', 'IA' => 'Iowa', 'KS' => 'Kansas', 'KY' => 'Kentucky', 'LA' => 'Louisiana', 'ME' => 'Maine', 'MD' => 'Maryland', 'MA' => 'Massachusetts', 'MI' => 'Michigan', 'MN' => 'Minnesota', 'MS' => 'Mississippi', 'MO' => 'Missouri', 'MT' => 'Montana', 'NE' => 'Nebraska', 'NV' => 'Nevada', 'NH' => 'New Hampshire', 'NM' => 'New Mexico', 'NJ' => 'New Jersey', 'NY' => 'New York', 'NC' => 'North Carolina', 'ND' => 'North Dakota', 'OH' => 'Ohio', 'OK' => 'Oklahoma', 'OR' => 'Oregon', 'PA' => 'Pennsylvania', 'RI' => 'Rhode Island', 'SC' => 'South Carolina', 'SD' => 'South Dakota', 'TN' => 'Tennessee', 'TX' => 'Texas', 'UT' => 'Utah', 'VT' => 'Vermont', 'VA' => 'Virginia', 'WA' => 'Washington', 'WV' => 'West Virginia', 'WI' => 'Wisconsin', 'WY' => 'Wyoming', ]; if ( isset( $map[strtoupper( $state )] ) ) { return $map[strtoupper( $state )]; } return false; } function _getStateNumericCode( $state ) { $map = [ 'AL' => '01', 'AK' => '02', 'AZ' => '04', 'AR' => '05', 'CA' => '06', 'CO' => '08', 'CT' => '09', 'DE' => '10', 'DC' => '11', 'FL' => '12', 'GA' => '13', 'HI' => '15', 'ID' => '16', 'IL' => '17', 'IN' => '18', 'IA' => '19', 'KS' => '20', 'KY' => '21', 'LA' => '22', 'ME' => '23', 'MD' => '24', 'MA' => '25', 'MI' => '26', 'MN' => '27', 'MS' => '28', 'MO' => '29', 'MT' => '30', 'NE' => '31', 'NV' => '32', 'NH' => '33', 'NM' => '34', 'NJ' => '35', 'NY' => '36', 'NC' => '37', 'ND' => '38', 'OH' => '39', 'OK' => '40', 'OR' => '41', 'PA' => '42', 'RI' => '44', 'SC' => '45', 'SD' => '46', 'TN' => '47', 'TX' => '48', 'UT' => '49', 'VT' => '50', 'VA' => '51', 'WA' => '53', 'WV' => '54', 'WI' => '55', 'WY' => '56', ]; if ( isset( $map[strtoupper( $state )] ) ) { return $map[strtoupper( $state )]; } return false; } function _getL12AmountByCode( $code ) { //Debug::Text( 'Checking for Code:' . $code, __FILE__, __LINE__, __METHOD__, 10 ); foreach ( range( 'a', 'z' ) as $z ) { if ( isset( $this->{'l12' . $z . '_code'} ) && $this->{'l12' . $z . '_code'} == $code ) { Debug::Text( ' Found amount for Code:' . $code, __FILE__, __LINE__, __METHOD__, 10 ); return $this->{'l12' . $z}; } } //Debug::Text( 'No amount found, Code:' . $code, __FILE__, __LINE__, __METHOD__, 10 ); return false; } function _compileRA() { //RA (Submitter) Record if ( in_array( strtoupper( $this->efile_state ), [ 'AL' ] ) ) { //Skip for eFiling in these states. return false; } $line[] = 'RA'; //RA Record Debug::Text( 'RA Record State: ' . $this->efile_state, __FILE__, __LINE__, __METHOD__, 10 ); switch ( strtolower( $this->efile_state ) ) { case 'ny': //New York $efile_user_id = null; $is_resub = null; $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //EIN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $efile_user_id ), 8, 'AN' ); //User ID $line[] = $this->padRecord( '', 4, 'AN' ); //Software Vendor code $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( $is_resub, 1, 'AN' ); //Resub $line[] = $this->padRecord( '', 6, 'AN' ); //Blank $line[] = $this->padRecord( '', 2, 'AN' ); //Software Code $line[] = $this->padRecord( '', 57, 'AN' ); //Company Name $line[] = $this->padRecord( '', 22, 'AN' ); //Company Location Address $line[] = $this->padRecord( '', 22, 'AN' ); //Company Delivery Address $line[] = $this->padRecord( '', 22, 'AN' ); //Company City $line[] = $this->padRecord( '', 2, 'AN' ); //Company State $line[] = $this->padRecord( '', 5, 'AN' ); //Company Zip Code $line[] = $this->padRecord( '', 4, 'AN' ); //Company Zip Code Extension $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 23, 'AN' ); //Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //Company Country, fill with blanks if its the US $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->trade_name ), 57, 'AN' ); //Submitter organization. $line[] = $this->padRecord( $this->stripNonAlphaNumeric( ( $this->company_address2 != '' ) ? $this->company_address2 : $this->company_address1 ), 22, 'AN' ); //Submitter Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address1 ), 22, 'AN' ); //Submitter Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_city ), 22, 'AN' ); //Submitter City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_state ), 2, 'AN' ); //Submitter State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_zip_code ), 5, 'AN' ); //Submitter Zip Code $line[] = $this->padRecord( '', 4, 'AN' ); //Submitter Zip Code Extension $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 23, 'AN' ); //Submitter Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //Submitter Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //Submitter Country, fill with blanks if its the US $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->contact_name ), 27, 'AN' ); //Contact Name $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_phone ), 15, 'AN' ); //Contact Phone $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_phone_ext ), 5, 'AN' ); //Contact Phone Ext $line[] = $this->padRecord( '', 3, 'AN' ); //Blank $line[] = $this->padRecord( $this->contact_email, 40, 'AN' ); //Contact Email $line[] = $this->padRecord( '', 3, 'AN' ); //Blank $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_fax ), 10, 'AN' ); //Contact Fax $line[] = $this->padRecord( '', 1, 'AN' ); //Blank $line[] = $this->padRecord( '', 1, 'AN' ); //PreParers Code $line[] = $this->padRecord( '', 12, 'AN' ); //Blank break; default: $is_resub = 0; $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //EIN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->efile_user_id ), 8, 'AN' ); //User ID $line[] = $this->padRecord( '', 4, 'AN' ); //Software Vendor code $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( $is_resub, 1, 'AN' ); //Resub $line[] = $this->padRecord( '', 6, 'AN' ); //Blank $line[] = $this->padRecord( '98', 2, 'AN' ); //Software Code $line[] = $this->padRecord( $this->trade_name, 57, 'AN' ); //Company Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address2 ), 22, 'AN' ); //Company Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address1 ), 22, 'AN' ); //Company Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_city ), 22, 'AN' ); //Company City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_state ), 2, 'AN' ); //Company State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_zip_code ), 5, 'AN' ); //Company Zip Code $line[] = $this->padRecord( '', 4, 'AN' ); //Company Zip Code Extension $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 23, 'AN' ); //Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //Company Country, fill with blanks if its the US $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->trade_name ), 57, 'AN' ); //Submitter organization. $line[] = $this->padRecord( $this->stripNonAlphaNumeric( ( $this->company_address2 != '' ) ? $this->company_address2 : $this->company_address1 ), 22, 'AN' ); //Submitter Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address1 ), 22, 'AN' ); //Submitter Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_city ), 22, 'AN' ); //Submitter City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_state ), 2, 'AN' ); //Submitter State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_zip_code ), 5, 'AN' ); //Submitter Zip Code $line[] = $this->padRecord( '', 4, 'AN' ); //Submitter Zip Code Extension $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 23, 'AN' ); //Submitter Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //Submitter Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //Submitter Country, fill with blanks if its the US $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->contact_name ), 27, 'AN' ); //Contact Name $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_phone ), 15, 'AN' ); //Contact Phone $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_phone_ext ), 5, 'AN' ); //Contact Phone Ext $line[] = $this->padRecord( '', 3, 'AN' ); //Blank $line[] = $this->padRecord( $this->contact_email, 40, 'AN' ); //Contact Email $line[] = $this->padRecord( '', 3, 'AN' ); //Blank $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_fax ), 10, 'AN' ); //Contact Fax $line[] = $this->padRecord( '', 1, 'AN' ); //Blank $line[] = $this->padRecord( 'L', 1, 'AN' ); //PreParers Code $line[] = $this->padRecord( '', 12, 'AN' ); //Blank break; } $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RA Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RA Record:' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } function _compileRE() { //RE (Employer) Record if ( in_array( strtoupper( $this->efile_state ), [ 'AL' ] ) ) { //Skip for eFiling in these states. return false; } switch ( strtolower( $this->efile_state ) ) { case 'ny': //New York $line[] = 'RE'; //(1-2) RE Record $line[] = $this->padRecord( '', 4, 'AN' ); //(3-6) Tax Year $line[] = $this->padRecord( '', 1, 'AN' ); //(7) Agent Indicator $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //(8-16 ) EIN $line[] = $this->padRecord( '', 9, 'AN' ); //(17-25) Agent for EIN $line[] = $this->padRecord( '', 1, 'AN' ); //(26) Terminating Business $line[] = $this->padRecord( '', 4, 'AN' ); //(27-30) Establishment Number $line[] = $this->padRecord( '', 9, 'AN' ); //(31-39) Other EIN $line[] = $this->padRecord( $this->trade_name, 57, 'AN' ); //(40-96) Company Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address2 ), 22, 'AN' ); //(97-118) Company Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address1 ), 22, 'AN' ); //(119-140) Company Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_city ), 22, 'AN' ); //(141-162) Company City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_state ), 2, 'AN' ); //(163-164) Company State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_zip_code ), 5, 'AN' ); //(165-169) Company Zip Code $line[] = $this->padRecord( '', 4, 'AN' ); //(170-173) Company Zip Code Extension $line[] = $this->padRecord( '42020', 5, 'AN' ); //(174) Kind of Employer ??????? //$line[] = $this->padRecord( '', 4, 'AN' ); //(175-178) Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(179-201) Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(202-216) Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(217-218) Country, fill with blanks if its the US $line[] = $this->padRecord( '', 1, 'AN' ); //(219) Employment Code - 941 Form $line[] = $this->padRecord( '', 1, 'AN' ); //(220) Tax Jurisdiction $line[] = $this->padRecord( '', 1, 'AN' ); //(221) Third Party Sick Pay $line[] = $this->padRecord( '', 27, 'AN' ); //(222-248) Contact Name $line[] = $this->padRecord( '', 15, 'AN' ); //(249-263) Contact Phone $line[] = $this->padRecord( '', 5, 'AN' ); //(264-268) Contact Phone Ext $line[] = $this->padRecord( '', 10, 'AN' ); //(269-278) Contact Fax $line[] = $this->padRecord( '', 40, 'AN' ); //(279-318) Contact Email $line[] = $this->padRecord( '', 194, 'AN' ); //(319-512) Blank break; default: $line[] = 'RE'; //(1-2) RE Record $line[] = $this->padRecord( $this->stripNonNumeric( $this->year ), 4, 'N' ); //(3-6) Tax Year $line[] = $this->padRecord( '', 1, 'AN' ); //(7) Agent Indicator $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //(8-16 ) EIN $line[] = $this->padRecord( '', 9, 'AN' ); //(17-25) Agent for EIN $line[] = $this->padRecord( '0', 1, 'N' ); //(26) Terminating Business $line[] = $this->padRecord( '', 4, 'AN' ); //(27-30) Establishment Number $line[] = $this->padRecord( '', 9, 'AN' ); //(31-39) Other EIN $line[] = $this->padRecord( $this->trade_name, 57, 'AN' ); //(40-96) Company Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address2 ), 22, 'AN' ); //(97-118) Company Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address1 ), 22, 'AN' ); //(119-140) Company Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_city ), 22, 'AN' ); //(141-162) Company City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_state ), 2, 'AN' ); //(163-164) Company State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_zip_code ), 5, 'AN' ); //(165-169) Company Zip Code $line[] = $this->padRecord( '', 4, 'AN' ); //(170-173) Company Zip Code Extension $line[] = $this->padRecord( strtoupper( $this->kind_of_employer ), 1, 'AN' ); //(174) Kind of Employer $line[] = $this->padRecord( '', 4, 'AN' ); //(175-178) Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(179-201) Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(202-216) Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(217-218) Country, fill with blanks if its the US $line[] = $this->padRecord( 'R', 1, 'AN' ); //(219) Employment Code - 941 Form $line[] = $this->padRecord( '', 1, 'AN' ); //(220) Tax Jurisdiction $line[] = $this->padRecord( ( $this->l13c == '' ) ? 0 : 1, 1, 'N' ); //(221) Third Party Sick Pay $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->contact_name ), 27, 'AN' ); //(222-248) Contact Name $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_phone ), 15, 'AN' ); //(249-263) Contact Phone $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_phone_ext ), 5, 'AN' ); //(264-268) Contact Phone Ext $line[] = $this->padRecord( $this->stripNonNumeric( $this->contact_fax ), 10, 'AN' ); //(269-278) Contact Fax $line[] = $this->padRecord( $this->contact_email, 40, 'AN' ); //(279-318) Contact Email $line[] = $this->padRecord( '', 194, 'AN' ); //(319-512) Blank break; } $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RE Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RE Record:' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } function _compileRW() { //RW (Employee) Record if ( in_array( strtoupper( $this->efile_state ), [ 'NY', 'AL', 'CO', 'CT', 'DE', 'MA', 'PA', 'VA' ] ) ) { //Skip for eFiling in these states. return false; } switch ( strtolower( $this->efile_state ) ) { default: $line[] = 'RW'; //RW Record $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //Zip $line[] = $this->padRecord( '', 4, 'AN' ); //Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 23, 'AN' ); //Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //Country, fill with blanks if its the US $line[] = $this->padRecord( $this->removeDecimal( $this->l1 ), 11, 'N' ); //(188-198) Wages, Tips and Other Compensation $line[] = $this->padRecord( $this->removeDecimal( $this->l2 ), 11, 'N' ); //(199-209) Federal Income Tax $line[] = $this->padRecord( $this->removeDecimal( $this->l3 ), 11, 'N' ); //(210-220) Social Security Wages $line[] = $this->padRecord( $this->removeDecimal( $this->l4 ), 11, 'N' ); //(221-231) Social Security Tax $line[] = $this->padRecord( $this->removeDecimal( $this->l5 ), 11, 'N' ); //(232-242) Medicare Wages and Tips $line[] = $this->padRecord( $this->removeDecimal( $this->l6 ), 11, 'N' ); //(243-253) Medicare Tax $line[] = $this->padRecord( $this->removeDecimal( $this->l7 ), 11, 'N' ); //(254-264) Social Security Tips $line[] = $this->padRecord( '', 11, 'AN' ); //(265-275) Blank $line[] = $this->padRecord( $this->removeDecimal( $this->l10 ), 11, 'N' ); //(276-286) Dependant Care Benefits $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'D' ) ), 11, 'N' ); //Deferred Compensation Contributions to 401K //Code D in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'E' ) ), 11, 'N' ); //Deferred Compensation Contributions to 403(b) //Code E in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'F' ) ), 11, 'N' ); //Deferred Compensation Contributions to 408(k)(6) //Code F in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'G' ) ), 11, 'N' ); //Deferred Compensation Contributions to 457(b) //Code G in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'H' ) ), 11, 'N' ); //(331-341) Deferred Compensation Contributions to 501(c)(18)(D) //Code H in any of the Box 12(a through d). $line[] = $this->padRecord( '', 11, 'AN' ); //(342-352) Blank $line[] = $this->padRecord( $this->removeDecimal( $this->l11 ), 11, 'N' ); //(353-363) Non-qualified Plan Section 457 $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'W' ) ), 11, 'N' ); //(364-374) Employer Contributions to Health Savings Account //Code W in any of the Box 12(a through d). $line[] = $this->padRecord( '', 11, 'N' ); //(375-385) Non-qualified NOT Plan Section 457 $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'Q' ) ), 11, 'N' ); //(386-396) Non taxable combat pay //Code Q in any of the Box 12(a through d). $line[] = $this->padRecord( '', 11, 'AN' ); //Blank $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'C' ) ), 11, 'N' ); //(408-418) Employer Cost of Premiums for Group Term Life Insurance over $50K //Code C in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'V' ) ), 11, 'N' ); //(419-429) Income from the Exercise of Nonstatutory Stock Options //Code V in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'Y' ) ), 11, 'N' ); //(430-440) Deferrals Under a Section 409A non-qualified plan //Code Y in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'AA' ) ), 11, 'N' ); //(441-451) Desiginated Roth Contributions under a section 401K //Code AA in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'BB' ) ), 11, 'N' ); //(452-462) Desiginated Roth Contributions under a section 403B //Code BB in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'DD' ) ), 11, 'N' ); //(463-473) Cost of Employer Sponsored Health Coverage //Code DD in any of the Box 12(a through d). $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'FF' ) ), 11, 'N' ); //(474-484) Permitted Benefits Under a Qualified Small Employer Health Reimbursement Arrangement //Code FF in any of the Box 12(a through d). $line[] = $this->padRecord( '', 1, 'AN' ); //(485) Blank $line[] = $this->padRecord( ( ( $this->l13a == '' ) ? 0 : 1 ), 1, 'N' ); //(486) Statutory Employee $line[] = $this->padRecord( '', 1, 'AN' ); //(487) Blank $line[] = $this->padRecord( ( ( $this->l13b == '' ) ? 0 : 1 ), 1, 'N' ); //(488) Retirement Plan Indicator $line[] = $this->padRecord( ( ( $this->l13c == '' ) ? 0 : 1 ), 1, 'N' ); //(489) 3rd Party Sick Pay Indicator $line[] = $this->padRecord( '', 23, 'AN' ); //(490-512) Blank break; } $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RW Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RW Record:' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } //ID is the state identifier like: a, b, c, d,... function _compileRS( $id ) { //RS (State) Record if ( $this->efile_state == '' ) { //Federal filing does not need any RS record at all. return false; } $l15_state = 'l15' . $id . '_state'; $l15_state_id = 'l15' . $id . '_state_id'; $l15_state_control_number = 'l15' . $id . '_state_control_number'; $l16 = 'l16' . $id; $l17 = 'l17' . $id; $l18 = 'l18' . $id; $l19 = 'l19' . $id; $l20 = 'l20' . $id . '_district'; if ( !isset( $this->$l15_state ) ) { return false; } if ( strtolower( $this->efile_state ) != strtolower( $this->$l15_state ) ) { Debug::Text( ' eFile Format for State: ' . $this->efile_state . ' Employee Record State: ' . $this->$l15_state, __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RS Record State: ' . $this->efile_state, __FILE__, __LINE__, __METHOD__, 10 ); switch ( strtolower( $this->efile_state ) ) { case 'al': //Alabama //Withholding Number for State format is the State ID number. $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( '', 2, 'AN' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( '', 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( '', 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( '', 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( '', 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( '', 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //(197-202)[6]: Reporting Period $line[] = $this->padRecord( '', 11, 'AN' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'AN' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 10, 'N' ); //(248-257)[10]: State Employer Account Number - For AL: Numbers below 700000 – right justify and zero fill. Numbers 700000 and above – R followed by nine digits. $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //(258-266)[9]: FEIN $line[] = $this->padRecord( '', 7, 'AN' ); //(267-273)[7]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( $this->removeDecimal( $this->l2 ), 10, 'N' ); //(298-307)[10]: AL: Federal Income Tax Withheld $line[] = $this->padRecord( '', 1, 'AN' ); //(308)[1]: Tax Type Code [C=City, D=County, E=School District, F=Other] $line[] = $this->padRecord( '', 11, 'AN' ); //(309-319)[11]: Local Wages $line[] = $this->padRecord( '', 11, 'AN' ); //(320-330)[11]: Local Income Tax $line[] = $this->padRecord( '', 7, 'AN' ); //(331-337)[7]: State Control Number $line[] = $this->padRecord( 0, 11, 'N' ); //(338-348)[11]: AL: Other income (1099, W2G, etc.), columns 338-348. (Only use this field to report other income reported on 1099, W2G, etc. from which Alabama tax was withheld. Zero fill if not applicable.) $line[] = $this->padRecord( '', 44, 'AN' ); //(349-392)[44]: Supplemental Data 1 $line[] = $this->padRecord( $this->year, 4, 'N' ); //(393-396)[4]: AL: Payment Year $line[] = $this->padRecord( '', 116, 'AN' ); //(397-512)[116]: Supplemental Data 1 break; case 'ar': //Arkansas - https://www.dfa.arkansas.gov/images/uploads/incomeTaxOffice/Mag_Media.pdf //Withholding Number for State format is the State ID number. $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '122020', 6, 'AN' ); //(197-202)[6]: AR: Last month and four digit year for the calendar quarter. Unemployment only, but might be required? $line[] = $this->padRecord( '', 11, 'N' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'N' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'N' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 20, 'AN' ); //(248-267)[20]: AR: FEIN $line[] = $this->padRecord( '', 6, 'AN' ); //(268-273)[6]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( '', 10, 'AN' ); //(298-307)[10]: Other State Data $line[] = $this->padRecord( '', 1, 'AN' ); //(308)[1]: Tax Type Code [C=City, D=County, E=School District, F=Other] $line[] = $this->padRecord( '', 11, 'AN' ); //(309-319)[11]: Local Wages $line[] = $this->padRecord( '', 11, 'AN' ); //(320-330)[11]: Local Income Tax $line[] = $this->padRecord( '', 7, 'AN' ); //(331-337)[7]: State Control Number $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 75, 'AN' ); //(338-412)[75]: AR: Same as 248-267. EIN from RE Record. $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 75, 'AN' ); //(413-487)[75]: AR: 11 digit State of Arkansas ID number. Omit hypens. $line[] = $this->padRecord( '', 25, 'AN' ); //(488-512)[25]: Blank break; case 'ga': //Georgia -- Has Local Taxes // File Format Specifications: https://dor.georgia.gov/sites/dor.georgia.gov/files/related_files/document/Federal%20Format%20Specs%202015.pdf $line[] = 'RS'; //RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //State Code $line[] = $this->padRecord( '', 5, 'AN' ); //Tax Entity Code (Leave Blank) $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //Zip $line[] = $this->padRecord( '', 4, 'AN' ); //Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 23, 'AN' ); //Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //Reporting Period $line[] = $this->padRecord( '', 11, 'N' ); //State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'N' ); //State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 20, 'AN' ); //State Employer Account Number $line[] = $this->padRecord( '', 6, 'AN' ); //Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //State income tax $line[] = $this->padRecord( '12/31/' . $this->year, 10, 'AN' ); //Period End Date (last day of the year) $line[] = $this->padRecord( '', 1, 'AN' ); //Tax Type Code $line[] = $this->padRecord( '', 11, 'AN' ); //Local Wages (blank) $line[] = $this->padRecord( '', 11, 'AN' ); //Local Income Tax (blank) $line[] = $this->padRecord( str_replace( [ '-', ' ' ], '', strtoupper( $this->$l15_state_id ) ), 9, 'AN' ); //Withholding Number, no hyphen and upper case alpha $line[] = $this->padRecord( $this->trade_name, 57, 'AN' ); //Company Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address2 ), 22, 'AN' ); //Company Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_address1 ), 22, 'AN' ); //Company Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_city ), 22, 'AN' ); //Company City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_state ), 2, 'AN' ); //Company State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->company_zip_code ), 5, 'AN' ); //Company Zip Code $line[] = $this->padRecord( '', 4, 'AN' ); //Company Zip Code Extension $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //EIN $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 25, 'AN' ); //Blank break; case 'ks': //Kansas - https://www.ksrevenue.org/pdf/K-2MT.pdf $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //(197-202)[6]: Reporting Period $line[] = $this->padRecord( '', 11, 'N' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'N' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->$l15_state_id ), 20, 'AN' ); //(248-267)[20]: State Employer Account Number $line[] = $this->padRecord( '', 6, 'AN' ); //(268-273)[6]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( '', 10, 'AN' ); //(298-307)[10]: Other State Data $line[] = $this->padRecord( '', 1, 'AN' ); //(308)[1]: Tax Type Code [C=City, D=County, E=School District, F=Other] $line[] = $this->padRecord( $this->removeDecimal( $this->$l18 ), 11, 'N' ); //(309-319)[11]: Local Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l19 ), 11, 'N' ); //(320-330)[11]: Local Income Tax $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_control_number ), 7, 'AN' ); //(331-337)[7]: State Control Number $line[] = $this->padRecord( $this->removeDecimal( $this->getL14AmountByName( 'KPER' ) ), 11, 'N' ); //(338-348)[11]: KS: Employee Contribution to KPERS, KP & F and Judges - "KPER" or "KPERS" should appear on W2 under Box 14. - https://www.ksrevenue.org/kpers.html $line[] = $this->padRecord( '', 64, 'AN' ); //(349-412)[64]: Supplemental Data 1 $line[] = $this->padRecord( '', 75, 'AN' ); //(413-487)[75]: Supplemental Data 2 $line[] = $this->padRecord( '', 25, 'AN' ); //(488-512)[25]: Blank break; case 'ma': //Massachusetts //Withholding Number for State format is the State ID number. $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //(197-202)[6]: Reporting Period $line[] = $this->padRecord( '', 11, 'AN' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'AN' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( '', 20, 'AN' ); //(248-267)[20]: State Employer Account Number $line[] = $this->padRecord( '', 6, 'AN' ); //(268-273)[6]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( '', 10, 'AN' ); //(298-307)[10]: Other State Data $line[] = $this->padRecord( '', 1, 'AN' ); //(308)[1]: Tax Type Code [C=City, D=County, E=School District, F=Other] $line[] = $this->padRecord( $this->removeDecimal( $this->$l18 ), 11, 'N' ); //(309-319)[11]: Local Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l19 ), 11, 'N' ); //(320-330)[11]: Local Income Tax $line[] = $this->padRecord( '', 7, 'AN' ); //(331-337)[7]: State Control Number $line[] = $this->padRecord( '', 75, 'AN' ); //(338-412)[75]: Supplemental Data 1 $line[] = $this->padRecord( '', 75, 'AN' ); //(413-487)[75]: Supplemental Data 2 $line[] = $this->padRecord( '', 25, 'AN' ); //(488-512)[25]: Blank break; case 'oh': //Ohio - They share with Federal SSA. This is for RITA/Local format instead. It does not include school district taxes. //File format specifications: https://www.tax.ohio.gov/Portals/0/employer_withholding/2019%20tax%20year/2018_W2_Specs_v3.pdf //Ohio Regional for City reporting. //File format specifications: https://www.ritaohio.com/Media/701193/2020%20W-2%20SPECS.pdf // List of codes and tax rates: https://ritaohio.com/TaxRatesTable $municipality_code = false; $municipality_name = null; $municipality_tax_type = 'C'; //District/City Name must contain: [NNNA] or [NNNNA] ie: [123R] or [1234R] or [123C] -- Where R is tax based on residence location and C is tax based on work location. $municipality_match = preg_match( '/\[([0-9]{3,4})([RCDEF]{1})\]/i', $this->$l20, $matches ); if ( isset( $matches[0] ) ) { if ( isset( $matches[1] ) ) { $municipality_code = str_pad( trim( $matches[1] ), 4, '0', STR_PAD_LEFT ); } if ( isset( $matches[2] ) ) { $municipality_tax_type = trim( $matches[2] ); } } $municipality_name = strtoupper( trim( preg_replace( '/\[.*\]/', '', $this->$l20 ) ) ); //Strip off the square brackets [] if ( $municipality_code != '' && $municipality_tax_type != '' ) { //Withholding Number for State format is the State ID number. $line[] = 'RS'; //RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //State Code $line[] = $this->padRecord( 'R' . $municipality_code, 5, 'AN' ); //Tax Entity Code (Leave Blank) [5-9] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //SSN [10-18] $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //Zip $line[] = $this->padRecord( '', 4, 'AN' ); //Zip Extension [146-149] $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( '', 23, 'AN' ); //Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //Country, fill with blanks if its the US //Unemployment reporting: Starts at 194 $line[] = $this->padRecord( '', 2, 'AN' ); //Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //Reporting Period $line[] = $this->padRecord( '', 11, 'N' ); //State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'N' ); //State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 20, 'N' ); //State Employer Account Number $line[] = $this->padRecord( '', 6, 'AN' ); //Blank //Income Tax Reporting: Starts at 273 $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //State Code [273-275] $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //State Taxable Wages [276-286] $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //State income tax [287-297] $line[] = $this->padRecord( '', 10, 'AN' ); //Other State Data [298-307] $line[] = $this->padRecord( strtoupper( $municipality_tax_type ), 1, 'AN' ); //Tax Type Code [308] //C=City, D=County, E=School District, F=Other -- For City: R=Residence C=Company/Work Location $line[] = $this->padRecord( $this->removeDecimal( $this->$l18 ), 11, 'N' ); //Local Wages [309-319] $line[] = $this->padRecord( $this->removeDecimal( $this->$l19 ), 11, 'N' ); //Local Income Tax [320-330] $line[] = $this->padRecord( '', 7, 'AN' ); //State Control Number if ( isset( $this->efile_agency_id ) && $this->efile_agency_id == '30:US:OH:00:0010' ) { $line[] = $this->padRecord( $municipality_name, 75, 'AN' ); //Supplemental Data 1 $line[] = $this->padRecord( strtoupper( $this->_getStateName( $this->$l15_state ) ), 75, 'AN' ); //Supplemental Data 2 } else { $line[] = $this->padRecord( '', 75, 'AN' ); //Supplemental Data 1 $line[] = $this->padRecord( '', 75, 'AN' ); //Supplemental Data 2 } $line[] = $this->padRecord( '', 25, 'AN' ); //Blank } else { Debug::Text( 'Skipping RS Record due to incorrect Municipality Code: ' . $municipality_code . ' Tax Type: ' . $municipality_tax_type .' String: '. $this->$l20, __FILE__, __LINE__, __METHOD__, 10 ); } break; case 'ok': //https://www.ok.gov/tax/documents/What%20is%20the%20purpose%20of%20the%20RS.pdf $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //(197-202)[6]: Reporting Period $line[] = $this->padRecord( '', 11, 'AN' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'AN' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( '', 20, 'AN' ); //(248-267)[20]: UI: State Employer Account Number $line[] = $this->padRecord( '', 6, 'AN' ); //(268-273)[6]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( '', 10, 'AN' ); //(298-307)[10]: Other State Data $line[] = $this->padRecord( '', 1, 'AN' ); //(308)[1]: Tax Type Code [C=City, D=County, E=School District, F=Other] $line[] = $this->padRecord( $this->removeDecimal( $this->$l18 ), 11, 'N' ); //(309-319)[11]: Local Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l19 ), 11, 'N' ); //(320-330)[11]: Local Income Tax $line[] = $this->padRecord( '', 7, 'AN' ); //(331-337)[7]: State Control Number $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 15, 'AN' ); //(338-352)[15]: OK: Oklahoma withholding (WTH) Account Number $line[] = $this->padRecord( '', 60, 'AN' ); //(353-412)[60]: Supplemental Data 1 $line[] = $this->padRecord( '', 75, 'AN' ); //(413-487)[75]: Supplemental Data 2 $line[] = $this->padRecord( '', 25, 'AN' ); //(488-512)[25]: Blank break; case 'or': //https://www.oregon.gov/dor/programs/businesses/Documents/iWire-w2-specifications.pdf $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //(197-202)[6]: Reporting Period $line[] = $this->padRecord( '', 11, 'AN' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'AN' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'N' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'N' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 20, 'N' ); //(248-267)[20]: State Employer Account Number $line[] = $this->padRecord( '', 6, 'AN' ); //(268-273)[6]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( '', 50, 'AN' ); //(298-347)[50]: OR: Other State Data $line[] = $this->padRecord( $this->removeDecimal( $this->$l18 ), 11, 'N' ); //(348-358)[11]: Statewide Transit Tax Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l19 ), 11, 'N' ); //(359-369)[11]: Statewide Transit Tax Income Tax Withheld $line[] = $this->padRecord( '', 143, 'AN' ); //(370-512)[143]: Blank break; case 'pa': //https://www.revenue.pa.gov/TaxTypes/EmployerWithholding/Documents/EFW2-EFW2C_reporting_inst_and_specs.pdf $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //(197-202)[6]: Reporting Period $line[] = $this->padRecord( '', 11, 'N' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'N' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 8, 'N' ); //(248-255)[8]: State Employer Account Number $line[] = $this->padRecord( '', 12, 'AN' ); //(256-267)[12]: Blank $line[] = $this->padRecord( '', 6, 'AN' ); //(268-273)[6]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( '', 10, 'AN' ); //(298-307)[10]: Other State Data $line[] = $this->padRecord( '', 1, 'AN' ); //(308)[1]: Tax Type Code [C=City, D=County, E=School District, F=Other] $line[] = $this->padRecord( $this->removeDecimal( $this->$l18 ), 11, 'N' ); //(309-319)[11]: Local Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l19 ), 11, 'N' ); //(320-330)[11]: Local Income Tax $line[] = $this->padRecord( '', 7, 'AN' ); //(331-337)[7]: State Control Number $line[] = $this->padRecord( 0, 9, 'N' ); //(338-346)[9]: Employees ITIN as shown on card issued by SSA $line[] = $this->padRecord( '', 166, 'AN' ); //(347-512)[166]: Blank break; case 'in': // Indiana - Has Local Taxes - https://www.in.gov/dor/files/w-2book.pdf $municipality_code = false; $municipality_name = null; $municipality_tax_type = 'D'; //D=County //District/City Name must contain: [NN] ie: [99] $municipality_match = preg_match( '/\[([0-9]{2})\]/i', $this->$l20, $matches ); if ( isset( $matches[0] ) ) { if ( isset( $matches[1] ) ) { $municipality_code = str_pad( trim( $matches[1] ), 2, '0', STR_PAD_LEFT ); } if ( isset( $matches[2] ) ) { $municipality_tax_type = trim( $matches[2] ); } } $municipality_name = strtoupper( trim( preg_replace( '/\[.*\]/', '', $this->$l20 ) ) ); //Strip off the square brackets [] if ( $municipality_code != '' && $municipality_tax_type != '' ) { $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //(197-202)[6]: Reporting Period $line[] = $this->padRecord( '', 11, 'N' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'N' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 20, 'N' ); //(248-267)[20]: State Employer Account Number $line[] = $this->padRecord( '', 6, 'AN' ); //(268-273)[6]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( '', 8, 'AN' ); //(298-305)[8]: Other State Data $line[] = $this->padRecord( $municipality_code, 2, 'N' ); //(306-307)[2]: County Code (numeric) See Appendix A. $line[] = $this->padRecord( strtoupper( $municipality_tax_type ), 1, 'AN' ); //(308)[1]: Tax Type Code [C=City, D=County, E=School District, F=Other] $line[] = $this->padRecord( $this->removeDecimal( $this->$l18 ), 11, 'N' ); //(309-319)[11]: Local Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l19 ), 11, 'N' ); //(320-330)[11]: Local Income Tax $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 10, 'N' ); //(331-340)[10]: IN: Indiana Employer Taxpayer ID (TID). Does not include the 3 digit location. $line[] = $this->padRecord( $this->stripNonNumeric( substr( $this->$l15_state_id, -3 ) ), 3, 'N' ); //(341-343)[3]: IN: Indiana Employer Taxpayer ID (TID) Location. Last 3 digits of the State ID. $line[] = $this->padRecord( '', 169, 'AN' ); //(444-512)[169]: Blank } else { Debug::Text( 'Skipping RS Record due to incorrect Municipality Code: ' . $municipality_code . ' Tax Type: ' . $municipality_tax_type .' String: '. $this->$l20, __FILE__, __LINE__, __METHOD__, 10 ); } break; case 'ia': if ( strtolower( $this->efile_state ) == 'ia' ) { //Since we don't use a break below, ensure we aren't running this code for other states. $this->$l15_state_id = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_id ), 20, 'N' ); //Must be right justified and zero filled. } //No break here, as we are just modifying some input data into the standard federal format. case 'ky': //https://revenue.ky.gov/Business/PublishingImages/Pages/Employer-Payroll-Withholding/Magnetic%20Media%20Specs%202021.pdf if ( strtolower( $this->efile_state ) == 'ky' ) { //Since we don't use a break below, ensure we aren't running this code for other states. //Only one RS record per state in KY. The local wages/taxes are optional. So we can just exclude any RS record without state income tax wages, and include local or not. // See FAQ of KY EFW2 format specifications. // The Kentucky Department of Revenue does not require that you report the local tax information; // therefore, the RS record that contains ONLY local tax information can be deleted. Make certain // that the RS record that remains in your file is the RS record that contains the state information. // There can only be one RS record with the same state code per RW record in your file if ( isset( $this->efile_agency_id ) && substr( $this->efile_agency_id, 0, 2 ) == '30' ) { //Local Agency //Handle State specific formats here. } else { //State Agency //Always include the first State record ('a'), only ignore ('b' -> 'z' ) if they don't have state wages/tax. if ( $id != 'a' && empty( (float)$this->$l16 ) && empty( (float)$this->$l17 ) ) { Debug::Text( 'Skipping RS Record due to no state wages or income tax...', __FILE__, __LINE__, __METHOD__, 10 ); return null; } //Clear out Local Wages/Tax as they are not required for state filing. $this->$l18 = 0; $this->$l19 = 0; } } //No break here, as we use the federal format mostly. default: //Federal //Withholding Number for State format is the State ID number. $line[] = 'RS'; //(1-2)[2]: RS Record $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( '', 5, 'AN' ); //(5-9)[5]: Tax Entity Code [Leave Blank] $line[] = $this->padRecord( $this->stripNonNumeric( $this->ssn ), 9, 'N' ); //(10-18)[9]: SSN $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->first_name ), 15, 'AN' ); //(19-33)[15]: First Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->middle_name ), 15, 'AN' ); //(34-48)[15]: Middle Name $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->last_name ), 20, 'AN' ); //(49-68)[20]: Last Name $line[] = $this->padRecord( '', 4, 'AN' ); //(69-72)[4]: Suffix $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address2 ), 22, 'AN' ); //(73-94)[22]: Location Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->address1 ), 22, 'AN' ); //(95-116)[22]: Delivery Address $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->city ), 22, 'AN' ); //(117-138)[22]: City $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->state ), 2, 'AN' ); //(139-140)[2]: State $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->zip_code ), 5, 'AN' ); //(141-145)[5]: Zip $line[] = $this->padRecord( '', 4, 'AN' ); //(146-149)[4]: Zip Extension $line[] = $this->padRecord( '', 5, 'AN' ); //(150-154)[5]: Blank $line[] = $this->padRecord( '', 23, 'AN' ); //(155-177)[23]: Foreign State/Province $line[] = $this->padRecord( '', 15, 'AN' ); //(178-192)[15]: Foreign Postal Code $line[] = $this->padRecord( '', 2, 'AN' ); //(193-194)[2]: Country, fill with blanks if its the US //Unemployment reporting $line[] = $this->padRecord( '', 2, 'AN' ); //(195-196)[2]: Optional Code $line[] = $this->padRecord( '', 6, 'AN' ); //(197-202)[6]: Reporting Period $line[] = $this->padRecord( '', 11, 'N' ); //(203-213)[11]: State Quarterly Unemployment Total $line[] = $this->padRecord( '', 11, 'N' ); //(214-224)[11]: State Quarterly Unemployment Insurance $line[] = $this->padRecord( '', 2, 'AN' ); //(225-226)[2]: Number of weeks worked $line[] = $this->padRecord( '', 8, 'AN' ); //(227-234)[8]: Date first employed $line[] = $this->padRecord( '', 8, 'AN' ); //(235-242)[8]: Date of separation $line[] = $this->padRecord( '', 5, 'AN' ); //(243-247)[5]: Blank $line[] = $this->padRecord( $this->stripNonAlphaNumeric( $this->$l15_state_id ), 20, 'AN' ); //(248-267)[20]: State Employer Account Number $line[] = $this->padRecord( '', 6, 'AN' ); //(268-273)[6]: Blank //Income Tax Reporting $line[] = $this->padRecord( $this->_getStateNumericCode( $this->$l15_state ), 2, 'N' ); //(274-275)[2]: State Code $line[] = $this->padRecord( $this->removeDecimal( $this->$l16 ), 11, 'N' ); //(276-286)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l17 ), 11, 'N' ); //(287-297)[11]: State income tax $line[] = $this->padRecord( '', 10, 'AN' ); //(298-307)[10]: Other State Data $line[] = $this->padRecord( '', 1, 'AN' ); //(308)[1]: Tax Type Code [C=City, D=County, E=School District, F=Other] $line[] = $this->padRecord( $this->removeDecimal( $this->$l18 ), 11, 'N' ); //(309-319)[11]: Local Wages $line[] = $this->padRecord( $this->removeDecimal( $this->$l19 ), 11, 'N' ); //(320-330)[11]: Local Income Tax $line[] = $this->padRecord( $this->stripNonNumeric( $this->$l15_state_control_number ), 7, 'AN' ); //(331-337)[7]: State Control Number $line[] = $this->padRecord( '', 75, 'AN' ); //(338-412)[75]: Supplemental Data 1 $line[] = $this->padRecord( '', 75, 'AN' ); //(413-487)[75]: Supplemental Data 2 $line[] = $this->padRecord( '', 25, 'AN' ); //(488-512)[25]: Blank break; } if ( isset( $line ) ) { $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RS Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RS Record: ' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } else { Debug::Text( 'Skipping RS Record... ', __FILE__, __LINE__, __METHOD__, 10 ); } } function _compileRO() { //RO (Employee Optional) if ( in_array( strtoupper( $this->efile_state ), [ 'NY', 'AL', 'CO', 'CT', 'DE', 'KS', 'MA', 'PA', 'VA' ] ) ) { //Skip for eFiling in these states. return false; } $line[] = 'RO'; //Employee Optional $line[] = $this->padRecord( '', 9, 'AN' ); //Blanks $line[] = $this->padRecord( $this->removeDecimal( $this->l8 ), 11, 'N' ); //(12-22) Allocated Tips $line[] = $this->padRecord( $this->removeDecimal( bcadd( $this->_getL12AmountByCode( 'A' ), $this->_getL12AmountByCode( 'B' ) ) ), 11, 'N' ); //(23-33) Uncollected Employee Tax on Tips (Codes A and B) $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'R' ) ), 11, 'N' ); //(34-44) Medical Savings Account (Code R) $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'S' ) ), 11, 'N' ); //(45-55) Simple Retirement Account (Code S) $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'T' ) ), 11, 'N' ); //(56-66) Qualified Adoption Expenses (Code T) $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'M' ) ), 11, 'N' ); //(67-77) Uncollected Social Security or RRTA Tax on Cost ofGroup Term Life Insurance Over $50,000 (Code M) $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'N' ) ), 11, 'N' ); //(78-88) Uncollected Medicare Tax on Cost of Group TermLife Insurance Over$50,000 (Code N) $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'Z' ) ), 11, 'N' ); //(89-99) Income Under a NonqualifiedDeferredCompensation PlanThat Fails to SatisfySection 409A (Code Z) $line[] = $this->padRecord( '', 11, 'AN' ); //(100-110) Blank $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'EE' ) ), 11, 'N' ); //(111-121) Designated Roth Contributions Under a Governmental Section 457(b) Plan (Code EE) $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'GG' ) ), 11, 'N' ); //(122-132) Income from Qualified Equity Grants Under Section 83(i) (Code GG) $line[] = $this->padRecord( $this->removeDecimal( $this->_getL12AmountByCode( 'HH' ) ), 11, 'N' ); //(133-143) Aggregate Deferrals Under Section 83(i) Elections as of theClose of the CalendarYear (Code HH) $line[] = $this->padRecord( '', 131, 'AN' ); //(144-274) Blank $line[] = $this->padRecord( 0, 11, 'N' ); //(275-285) Wages Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 11, 'N' ); //(286-296) Commissions Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 11, 'N' ); //(297-307) Allowances Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 11, 'N' ); //(308-318) Tips Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 11, 'N' ); //(319-329) Total Wages, Commissions, Tips and Allowances Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 11, 'N' ); //(330-340) Puerto Rico Tax Withheld $line[] = $this->padRecord( 0, 11, 'N' ); //(341-351) Retirement Fund Annual Contributions $line[] = $this->padRecord( '', 11, 'AN' ); //(352-362) Blank $line[] = $this->padRecord( 0, 11, 'N' ); //(363-373) Total Wages, Tips and Other Compensation Subject to Virgin Islands, Guam, American Samoa or Northern Mariana Islands Income Tax $line[] = $this->padRecord( 0, 11, 'N' ); //(374-384) Virgin Islands, Guam, American Samoa or Northern Mariana Islands Income Tax Withheld $line[] = $this->padRecord( '', 128, 'AN' ); //Blank $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RO Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RO Record:' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } function _compileRU( $total ) { //RU (Total Optional) Record if ( in_array( strtoupper( $this->efile_state ), [ 'AL', 'CO', 'CT', 'DE', 'KS', 'MA', 'PA', 'VA' ] ) ) { //Skip for eFiling in these states. return false; } $line[] = 'RU'; //Employee Optional $line[] = $this->padRecord( $total->total, 7, 'N' ); //(3-9) Total Number of RO Records switch ( strtolower( $this->efile_state ) ) { case 'ny': $line[] = $this->padRecord( '', 503, 'AN' ); //(10-512) Blank break; default: $line[] = $this->padRecord( $this->removeDecimal( $total->l8 ), 15, 'N' ); //(10-24) Total Allocated Tips $line[] = $this->padRecord( $this->removeDecimal( bcadd( $total->l12a, $total->l12b ) ), 15, 'N' ); //(25-39) Total Uncollected Employee Tax on Tips (Codes A and B) $line[] = $this->padRecord( $this->removeDecimal( $total->l12r ), 15, 'N' ); //(40-54) Total Medica Savings Account (Code R) $line[] = $this->padRecord( $this->removeDecimal( $total->l12s ), 15, 'N' ); //(55-69) Total Simpl Retirement Account (Code S) $line[] = $this->padRecord( $this->removeDecimal( $total->l12t ), 15, 'N' ); //(70-84) Total Qualified Adoption Expenses (Code T) $line[] = $this->padRecord( $this->removeDecimal( $total->l12m ), 15, 'N' ); //(85-99) Total Uncollected Social Security or RRTA Tax on Cost of Group Term Life Insurance Over $50,000 (Code M) $line[] = $this->padRecord( $this->removeDecimal( $total->l12n ), 15, 'N' ); //(100-114) Total Uncollected Medicare Tax on Cost of Group Term Life Insurance Over $50,000 (Code N) $line[] = $this->padRecord( $this->removeDecimal( $total->l12z ), 15, 'N' ); //(115-129) Total Income Under a Nonqualified Deferred Compensation Plan That Fails to Satisfy Section 409A (Code Z) $line[] = $this->padRecord( '', 15, 'AN' ); //(130-144) Blank $line[] = $this->padRecord( $this->removeDecimal( $total->l12ee ), 15, 'N' ); //(145-159) Total Designated Roth Contributions Under a Governmental Section 457(b) Plan (Code EE) $line[] = $this->padRecord( $this->removeDecimal( $total->l12gg ), 15, 'N' ); //(160-174) Total Income from Qualified Equity Grants Under Section 83(i) (Code GG) $line[] = $this->padRecord( $this->removeDecimal( $total->l12hh ), 15, 'N' ); //(175-189) Total Aggregate Deferrals Under Section 83(i) Elections as of the Close of the Calendar Year(Code HH) $line[] = $this->padRecord( '', 165, 'AN' ); //(190-354) Blank $line[] = $this->padRecord( 0, 15, 'N' ); //(355-369) Wages Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 15, 'N' ); //(370-384) Commissions Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 15, 'N' ); //(385-399) Allowances Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 15, 'N' ); //(400-414) Tips Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 15, 'N' ); //(415-429) Total Wages, Commissions, Tips and Allowances Subject to Puerto Rico Tax $line[] = $this->padRecord( 0, 15, 'N' ); //(430-444) Puerto Rico Tax Withheld $line[] = $this->padRecord( 0, 15, 'N' ); //(445-459) Retirement Fund Annual Contributions $line[] = $this->padRecord( 0, 15, 'N' ); //(460-474) Total Wages, Tips and Other Compensation Subject to Virgin Islands, Guam, American Samoa or Northern Mariana Islands Income Tax $line[] = $this->padRecord( 0, 15, 'N' ); //(475-489) Virgin Islands, Guam, American Samoa or Northern Mariana Islands Income Tax Withheld $line[] = $this->padRecord( '', 23, 'AN' ); //(490-512) Blank break; } $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RU Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RU Record:' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } function _compileRT( $total ) { //RT (Total) Record - Total number of RW records reported since the last RE (Employer) record. if ( in_array( strtoupper( $this->efile_state ), [ 'NY', 'AL', 'CO', 'DE', 'PA', 'VA' ] ) ) { //Skip for eFiling in these states. return false; } $line[] = 'RT'; //(1-2)[2]: RT Record switch ( strtolower( $this->efile_state ) ) { case 'ct': $line[] = $this->padRecord( $total->total, 7, 'N' ); //(3-9)[7]: Total RS records. $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 15, 'N' ); //(10-24)[15]: CT: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 15, 'N' ); //(25-39)[15]: CT: State Tax Withheld $line[] = $this->padRecord( '', 473, 'AN' ); //(40-512)[473]: Blank break; case 'ma': $line[] = $this->padRecord( $total->total, 7, 'N' ); //(3-9)[7]: Total RS records. $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 15, 'N' ); //(10-24)[15]: MA: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 15, 'N' ); //(25-39)[15]: MA: State Tax Withheld $line[] = $this->padRecord( '', 473, 'AN' ); //(40-512)[473]: Blank break; default: $line[] = $this->padRecord( $total->total, 7, 'N' ); //(3-9)[7]: Total RW records. $line[] = $this->padRecord( $this->removeDecimal( $total->l1 ), 15, 'N' ); //(10-24)[15]: Wages, Tips and Other Compensation $line[] = $this->padRecord( $this->removeDecimal( $total->l2 ), 15, 'N' ); //(25-39)[15]: Federal Income Tax $line[] = $this->padRecord( $this->removeDecimal( $total->l3 ), 15, 'N' ); //(40-54)[15]: Social Security Wages $line[] = $this->padRecord( $this->removeDecimal( $total->l4 ), 15, 'N' ); //(55-69)[15]: Social Security Tax $line[] = $this->padRecord( $this->removeDecimal( $total->l5 ), 15, 'N' ); //(70-84)[15]: Medicare Wages and Tips $line[] = $this->padRecord( $this->removeDecimal( $total->l6 ), 15, 'N' ); //(85-99)[15]: Medicare Tax $line[] = $this->padRecord( $this->removeDecimal( $total->l7 ), 15, 'N' ); //(100-114)[15]: Social Security Tips $line[] = $this->padRecord( '', 15, 'AN' ); //(115-129)[15]: Blank $line[] = $this->padRecord( $this->removeDecimal( $total->l10 ), 15, 'N' ); //(130-144)[15]: Dependant Care Benefits $line[] = $this->padRecord( $this->removeDecimal( $total->l12d ), 15, 'N' ); //(145-159)[15]: Deferred Compensation Contributions to 401K (Code D) $line[] = $this->padRecord( $this->removeDecimal( $total->l12e ), 15, 'N' ); //(160-174)[15]: Deferred Compensation Contributions to 403(b) (Code E) $line[] = $this->padRecord( $this->removeDecimal( $total->l12f ), 15, 'N' ); //(175-189)[15]: Deferred Compensation Contributions to 408(k)(6) (Code F) $line[] = $this->padRecord( $this->removeDecimal( $total->l12g ), 15, 'N' ); //(190-204)[15]: Deferred Compensation Contributions to 457(b) (Code G) $line[] = $this->padRecord( $this->removeDecimal( $total->l12h ), 15, 'N' ); //(205-219)[15]: Deferred Compensation Contributions to 501(c)(18)(D) (Code H) $line[] = $this->padRecord( '', 15, 'AN' ); //(220-234)[15]: Blank $line[] = $this->padRecord( $this->removeDecimal( $total->l11 ), 15, 'N' ); //(235-249)[15]: Non-qualified Plan Section 457 $line[] = $this->padRecord( $this->removeDecimal( $total->l12w ), 15, 'N' ); //(250-264)[15]: Employer Contributions to Health Savings Account (Code W) $line[] = $this->padRecord( 0, 15, 'N' ); //(265-279)[15]: Non-qualified NOT Plan Section 457 $line[] = $this->padRecord( $this->removeDecimal( $total->l12q ), 15, 'N' ); //(280-294)[15]: Non taxable combat pay (Code Q) $line[] = $this->padRecord( $this->removeDecimal( $total->l12dd ), 15, 'N' ); //(295-309)[15]: Cost of Employer Sponsored Health Coverage (Code DD) $line[] = $this->padRecord( $this->removeDecimal( $total->l12c ), 15, 'N' ); //(310-324)[15]: Employer Cost of Premiums for Group Term Life Insurance over $50K (Code C) $line[] = $this->padRecord( 0, 15, 'N' ); //(325-339)[15]: 3rd party sick pay. $line[] = $this->padRecord( $this->removeDecimal( $total->l12v ), 15, 'N' ); //(340-354)[15]: Income from the Exercise of Nonstatutory Stock Options (Code V) $line[] = $this->padRecord( $this->removeDecimal( $total->l12y ), 15, 'N' ); //(355-369)[15]: Deferrals Under a Section 409A non-qualified plan (Code Y) $line[] = $this->padRecord( $this->removeDecimal( $total->l12aa ), 15, 'N' ); //(370-384)[15]: Desiginated Roth Contributions under a section 401K (Code AA) $line[] = $this->padRecord( $this->removeDecimal( $total->l12bb ), 15, 'N' ); //(385-399)[15]: Desiginated Roth Contributions under a section 403B (Code BB) $line[] = $this->padRecord( $this->removeDecimal( $total->l12ff ), 15, 'N' ); //(400-414)[15]: Permitted Benefits Under a Qualified Small Employer Health Reimbursement (Code FF) $line[] = $this->padRecord( '', 98, 'AN' ); //(415-512)[98]: Blank break; } $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RT Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RT Record:' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } function _compileRV( $total ) { //RV (State Total) Record - **OPTIONAL** Not processed or shared by SSA or IRS. Custom to each state. if ( $this->efile_state == '' ) { //Federal filing does not need any RS record at all. return false; } if ( $this->efile_state == '' || !in_array( strtoupper( $this->efile_state ), [ 'IA', 'ID', 'IL', 'MO', 'MT', 'ND', 'NE', 'OK', 'OR', 'PA' ] ) ) { //**THIS IS OPPOSITE AS OTHER FUNCTIONS** - Skip for eFiling in these states. return false; } if ( $total->total > 0 ) { $line[] = 'RV'; //RT Record switch ( strtolower( $this->efile_state ) ) { case 'ia': //https://tax.iowa.gov/sites/default/files/2020-09/2020_ElectronicReportingofWageandTaxStatements_Pulication_44082.pdf $line[] = $this->padRecord( $total->total, 7, 'N' ); //(3-9)[2]: Total RS records. $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 15, 'N' ); //(10-24)[15]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 15, 'N' ); //(25-39)[15]: State Income Tax Withheld $line[] = $this->padRecord( $this->stripNonNumeric( $this->state_secondary_id ), 8, 'N' ); //(40-47)[8]: IA: Employers BEN (Business eFile Number) $line[] = $this->padRecord( 0, 10, 'N' ); //(48-57)[10]: IA: Confirmation Number (All Zeros) $line[] = $this->padRecord( '', 455, 'AN' ); //(58-512)[455]: Blank break; case 'id': //https://tax.idaho.gov/pubs/EPB00668_12-22-2021.pdf **NOTE: ID "TAP" online efiling has a tool for employers to generate the RV record, with a screenshot on Page 13. $state_income_tax_payments = $total->state_income_tax; $state_tax_due = bcsub( $total->state_income_tax, $state_income_tax_payments ); $state_filing_cycle = 'M'; if ( isset( $this->state_deposit_frequency ) ) { $agency_frequency_to_state_code = [ 2000 => 'Y', //Annual 3000 => 'Q', //Quarter 4100 => 'M', //Monthly 4200 => 'B', //Semi-Monthly ]; if ( isset( $agency_frequency_to_state_code[$this->state_deposit_frequency] ) ) { $state_filing_cycle = $agency_frequency_to_state_code[$this->state_deposit_frequency]; } } $state_penalty = 0; $state_interest = 0; $state_total_amount_due = bcadd( $state_tax_due, $state_penalty, $state_interest); $federal_state_combined_1099_participant = 0; //0 or 1. $late_filing_penalty = 0; $total_due_with_penalty = bcadd( $state_total_amount_due, $late_filing_penalty ); Debug::Text( ' State Filing Cycle: ' . $state_filing_cycle, __FILE__, __LINE__, __METHOD__, 10 ); $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //(3-11)[9]: FEIN $line[] = $this->padRecord( $this->stripSpaces( $this->stripNonAlphaNumeric( $this->name ) ), 4, 'AN' ); //(12-15)[4]: Control name (4 letters of legal name) $line[] = $this->padRecord( $this->stripNonNumeric( $total->state_id ), 9, 'N' ); //(16-24)[9]: State ID Number $line[] = $this->padRecord( $state_filing_cycle, 1, 'AN' ); //(25-25)[1]: Filing Cycle (M=Monthly, B=SemiMonthly, Q=Quarterly, or Y=Yearly) $line[] = $this->padRecord( '12'.$this->year, 6, 'N' ); //(26-31)[4]: Tax Period (MMYYYY ie: 122020) $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 11, 'N' ); //(32-42)[11]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 11, 'N' ); //(43-53)[11]: State Income Tax Withheld $line[] = $this->padRecord( $this->removeDecimal( $state_income_tax_payments ), 11, 'N' ); //(54-64)[11]: Withholding Payments Made during the year. $line[] = $this->padRecord( 0, 22, 'N' ); //(65-86)[22]: Zero Fill $line[] = $this->padRecord( $this->removeDecimal( $state_tax_due ), 11, 'N' ); //(87-97)[11]: Remaining Tax Due or Refund (Total of Positions "43-53" minus "54-64") $line[] = $this->padRecord( ( $state_tax_due < 0 ) ? '-' : ' ', 1, 'AN' ); //(98-98)[1]: Enter negative sign if there is a refund. $line[] = $this->padRecord( $this->removeDecimal( $state_penalty ), 11, 'N' ); //(99-109)[11]: Penalty on Balance Due $line[] = $this->padRecord( $this->removeDecimal( $state_interest ), 11, 'N' ); //(110-120)[11]: Interest on Balance Due $line[] = $this->padRecord( $this->removeDecimal( $state_total_amount_due ), 11, 'N' ); //(121-131)[11]: Total Amount Due or Refund (Total amounts in positions "87-97" plus positions "99-109" plus positions "110-120") $line[] = $this->padRecord( ( $state_total_amount_due < 0 ) ? '-' : ' ', 1, 'AN' ); //(132-132)[1]: Enter negative sign if there is a refund. $line[] = $this->padRecord( $total->total, 7, 'N' ); //(133-139)[7]: Employer Number of W2's $line[] = $this->padRecord( 0, 7, 'N' ); //(140-146)[7]: Total number of 1099's $line[] = $this->padRecord( $federal_state_combined_1099_participant, 1, 'N' ); //(147-147)[1]: Fed/State Combined 1099 Participant $line[] = $this->padRecord( $total->total, 7, 'N' ); //(148-154)[7]: Total Number of W2 and 1099s (Total positions "133-139" plus positions "140-146") $line[] = $this->padRecord( $this->removeDecimal( $late_filing_penalty ), 11, 'N' ); //(155-165)[11]: Penalty for late filing. $line[] = $this->padRecord( $this->removeDecimal( $total_due_with_penalty ), 11, 'N' ); //(166-176)[11]: Total Due or Refund with Penalty (Total of "121-131" plus "155-165") $line[] = $this->padRecord( ( $total_due_with_penalty < 0 ) ? '-' : ' ', 1, 'AN' ); //(177-177)[1]: Total Due sign. $line[] = $this->padRecord( '', 335, 'AN' ); //(178-512)[335]: Blank break; case 'mo': // https://dor.mo.gov/business/withhold/documents/MissouriAnnualW-2FilingGuidelines.pdf $line[] = $this->padRecord( $this->year, 4, 'N' ); //(3-6)[4]: Tax Year $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //(7-15)[9]: FEIN $line[] = $this->padRecord( $this->stripNonNumeric( $total->state_id ), 8, 'N' ); //(16-23)[8]: State ID Number $line[] = $this->padRecord( $this->trade_name, 57, 'AN' ); //(24-80)[57]: Employer Name $line[] = $this->padRecord( $total->total, 6, 'N' ); //(81-86)[6]: Employer Number of W2's $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 12, 'N' ); //(87-98)[12]: Employer TOtal Tax Withheld as shown on W2s $line[] = $this->padRecord( '', 414, 'AN' ); //(99-512)[414]: Blank break; case 'ok': // https://www.ok.gov/tax/documents/What%20is%20the%20purpose%20of%20the%20RV.pdf $line[] = $this->padRecord( $this->_getStateNumericCode( $total->state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( $total->total, 7, 'N' ); //(5-11)[7]: Total RS records. $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //(12-20)[9]: FEIN $line[] = $this->padRecord( '', 21, 'AN' ); //(21-41)[21]: Blank $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 15, 'N' ); //(42-56)[15]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 15, 'N' ); //(57-71)[15]: State Income Tax Withheld $line[] = $this->padRecord( $this->removeDecimal( $total->local_taxable_wages ), 15, 'N' ); //(72-86)[15]: Local Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->local_income_tax ), 15, 'N' ); //(87-101)[15]: Local Income Tax Withheld $line[] = $this->padRecord( '', 411, 'AN' ); //(102-512)[411]: Blank break; case 'or': // https://www.oregon.gov/dor/programs/businesses/Documents/iWire-w2-specifications.pdf $line[] = $this->padRecord( $total->total, 7, 'N' ); //(3-9)[2]: Total RS records. $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 15, 'N' ); //(10-24)[15]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 15, 'N' ); //(25-39)[15]: State Income Tax Withheld $line[] = $this->padRecord( $this->removeDecimal( $total->local_taxable_wages ), 15, 'N' ); //(40-54)[15]: OR: Statewide Transit Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->local_income_tax ), 15, 'N' ); //(55-69)[15]: OR: Statewide Transit Tax Withheld $line[] = $this->padRecord( '', 443, 'AN' ); //(70-512)[443]: Blank break; case 'pa': // https://www.revenue.pa.gov/GeneralTaxInformation/Tax%20Types%20and%20Information/EmployerWithholding/Documents/EFW2-EFW2C_reporting_inst_and_specs.pdf $line[] = $this->padRecord( $this->_getStateNumericCode( $total->state ), 2, 'N' ); //(3-4)[2]: State Code $line[] = $this->padRecord( $this->year, 4, 'N' ); //(5-8)[4]: Tax Year $line[] = $this->padRecord( $this->stripNonNumeric( $total->state_id ), 8, 'N' ); //(9-16)[8]: PA Employer Account ID $line[] = $this->padRecord( $this->stripNonNumeric( $this->ein ), 9, 'N' ); //(17-25)[9]: Employer Entity ID $line[] = $this->padRecord( $total->total, 7, 'N' ); //(26-32)[7]: Total RS records. $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 15, 'N' ); //(33-47)[15]: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 15, 'N' ); //(48-62)[15]: State Income Tax Withheld $line[] = $this->padRecord( '', 450, 'AN' ); //(63-512)[450]: Blank break; default: //SSA specifications state RV records are optional and not processed or shared anyways. //$retval = false; $line[] = $this->padRecord( $total->total, 7, 'N' ); //Total RW records. $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 15, 'N' ); //State Wages, Tips and Other Compensation $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 15, 'N' ); //State Income Tax $line[] = $this->padRecord( '', 473, 'AN' ); //Blank break; } $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RV Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RV Record:' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } return false; } function _compileRF( $total ) { //RF (Final) Record - Total number of RW (Employee) Records reported on the entire file. if ( in_array( strtoupper( $this->efile_state ), [ 'AL' ] ) ) { //Skip for eFiling in these states. return false; } $line[] = 'RF'; //RF Record switch ( strtolower( $this->efile_state ) ) { case 'ct': $line[] = $this->padRecord( $total->total, 9, 'N' ); //(3-11)[9]: Total RS records. $line[] = $this->padRecord( $this->removeDecimal( $total->state_taxable_wages ), 16, 'N' ); //(12-27)[16]: CT: State Taxable Wages $line[] = $this->padRecord( $this->removeDecimal( $total->state_income_tax ), 16, 'N' ); //(28-43)[16]: CT: State Tax Withheld $line[] = $this->padRecord( '', 469, 'AN' ); //(44-512)[469]: Blank break; case 'ny': case 'pa': $line[] = $this->padRecord( '', 510, 'AN' ); //Blank break; default: $line[] = $this->padRecord( '', 5, 'AN' ); //Blank $line[] = $this->padRecord( $total->total, 9, 'N' ); //Total RW records. $line[] = $this->padRecord( '', 496, 'AN' ); //Blank break; } $retval = implode( ( $this->debug == true ) ? ',' : '', $line ); if ( $this->debug == false && strlen( $retval ) != 512 ) { Debug::Text( 'ERROR! RF Record length is incorrect, should be 512 is: ' . strlen( $retval ), __FILE__, __LINE__, __METHOD__, 10 ); return false; } Debug::Text( 'RF Record:' . $retval, __FILE__, __LINE__, __METHOD__, 10 ); return $retval; } //Fixed length field EFW2 format function _outputEFILE( $type = null ) { /* Submitter Record (RA) Employer Record (RE) Employee Wage Records (RW AND RO) State Wage Record (RS) Total Records (RT and RU) State Total Record (RV) - Page 64 Final Record (RF) Publication 42-007: http://www.ssa.gov/employer/EFW2&EFW2C.htm Download: AccuWage from the bottom of this website for testing: http://www.socialsecurity.gov/employer/accuwage/index.html */ $records = $this->getRecords(); //Debug::Arr($records, 'Output EFILE Records: ',__FILE__, __LINE__, __METHOD__, 10); if ( is_array( $records ) && count( $records ) > 0 ) { $retval = $this->padLine( $this->_compileRA() ); $retval .= $this->padLine( $this->_compileRE() ); $rt_total = Misc::preSetArrayValues( new stdClass(), [ 'total', 'l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l10', 'l11', 'l12c', 'l12d', 'l12e', 'l12f', 'l12g', 'l12h', 'l12w', 'l12q', 'l12v', 'l12y', 'l12aa', 'l12bb', 'l12dd', 'l12ff' ], 0 ); $rw_total = Misc::preSetArrayValues( new stdClass(), [ 'total' ], 0 ); $ro_total = Misc::preSetArrayValues( new stdClass(), [ 'total', 'l8', 'l12a', 'l12b', 'l12r', 'l12s', 'l12t', 'l12m', 'l12n', 'l12z', 'l12ee', 'l12gg', 'l12hh' ], 0 ); $state_total = Misc::preSetArrayValues( new stdClass(), [ 'total', 'state_taxable_wages', 'state_income_tax', 'local_taxable_wages', 'local_income_tax' ], 0 ); $i = 0; foreach ( $records as $w2_data ) { $this->arrayToObject( $w2_data ); //Convert record array to object $compile_rw_retval = $this->padLine( $this->_compileRW() ); if ( $compile_rw_retval != '' ) { $retval .= $compile_rw_retval; $rw_total->total += 1; } $retval .= $this->padLine( $this->_compileRO() ); foreach ( range( 'a', 'z' ) as $z ) { if ( strtolower( $this->{'l15' . $z . '_state'} ) == strtolower( $this->efile_state ) ) { //Only include RS records for the state we are filing for. They are optional for SSA so exclude them federally. $compile_rs_retval = $this->padLine( $this->_compileRS( $z ) ); //This also excludes RS records for other states, but we need make we only consider totals for just this state too. if ( $compile_rs_retval != '' ) { $retval .= $compile_rs_retval; $state_total->total += 1; if ( !isset( $state_total->state ) && !isset( $state_total->state_id ) ) { //This uses the first State ID. $state_total->state = $this->{'l15' . $z . '_state'}; $state_total->state_id = $this->{'l15' . $z . '_state_id'}; } $state_total->state_taxable_wages += $this->{'l16' . $z}; $state_total->state_income_tax += $this->{'l17' . $z}; $state_total->local_taxable_wages += $this->{'l18' . $z}; $state_total->local_income_tax += $this->{'l19' . $z}; } } } $rt_total->total += 1; $rt_total->l1 += $this->l1; $rt_total->l2 += $this->l2; $rt_total->l3 += $this->l3; $rt_total->l4 += $this->l4; $rt_total->l5 += $this->l5; $rt_total->l6 += $this->l6; $rt_total->l7 += $this->l7; $rt_total->l10 += $this->l10; $rt_total->l11 += $this->l11; $rt_total->l12c += $this->_getL12AmountByCode( 'C' ); $rt_total->l12d += $this->_getL12AmountByCode( 'D' ); $rt_total->l12e += $this->_getL12AmountByCode( 'E' ); $rt_total->l12f += $this->_getL12AmountByCode( 'F' ); $rt_total->l12g += $this->_getL12AmountByCode( 'G' ); $rt_total->l12h += $this->_getL12AmountByCode( 'H' ); $rt_total->l12w += $this->_getL12AmountByCode( 'W' ); $rt_total->l12q += $this->_getL12AmountByCode( 'Q' ); $rt_total->l12v += $this->_getL12AmountByCode( 'V' ); $rt_total->l12y += $this->_getL12AmountByCode( 'Y' ); $rt_total->l12aa += $this->_getL12AmountByCode( 'AA' ); $rt_total->l12bb += $this->_getL12AmountByCode( 'BB' ); $rt_total->l12dd += $this->_getL12AmountByCode( 'DD' ); $rt_total->l12ff += $this->_getL12AmountByCode( 'FF' ); $ro_total->total += 1; $ro_total->l8 += $this->l8; $ro_total->l12a += $this->_getL12AmountByCode( 'A' ); $ro_total->l12b += $this->_getL12AmountByCode( 'B' ); $ro_total->l12r += $this->_getL12AmountByCode( 'R' ); $ro_total->l12s += $this->_getL12AmountByCode( 'S' ); $ro_total->l12t += $this->_getL12AmountByCode( 'T' ); $ro_total->l12m += $this->_getL12AmountByCode( 'M' ); $ro_total->l12n += $this->_getL12AmountByCode( 'N' ); $ro_total->l12z += $this->_getL12AmountByCode( 'Z' ); $ro_total->l12ee += $this->_getL12AmountByCode( 'EE' ); $ro_total->l12gg += $this->_getL12AmountByCode( 'GG' ); $ro_total->l12hh += $this->_getL12AmountByCode( 'HH' ); $this->revertToOriginalDataState(); $i++; } if ( in_array( $this->efile_state, [ 'CT', 'MA' ] ) ) { $retval .= $this->padLine( $this->_compileRT( $state_total ) ); //CT uses the RT record like an RV record, showing state totals. } else { $retval .= $this->padLine( $this->_compileRT( $rt_total ) ); } $retval .= $this->padLine( $this->_compileRU( $ro_total ) ); $retval .= $this->padLine( $this->_compileRV( $state_total ) ); //State Total Record if ( in_array( $this->efile_state, [ 'CT', 'MA', 'VA' ] ) ) { $retval .= $this->padLine( $this->_compileRF( $state_total ) ); } else { $retval .= $this->padLine( $this->_compileRF( $rw_total ) ); } } if ( isset( $retval ) ) { return $retval; } return false; } //Gets Line 14 amount by the name associated with that Line. function getL14AmountByName( $name ) { $name = trim( $name ); $retval = 0; if ( $name != '' ) { foreach ( range( 'a', 'd' ) as $z ) { $l14_field = 'l14' . $z; $l14_name_field = 'l14' . $z . '_name'; if ( strtolower( trim( $this->$l14_name_field ) ) == strtolower( $name ) ) { $retval = $this->$l14_field; break; } } } return $retval; } //This takes a single employee record and moves state/locality data from rows c, d, e, f, ... into rows a,b. // Because it changes the data, it can be run multiple times on the same input data. function handleThreeOrMoreStateData( $data ) { //Clear all variables that should be empty when generating multiple W2 forms. (everything except box a thru f) $data['l1'] = null; $data['l2'] = null; $data['l3'] = null; $data['l4'] = null; $data['l5'] = null; $data['l6'] = null; $data['l7'] = null; $data['l8'] = null; $data['l9'] = null; $data['l10'] = null; $data['l11'] = null; $data['l12a'] = null; $data['l12a_code'] = null; $data['l12b'] = null; $data['l12b_code'] = null; $data['l12c'] = null; $data['l12c_code'] = null; $data['l12d'] = null; $data['l12d_code'] = null; $data['l14a'] = null; $data['l14a_name'] = null; $data['l14b'] = null; $data['l14b_name'] = null; $data['l14c'] = null; $data['l14c_name'] = null; $data['l14d'] = null; $data['l14d_name'] = null; $data_changed = false; //Clear all variables for State rows 'a' and 'b' foreach ( range( 'a', 'b' ) as $z ) { //Skip A/B in range, since those are always what we copy the d, c, e, ... data too. $data['l15' . $z . '_state_id'] = null; $data['l15' . $z . '_state'] = null; $data['l16' . $z] = null; $data['l17' . $z] = null; $data['l20' . $z . '_district'] = null; $data['l18' . $z] = null; $data['l19' . $z] = null; } //Copy non-NULL data from rows c, d to rows a, b $destination_position = 'a'; foreach ( range( 'c', 'z' ) as $z ) { //Skip A/B in range, since those are always what we copy the d, c, e, ... data too. if ( !( $data['l15' . $z . '_state_id'] == null && $data['l15' . $z . '_state'] == null && $data['l16' . $z] == null && $data['l17' . $z] == null && $data['l20' . $z . '_district'] == null && $data['l18' . $z] == null && $data['l19' . $z] == null ) ) { Debug::Text( 'Found 3+ State Info, moving to position: ' . $destination_position, __FILE__, __LINE__, __METHOD__, 10 ); $data_changed = true; $data['l15' . $destination_position . '_state_id'] = $data['l15' . $z . '_state_id']; $data['l15' . $destination_position . '_state'] = $data['l15' . $z . '_state']; $data['l16' . $destination_position] = $data['l16' . $z]; $data['l17' . $destination_position] = $data['l17' . $z]; $data['l20' . $destination_position . '_district'] = $data['l20' . $z . '_district']; $data['l18' . $destination_position] = $data['l18' . $z]; $data['l19' . $destination_position] = $data['l19' . $z]; //Clear all variables. $data['l15' . $z . '_state_id'] = null; $data['l15' . $z . '_state'] = null; $data['l16' . $z] = null; $data['l17' . $z] = null; $data['l20' . $z . '_district'] = null; $data['l18' . $z] = null; $data['l19' . $z] = null; $destination_position++; if ( $destination_position == 'c' ) { break; } } } //Clear all variables for Box 12 rows 'a' thru 'd' foreach ( range( 'a', 'd' ) as $z ) { //Skip A thru D in range, since those are always what we copy the e, f, g, ... data too. $data['l14' . $z . '_name'] = null; $data['l14' . $z] = null; } //Copy non-NULL data from rows c, d to rows a, b $destination_position = 'a'; foreach ( range( 'e', 'h' ) as $z ) { //Skip A thru DD in range, since those are always what we copy the e, f, g, ... data too. if ( !( $data['l14' . $z . '_name'] == null && $data['l14' . $z] == null ) ) { Debug::Text( 'Found 4+ Box 14 Info, moving to position: ' . $destination_position, __FILE__, __LINE__, __METHOD__, 10 ); $data_changed = true; $data['l14' . $destination_position . '_name'] = $data['l14' . $z . '_name']; $data['l14' . $destination_position] = $data['l14' . $z]; //Clear all variables. $data['l14' . $z . '_name'] = null; $data['l14' . $z] = null; $destination_position++; if ( $destination_position == 'e' ) { break; } } } //Clear all variables for Box 12 rows 'a' thru 'd' foreach ( range( 'a', 'd' ) as $z ) { //Skip A thru D in range, since those are always what we copy the e, f, g, ... data too. $data['l12' . $z . '_code'] = null; $data['l12' . $z] = null; } //Copy non-NULL data from rows c, d to rows a, b $destination_position = 'a'; foreach ( range( 'e', 'h' ) as $z ) { //Skip A thru DD in range, since those are always what we copy the e, f, g, ... data too. if ( !( $data['l12' . $z . '_code'] == null && $data['l12' . $z] == null ) ) { Debug::Text( 'Found 4+ Box 12 Info, moving to position: ' . $destination_position, __FILE__, __LINE__, __METHOD__, 10 ); $data_changed = true; $data['l12' . $destination_position . '_code'] = $data['l12' . $z . '_code']; $data['l12' . $destination_position] = $data['l12' . $z]; //Clear all variables. $data['l12' . $z . '_code'] = null; $data['l12' . $z] = null; $destination_position++; if ( $destination_position == 'e' ) { break; } } } if ( $data_changed == true ) { return $data; } return false; } //This takes a single employee record that has three or more states/localities and splits them into multiple records to simplify generating the PDFs. function handleMultipleForms( $records ) { $tmp_records = []; if ( is_array( $records ) && count( $records ) > 0 ) { foreach ( $records as $employee_data ) { $tmp_records[] = $employee_data; $tmp_record = $employee_data; do { $tmp_record = $this->handleThreeOrMoreStateData( $tmp_record ); if ( is_array( $tmp_record ) ) { $tmp_records[] = $tmp_record; } } while ( is_array( $tmp_record ) ); } } //**NOTE: If we save these records permanantely in memory, then subsuquent calls to things like serailize() records will not be correct, as the records will all be split, but it will be based on the order of operations. // Instead just return the split records in memory so we never modify the original records. //$this->clearRecords(); //$this->setRecords( $tmp_records ); //return $this->getRecords(); return $tmp_records; } function _outputPDF( $type ) { //Initialize PDF with template. $pdf = $this->getPDFObject(); if ( $this->getShowBackground() == true ) { $pdf->setSourceFile( $this->getTemplateDirectory() . DIRECTORY_SEPARATOR . $this->pdf_template ); for ( $tp = 1; $tp <= 11; $tp++ ) { $this->template_index[$tp] = $pdf->ImportPage( $tp ); } } if ( $this->year == '' ) { $this->year = $this->getYear(); } if ( $this->getType() == 'government' ) { $employees_per_page = 2; $n = 2; //Don't loop the same employee. if ( $this->efile_state != '' ) { //When doing state filing, only include the state copy of the W2. $form_template_pages = [ 3 ]; //Template pages to use. } else { $form_template_pages = [ 2, 3, 10 ]; //Template pages to use. 2=SSA, 3=State, City, Local, 10=Employer } } else { $employees_per_page = 1; $n = 1; //Loop the same employee twice. $form_template_pages = [ 4, 6, 8 ]; //Template pages to use. 4=Employee Federal Return, 6=Employee Records, 8=Employee State, City Local } //Get location map, start looping over each variable and drawing $records = $this->handleMultipleForms( $this->getRecords() ); if ( is_array( $records ) && count( $records ) > 0 ) { $template_schema = $this->getTemplateSchema(); foreach ( $form_template_pages as $key => $form_template_page ) { //Set the template used. $template_schema[0]['template_page'] = $form_template_page; $bottom_template_offset = 380; if ( $this->getShowBackground() == true && $this->getType() == 'government' ) { $template_schema[0]['combine_templates'] = [ [ 'template_page' => $form_template_page, 'x' => 0, 'y' => 0 ], ]; if ( count( $records ) > 1 ) { //Only if more than 1 employee, show both top and bottom forms. $template_schema[0]['combine_templates'][] = [ 'template_page' => $form_template_page, 'x' => 0, 'y' => $bottom_template_offset ]; //Place two templates on the same page. } } else if ( $this->getShowInstructionPage() == true && $this->getType() == 'employee' ) { $template_schema[0]['combine_templates'] = [ [ 'template_page' => $form_template_page, 'x' => 0, 'y' => 0 ], [ 'template_page' => ( $form_template_page + 1 ), 'x' => 0, 'y' => $bottom_template_offset ] //Place two templates on the same page. ]; } $e = 0; foreach ( $records as $employee_data ) { //Debug::Arr($employee_data, 'Employee Data: ', __FILE__, __LINE__, __METHOD__,10); $this->arrayToObject( $employee_data ); //Convert record array to object for ( $i = 0; $i < $n; $i++ ) { $this->setTempPageOffsets( $this->getPageOffsets( 'x' ), $this->getPageOffsets( 'y' ) ); if ( ( $employees_per_page == 1 && $i > 0 ) || ( $employees_per_page == 2 && $e % 2 != 0 ) ) { $this->setTempPageOffsets( $this->getPageOffsets( 'x' ), ( $bottom_template_offset + $this->getPageOffsets( 'y' ) ) ); } foreach ( $template_schema as $field => $schema ) { $this->Draw( $this->$field, $schema ); } } if ( $employees_per_page == 1 || ( $employees_per_page == 2 && $e % $employees_per_page != 0 ) ) { $this->resetTemplatePage(); } $this->revertToOriginalDataState(); $e++; } } } return true; } function _outputXML( $type = null ) { if ( is_object( $this->getXMLObject() ) ) { $xml = $this->getXMLObject(); } else { return false; //No XML object to append too. Needs return1040 form first. } $records = $this->getRecords(); Debug::Arr( $records, 'Output XML Records: ', __FILE__, __LINE__, __METHOD__, 10 ); if ( is_array( $records ) && count( $records ) > 0 ) { $e = 0; foreach ( $records as $w2_data ) { $w2_data['control_number'] = ( $e + 1 ); $this->arrayToObject( $w2_data ); //Convert record array to object $xml->ReturnData->addChild( 'IRSW2' ); $xml->ReturnData->IRSW2[$e]->addAttribute( 'documentId', $this->control_number ); // Must be unique within the return //Corrected W2 Indicator $xml->ReturnData->IRSW2[$e]->addChild( 'CorrectedW2Ind', 'X' ); //Employee SSN if ( empty( $this->ssn ) == false ) { $xml->ReturnData->IRSW2[$e]->addChild( 'EmployeeSSN', $this->stripNonNumeric( $this->ssn ) ); } //Employer EIN $xml->ReturnData->IRSW2[$e]->addChild( 'EmployerEIN', $this->stripNonNumeric( $this->ein ) ); $xml->ReturnData->IRSW2[$e]->addChild( 'EmployerNameControl', substr( strtoupper( $this->trade_name ), 0, 1 ) ); //Employer name $xml->ReturnData->IRSW2[$e]->addChild( 'EmployerName' ); $xml->ReturnData->IRSW2[$e]->EmployerName->addChild( 'BusinessNameLine1', $this->trade_name ); //$xml->EmployerName->addChild('BusinessNameLine2', '' ); //Employer US address $xml->ReturnData->IRSW2[$e]->addChild( 'EmployerUSAddress' ); $xml->ReturnData->IRSW2[$e]->EmployerUSAddress->addChild( 'AddressLine1', $this->stripNonAlphaNumeric( $this->company_address1 ) ); $xml->ReturnData->IRSW2[$e]->EmployerUSAddress->addChild( 'City', $this->company_city ); $xml->ReturnData->IRSW2[$e]->EmployerUSAddress->addChild( 'State', $this->company_state ); $xml->ReturnData->IRSW2[$e]->EmployerUSAddress->addChild( 'ZIPCode', $this->company_zip_code ); //Employer foreign address /* $xml->ReturnData->IRSW2[$e]->addChild('EmployerForeignAddress'); $xml->ReturnData->IRSW2[$e]->EmployerForeignAddress->addChild('AddressLine1', ); $xml->ReturnData->IRSW2[$e]->EmployerForeignAddress->addChild('AddressLine2', ); $xml->ReturnData->IRSW2[$e]->EmployerForeignAddress->addChild('City', ); $xml->ReturnData->IRSW2[$e]->EmployerForeignAddress->addChild('ProvinceOrState', ); $xml->ReturnData->IRSW2[$e]->EmployerForeignAddress->addChild('Country', ); $xml->ReturnData->IRSW2[$e]->EmployerForeignAddress->addChild('PostalCode', ); */ //Control number $xml->ReturnData->IRSW2[$e]->addChild( 'ControlNumber', $this->control_number ); //Employee name $xml->ReturnData->IRSW2[$e]->addChild( 'EmployeeName', $this->first_name . ' ' . $this->last_name ); //EmployeeUS address $xml->ReturnData->IRSW2[$e]->addChild( 'EmployeeUSAddress' ); $xml->ReturnData->IRSW2[$e]->EmployeeUSAddress->addChild( 'AddressLine1', $this->stripNonAlphaNumeric( $this->address1 ) ); $xml->ReturnData->IRSW2[$e]->EmployeeUSAddress->addChild( 'AddressLine2', $this->stripNonAlphaNumeric( $this->address2 ) ); $xml->ReturnData->IRSW2[$e]->EmployeeUSAddress->addChild( 'City', $this->city ); $xml->ReturnData->IRSW2[$e]->EmployeeUSAddress->addChild( 'State', $this->state ); $xml->ReturnData->IRSW2[$e]->EmployeeUSAddress->addChild( 'ZIPCode', $this->zip_code ); //Employee foreign address /* $xml->ReturnData->IRSW2[$e]->addChild('EmployeeForeignAddress'); $xml->ReturnData->IRSW2[$e]->EmployeeForeignAddress->addChild('AddressLine1', ); $xml->ReturnData->IRSW2[$e]->EmployeeForeignAddress->addChild('AddressLine2', ); $xml->ReturnData->IRSW2[$e]->EmployeeForeignAddress->addChild('City', ); $xml->ReturnData->IRSW2[$e]->EmployeeForeignAddress->addChild('ProvinceOrState', ); $xml->ReturnData->IRSW2[$e]->EmployeeForeignAddress->addChild('Country', ); $xml->ReturnData->IRSW2[$e]->EmployeeForeignAddress->addChild('PostalCode', ); */ //Wages amount if ( $this->isNumeric( $this->l1 ) && $this->l1 >= 0 ) { $xml->ReturnData->IRSW2[$e]->addChild( 'WagesAmt', $this->getBeforeDecimal( $this->l1 ) ); } //Withholding amount if ( $this->isNumeric( $this->l2 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'WithholdingAmt', $this->getBeforeDecimal( $this->l2 ) ); } //Social Security wages amount if ( $this->isNumeric( $this->l3 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'SocialSecurityWagesAmt', $this->getBeforeDecimal( $this->l3 ) ); } //Social Security tax amount if ( $this->isNumeric( $this->l4 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'SocialSecurityTaxAmt', $this->getBeforeDecimal( $this->l4 ) ); } //Medicare wages and tips amount if ( $this->isNumeric( $this->l5 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'MedicareWagesAndTipsAmt', $this->getBeforeDecimal( $this->l5 ) ); } //Medicare tax withheld amount if ( $this->isNumeric( $this->l6 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'MedicareTaxWithheldAmt', $this->getBeforeDecimal( $this->l6 ) ); } //Social security tips amount if ( $this->isNumeric( $this->l7 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'SocialSecurityTipsAmt', $this->getBeforeDecimal( $this->l7 ) ); } //Allocated tips amount if ( $this->isNumeric( $this->l8 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'AllocatedTipsAmt', $this->getBeforeDecimal( $this->l8 ) ); } //Dependent care benefits amount if ( $this->isNumeric( $this->l10 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'DependentCareBenefitsAmt', $this->getBeforeDecimal( $this->l10 ) ); } //Nonqualified plans amount if ( $this->isNumeric( $this->l11 ) ) { $xml->ReturnData->IRSW2[$e]->addChild( 'NonqualifiedPlansAmt', $this->getBeforeDecimal( $this->l11 ) ); } $x = 0; foreach ( range( 'a', 'd' ) as $z ) { $code_col = 'l12' . $z . '_code'; $amount_col = 'l12' . $z; if ( empty( $this->$code_col ) == false || empty( $this->$amount_col ) == false ) { $xml->ReturnData->IRSW2[$e]->addChild( 'EmployersUseGrp' ); } //Employer's Use Code if ( empty( $this->$code_col ) == false ) { $xml->ReturnData->IRSW2[$e]->EmployersUseGrp[$x]->addChild( 'EmployersUseCd', (string)$this->$code_col ); } //Employer's Use Amount if ( empty( $this->$amount_col ) == false && $this->isNumeric( $this->$amount_col ) ) { $xml->ReturnData->IRSW2[$e]->EmployersUseGrp[$x]->addChild( 'EmployersUseAmt', $this->getBeforeDecimal( $this->$amount_col ) ); } $x++; } //Statutory Employee Ind if ( empty( $this->l13a ) == false ) { $xml->ReturnData->IRSW2[$e]->addChild( 'StatutoryEmployeeInd', 'X' ); } //Retirement Plan Ind if ( empty( $this->l13b ) == false ) { $xml->ReturnData->IRSW2[$e]->addChild( 'RetirementPlanInd', 'X' ); } //Third-Party Sick Pay Ind if ( empty( $this->l13c ) == false ) { $xml->ReturnData->IRSW2[$e]->addChild( 'ThirdPartySickPayInd', 'X' ); } //Other Deducts/Benefits Cd $x = 0; foreach ( range( 'a', 'd' ) as $z ) { $des_col = 'l14' . $z . '_name'; $amount_col = 'l14' . $z; if ( empty( $this->$des_col ) == false && empty( $this->$amount_col ) == false ) { $xml->ReturnData->IRSW2[$e]->addChild( 'OtherDeductsBenefits' ); $xml->ReturnData->IRSW2[$e]->OtherDeductsBenefits[$x]->addChild( 'Description', $this->$des_col ); $xml->ReturnData->IRSW2[$e]->OtherDeductsBenefits[$x]->addChild( 'Amount', (int)$this->$amount_col ); } $x++; } //W2 State Local Tax Group $x = 0; foreach ( range( 'a', 'z' ) as $z ) { $l15_state = 'l15' . $z . '_state'; $l15_state_id = 'l15' . $z . '_state_id'; $l16 = 'l16' . $z; $l17 = 'l17' . $z; $l18 = 'l18' . $z; $l19 = 'l19' . $z; $l20 = 'l20' . $z . '_district'; if ( empty( $this->$l15_state ) == false || empty( $this->$l15_state_id ) == false || empty( $this->$l16 ) == false || empty( $this->$l17 ) == false || empty( $this->$l18 ) == false || empty( $this->$l19 ) == false || empty( $this->$l20 ) == false ) { $xml->ReturnData->IRSW2[$e]->addChild( 'W2StateLocalTaxGrp' ); $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->addChild( 'W2StateTaxGrp' ); } if ( empty( $this->$l15_state ) == false ) { //State Abbreviation Code $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->W2StateTaxGrp->addChild( 'StateAbbreviationCd', $this->$l15_state ); } if ( empty( $this->$l15_state_id ) == false ) { //Employer's State ID Number $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->W2StateTaxGrp->addChild( 'EmployersStateIdNumber', $this->$l15_state_id ); } if ( empty( $this->$l16 ) == false && $this->isNumeric( $this->$l16 ) ) { //State Wages Amount $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->W2StateTaxGrp->addChild( 'StateWagesAmt', $this->getBeforeDecimal( $this->$l16 ) ); } if ( empty( $this->$l17 ) == false && $this->isNumeric( $this->$l17 ) ) { //State Income Tax Amount $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->W2StateTaxGrp->addChild( 'StateIncomeTaxAmt', $this->getBeforeDecimal( $this->$l17 ) ); } if ( empty( $this->$l18 ) == false || empty( $this->$l19 ) == false || empty( $this->$l20 ) == false ) { $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->W2StateTaxGrp->addChild( 'W2LocalTaxGrp' ); } if ( empty( $this->$l18 ) == false && $this->isNumeric( $this->$l18 ) ) { //Local Wages/Tips Amount $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->W2StateTaxGrp->W2LocalTaxGrp->addChild( 'LocalWagesAndTipsAmt', $this->getBeforeDecimal( $this->$l18 ) ); } if ( empty( $this->$l19 ) == false && $this->isNumeric( $this->$l19 ) ) { //Local Income Tax Amount $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->W2StateTaxGrp->W2LocalTaxGrp->addChild( 'LocalIncomeTaxAmt', $this->getBeforeDecimal( $this->$l19 ) ); } if ( empty( $this->$l20 ) == false && $this->isNumeric( $this->$l20 ) ) { //Name of Locality $xml->ReturnData->IRSW2[$e]->W2StateLocalTaxGrp[$x]->W2StateTaxGrp->W2LocalTaxGrp->addChild( 'NameOfLocality', $this->getBeforeDecimal( $this->$l20 ) ); } $x++; } //Standard or Non Standard Code $xml->ReturnData->IRSW2[$e]->addChild( 'StandardOrNonStandardCd', 'S' ); $this->revertToOriginalDataState(); $e++; } } return true; } } ?>