diff --git a/app/Config/Routes.php b/app/Config/Routes.php index f3ea3138..7070883c 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -203,6 +203,8 @@ $routes->get('deleteLeaveApplicationForm', 'Monthlypay::deleteLeaveApplicationFo $routes->post('validateDateRange', 'Monthlypay::validateDateRange'); $routes->match(['GET', 'POST'], 'leaveApplicationPDF/(:any)', 'Monthlypay::leaveApplicationPDF/$1'); $routes->match(['GET', 'POST'], 'overTimeDetails', 'Monthlypay::overTimeDetails'); +$routes->get('exportMonthlyPayInputs/(:any)', 'Payslip::exportMonthlyPayInputs/$1'); + $routes->get('emppaydate/addemppaydate', 'Emppaydate::addemppaydate'); $routes->post('emppaydate/addNewemppay', 'Emppaydate::addNewemppay'); diff --git a/app/Controllers/Payslip.php b/app/Controllers/Payslip.php index 5d09e9e2..26810657 100755 --- a/app/Controllers/Payslip.php +++ b/app/Controllers/Payslip.php @@ -287,14 +287,7 @@ class Payslip extends BaseController $empSalarySub = $esiAmount + $pfAmount + $loan; $salaryInCurrentday = $empSalaryAdd - $empSalarySub; - // echo $esiAmount .''; - // echo $pfAmount .''; - // echo $loan .''; - // echo $empSalarySub .''; - // echo $empSalaryAdd .''; - // echo $salaryInCurrentday .''; - // die; - + $employeeSalary[] = round($salaryInCurrentday); $esi[] = number_format($esiAmount,2, '.', ''); $pf[] = number_format($pfAmount,2, '.', ''); @@ -309,6 +302,315 @@ class Payslip extends BaseController $this->loadViews("monthlypayinputs", $this->global, $data, NULL); } + public function exportMonthlyPayInputs1($value) + { + $headlines = [ + 'company_name' => 'Resico Solutions', + 'file_name' => 'Resico_Salary_'.$value.'.xls', + 'type' => 1, + 'header1' => ['Emp ID', 'Name', 'Department', 'Salary'], // example headers + 'header2' => [], + 'footer' => false, + ]; + + $xldata = [ + ['E001', 'Arun', 'HR', 25000], + ['E002', 'Meena', 'Finance', 28000], + ]; + + helper('excel'); + generate_excel($headlines, $xldata); + } + + + public function exportMonthlyPayInputs($value){ + + helper('excel'); + $monthyear = get_date_time_dynamical_format('n-Y','m-Y',"$value"); + $employee = [];$i=0; $j=0; + $company_info = $this->payroll_model->getCompanyInformation(); + $employee_monthinputs_info = $this->monthlypay_model->getEmpPayDetailsforMonthInputs($monthyear); + $driver_monthinputs_info = $this->driverMonthlyPayInputs($monthyear); + // $headlines_main = ['S. No','Emp ID','Employees Name','Date of Joining','Destingnation','Total Days' ,'Days Worked','Leave','Basic Salary','Per day Salary','Worked Salary','Per Hours Salary','Earned Salary', '70% BASIC','30% HRA','Gross Salary','Esi 0.75%','Pf 12%','Esi + Pf (Ee`s)' ,'Over Time','Feb-25 Advance','TDS 92B','Refuned PF Nov24','Net Salary','Gross Salary','Over Time','Gross Net Salary','Esi (0)','Pf (0)','Sep-24 Advance','TDS 92B','Refuned PF Nov24','Net Salary','Diff']; + $headlines_main = ['S. No','Emp ID','Employees Name','Date of Joining','Destingnation','Total','Days','Leave','Basic','Per day','Worked','Per Hours','Earned','70%','30%','Gross','Esi','Pf','Esi + Pf','Over Time','Feb-25 Advance','TDS 92B','Refuned PF Nov24','Net Salary','Gross','Over Time','Gross Net','Esi','Pf','Sep-24 Advance','TDS 92B','Refuned PF Nov24','Net Salary','Diff']; + + $headlines_sub = ['', '', '', '', '', 'Days','Worked','', 'Salary','Salary','Salary','Salary','Salary', 'BASIC','HRA','Salary','0.75%','12%','Ee`s','','','','','','Salary','','Salary',' 0','0','','','','','']; + + $dum = []; + foreach ($employee_monthinputs_info as $key => $rec) { + // echo $rec->EmpID; + // print_r($dum);die; + $dum[$rec->EmpID] = $rec; + } + $employee_monthinputs_info = array_values($dum); + + + foreach ($employee_monthinputs_info as $value) { + + $employee[$i]['SNO'] = $i+1; + $employee[$i]['ID'] = $value->EmpID; + $employee[$i]['Name'] = $value->FirstName; + $employee[$i]['DOJ'] = get_date_time_dynamical_format('Y-m-d H:i:s','d-m-Y',"$value->DateofJoining"); + $employee[$i]['Designation'] = $value->Designation ; + $NoofDays = $value->NoofDays; // Month day 30,31,28 + $employee[$i]['NoofDays'] = round($NoofDays); + $Days_worked = $value->Days_worked; // Work day + $employee[$i]['Days_worked'] = round($Days_worked); + $employee[$i]['Leave'] = round($value->NoofDays - ($Days_worked)); // Absent Days LOP + $Basic_Pay = $value->Basic_Pay; + // $employee[$i]['Basic_Pay'] = $Basic_Pay; + $TotalSalary = $value->TotalSalary; + $employee[$i]['TotalSalary'] = number_format($TotalSalary, 2, '.', ''); + $PerDaySalary = $value->TotalSalary / $NoofDays; + $employee[$i]['PerDaySalary'] = number_format($PerDaySalary, 2, '.', ''); + + $WorkedSalary = $PerDaySalary * ($Days_worked); + $employee[$i]['WorkedSalary'] = number_format($WorkedSalary, 2, '.', ''); + $PerHrSalary = $PerDaySalary / 8; + $employee[$i]['PerHrSalary'] = number_format($PerHrSalary, 2, '.', ''); + $employee[$i]['EarnedSalary'] = number_format($WorkedSalary, 2, '.', ''); + + $BasicWorked = $WorkedSalary * 70 / 100; + $employee[$i]['BasicWorked'] = number_format($BasicWorked, 2, '.', ''); + $HraWorked = $WorkedSalary * 30 / 100; + $employee[$i]['HraWorked'] = number_format($HraWorked, 2, '.', ''); + $employee[$i]['GrossSalary'] = number_format($BasicWorked + $HraWorked, 2, '.', ''); + if ($value->is_management_team == 1) + { + $OT_Hrs_Worked = 0; //OT hours + $value->OT_Hrs_Worked = 0; + } else { + $OT_Hrs_Worked = $value->OT_Hrs_Worked; //OT hours + } + $totSalayOT = ($OT_Hrs_Worked != 0) ? $OT_Hrs_Worked * $PerHrSalary : 0; + + $HRA_Amount = $value->HRA_Amount; + $Paid_leave = $value->Paid_leave; // leave day + $Monthly_Due = $value->Monthly_Due; // AUTO LOAN DUE + $Loan_Recovered = $value->Loan_Recovered; //MANUAL LOAN DUE + $due_start_date = $value->DueDate; + + if (strlen((string)$monthyear) == 6) { + $monthyear = '0' . $monthyear; + } + $pmonth = substr($monthyear, 0, 2); + $pyear = substr($monthyear, -4); + + $pmonth = substr($monthyear, 0, 2); + $pyear = substr($monthyear, -4); + $pday = cal_days_in_month(CAL_GREGORIAN, $pmonth, $pyear); + $payfulldate = $pyear . '-' . $pmonth . '-' . $pday; + $totalDaysWorked = $Days_worked + $Paid_leave; + $Loan_amount = $value->Loan_Amount; + $Paid_Amount = $value->Paid_Amount; + $Balance_Amount = $Loan_amount - $Paid_Amount; + $loan = 0; + if ($Loan_Recovered == 'NA') { + $loan = 0.00; + } else if ($Loan_Recovered == 0.00) { + if (strtotime($due_start_date) <= strtotime($payfulldate)) { + $loan = $Monthly_Due; + } + } else if ($Loan_Recovered >= 0.00) { + if (strtotime($due_start_date) <= strtotime($payfulldate)) { + $loan = $Loan_Recovered; + } + } + + if ($Monthly_Due > $Balance_Amount) { + $loan = $Balance_Amount; + } + + $PF_Rate = $value->PF_Rate; + $ESI_Rate = $value->ESI_Rate; + + $dayHra = $HRA_Amount / $NoofDays; + $dayBasic = $Basic_Pay / $NoofDays; + + //current day basic and hra salary + if ($value->is_management_team == 1) + { + $currentDayBasic = $dayBasic * $NoofDays; + $currentDayHra = $dayHra * $NoofDays; + } else { + $currentDayBasic = $dayBasic * $totalDaysWorked; + $currentDayHra = $dayHra * $totalDaysWorked; + } + + if ($value->esi_applicable == 1) { $esiAmount = ($currentDayBasic + $currentDayHra) * $ESI_Rate / 100; } else { $esiAmount = 0; } + if ($value->pf_applicable == 1) { $pfAmount = $currentDayBasic * $PF_Rate / 100; } else { $pfAmount = 0; } + + /** pf amount per day**/ + + //echo $totalothour;die; + $empSalaryAdd = $currentDayBasic + $currentDayHra + $totSalayOT; + + $empSalarySub = $esiAmount + $pfAmount + $loan; + + $salaryInCurrentday = $empSalaryAdd - $empSalarySub; + + $employee[$i]['ESI'] = number_format($esiAmount, 2, '.', ''); + $employee[$i]['PF'] = number_format($pfAmount, 2, '.', ''); + $employee[$i]['ESI_PF'] = number_format($esiAmount + $pfAmount, 2, '.', ''); + $employee[$i]['OT'] = number_format($totSalayOT, 2, '.', ''); + + $employee[$i]['Feb_25_Advance'] = "-"; + $employee[$i]['TDS_92B'] ="-"; + $employee[$i]['Refuned_PF_Nov24'] ="-"; + $employee[$i]['NetSalary'] = round($salaryInCurrentday); + + $employee[$i]['GrossSalary2'] = "-"; + $employee[$i]['OT2'] = "-"; + $employee[$i]['GrossNetSalary'] = "-"; + $employee[$i]['ESI2'] ="-"; + $employee[$i]['PF2'] ="-"; + $employee[$i]['Sep_24_Advance'] = "-"; + $employee[$i]['TDS_92B'] = "-"; + $employee[$i]['Refuned_PF_Nov24'] = "-"; + $employee[$i]['Net_Salary'] = "-"; + $employee[$i]['Diff'] = "-"; + $employee[$i]['work_location'] = $value->work_location; + $employee[$i]['tds_applicable'] = $value->tds_applicable; + $employee[$i]['pf_applicable'] = $value->pf_applicable; + $employee[$i]['esi_applicable'] = $value->esi_applicable; + $i++; + + } + $j = $i; + foreach($driver_monthinputs_info as $record ){ + $hra_worked = $record->hra_worked; + $basic_worked = $record->basic_worked; + $sum_of_amount = ($record->driver_salary+$record->driver_shed+$record->driver_diesel); + + $employee[$j]['SNO'] = $j+1; + $employee[$j]['ID'] = $record->EmpID; + $employee[$j]['Name'] = $record->FirstName; + $employee[$j]['DOJ'] = get_date_time_dynamical_format('Y-m-d H:i:s','d-m-Y',"$record->DateofJoining"); + $employee[$j]['Designation'] = $record->Designation; + $employee[$j]['NoofDays'] = round($record->total_cal_days); + $employee[$j]['Days_worked'] = round($record->unique_days); + $employee[$j]['Leave'] = round($record->total_cal_days - $record->unique_days); + // number_format(0.00, 2, '.', ''); // paid leave + // number_format(0.00, 2, '.', ''); //ot hours + $employee[$j]['TotalSalary'] = number_format($sum_of_amount, 2, '.', ''); + $worked_amt = $sum_of_amount / $record->total_cal_days ; + $employee[$j]['PerDaySalary'] = number_format($worked_amt, 2, '.', ''); + $employee[$j]['WorkedSalary'] = number_format($worked_amt, 2, '.', ''); + $hr_amt = $worked_amt/8; + $employee[$j]['PerHrSalary'] = number_format($hr_amt, 2, '.', ''); + $employee[$j]['EarnedSalary'] = number_format($sum_of_amount, 2, '.', ''); + $employee[$j]['BasicWorked'] = number_format($basic_worked, 2, '.', ''); + $employee[$j]['HraWorked'] = number_format($hra_worked, 2, '.', ''); + $employee[$j]['GrossSalary'] = number_format($basic_worked + $hra_worked, 2, '.', ''); + + $employee[$j]['ESI'] = number_format($record->esi_amount, 2, '.', ''); + $employee[$j]['PF'] = number_format($record->pf_amount, 2, '.', ''); + $employee[$j]['ESI_PF'] = number_format($record->esi_amount + $record->pf_amount, 2, '.', ''); + $employee[$j]['OT'] = number_format(0, 2, '.', ''); + $estTotal = ($basic_worked + $hra_worked + $record->Festival_Bonus)-($record->Monthly_Due+$record->esi_amount+$record->pf_amount); + + $employee[$j]['Feb_25_Advance'] = "-"; + $employee[$j]['TDS_92B'] ="-"; + $employee[$j]['Refuned_PF_Nov24'] ="-"; + $employee[$j]['NetSalary'] = round($estTotal); + + $employee[$j]['GrossSalary2'] = "-"; + $employee[$j]['OT2'] = "-"; + $employee[$j]['GrossNetSalary'] = "-"; + $employee[$j]['ESI2'] ="-"; + $employee[$j]['PF2'] ="-"; + $employee[$j]['Sep_24_Advance'] = "-"; + $employee[$j]['TDS_92B'] = "-"; + $employee[$j]['Refuned_PF_Nov24'] = "-"; + $employee[$j]['Net_Salary'] = "-"; + $employee[$j]['Diff'] = "-"; + $employee[$j]['work_location'] = $record->work_location; + $employee[$j]['tds_applicable'] = $record->tds_applicable; + $employee[$j]['pf_applicable'] = $record->pf_applicable; + $employee[$j]['esi_applicable'] = $record->esi_applicable; + $j++; + } + $finalFooter[] = $employee; + // do not try chatgpt please. + $location_info = []; + foreach ($employee as $key => $value) + { + if (isset($value['work_location']) && $value['work_location'] == "Thiruvenkadu") { + array_push($location_info,$value); + unset($employee[$key]); + } + } + + $tds_info = []; + foreach ($employee as $key => $value) + { + if (isset($value['tds_applicable']) && (int)$value['tds_applicable'] == 1) { + array_push($tds_info,$value); + unset($employee[$key]); + } + } + + $esi_or_pf_info = []; + foreach ($employee as $key => $value) + { + if (isset($value['pf_applicable']) && (int)$value['pf_applicable'] == 1 || isset($value['esi_applicable']) && (int)$value['esi_applicable'] == 1) { + array_push($esi_or_pf_info,$value); + unset($employee[$key]); + } + } + + $keysToRemove = ['work_location','tds_applicable','pf_applicable','esi_applicable']; + foreach ($tds_info as &$t_item) { + foreach ($keysToRemove as $key) { + unset($t_item[$key]); + } + } + unset($t_item); + + foreach ($esi_or_pf_info as &$e_item) { + foreach ($keysToRemove as $key) { + unset($e_item[$key]); + } + } + unset($e_item); + + foreach ($location_info as &$l_item) { + foreach ($keysToRemove as $key) { + unset($l_item[$key]); + } + } + unset($l_item); + + foreach ($employee as &$o_item) { + foreach ($keysToRemove as $key) { + unset($o_item[$key]); + } + } + unset($o_item); + + $xl[] = array_values($tds_info); + $xl[] = array_values($esi_or_pf_info); + $xl[] = array_values($location_info); + $xl[] = array_values($employee); + + // dd($xl); + + $headlines['company_name'] = isset($company_info[0]->CompanyName) ? $company_info[0]->CompanyName : "Resico India Pvt Ltd"; + $headlines['header1'] = $headlines_main; + $headlines['header2'] = $headlines_sub; + $headlines['type'] = 2; + $headlines['header2'] = $headlines_sub; + $headlines['merge_end_column'] = 7; + $headlines['file_name'] = 'ResicoSalary'.$pmonth.'-'.$pyear.'.xls'; + $headlines['final_Footer'] = $finalFooter; + + generate_excel($headlines,$xl); + + + // dd($employee); + + } + public function driverMonthlyPayInputs($current) { diff --git a/app/Helpers/excel_helper.php b/app/Helpers/excel_helper.php index c4ab8e73..3ae8c548 100755 --- a/app/Helpers/excel_helper.php +++ b/app/Helpers/excel_helper.php @@ -3,47 +3,412 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Exception as SpreadsheetReaderException; +use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Style\Alignment; +use PhpOffice\PhpSpreadsheet\Style\Color; +use PhpOffice\PhpSpreadsheet\Style\Font; +use PhpOffice\PhpSpreadsheet\Style\Fill; +use PhpOffice\PhpSpreadsheet\Style\Border; +use PhpOffice\PhpSpreadsheet\Style\Borders; + if (!function_exists('generate_excel')) { - - /* - This function generates an Excel file using the given headers and data and saves it with the specified filename. - It utilizes the PhpSpreadsheet library to create and manipulate Excel files. - - Parameters: - - $headers: An array containing the column headers for the Excel sheet. - - $data: An array containing the data to be inserted into the Excel sheet. - - $filename: The name of the file to be saved. - - $totals (optional): A flag indicating whether to include total calculations in the Excel sheet. - */ - - - function generate_excel($headers, $data, $filename) + + function generate_excel($headlines, $xldata) { + + $headersMain = $headlines['header1']; + $headersSub = $headlines['header2']; + $company = $headlines['company_name']; + $filename = $headlines['file_name']; + $type = $headlines['type']; + $footer = false; + $mergeEndCol = $headlines['merge_end_column']; + // $type = 1 means $data is single + // $type = 2 means $data is multiple array + + // Create new Spreadsheet object $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + + // Set worksheet title + $sheet->setTitle('Sheet 1'); - // Set worksheet title - $spreadsheet->getActiveSheet()->setTitle('Sheet 1'); + + // A1 Start here... should be compnay name .... + $sheet->setCellValue('A1', $company); - // Set headers into the spreadsheet - $spreadsheet->getActiveSheet()->fromArray([$headers], null, 'A1'); + // Get last column letter based on headers count + // $lastColumnLetter = getExcelColumnName(count($headers) - 1); + $colCount = count($headersMain); + + // Calculate end column by character math (works up to 'ZZ') + $lastColumnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colCount); - // Set data into the spreadsheet - $spreadsheet->getActiveSheet()->fromArray($data, null, 'A2'); + $sheet->mergeCells("A1:{$lastColumnLetter}1"); + // Style A1 + $sheet->getStyle("A1")->getFill() + ->setFillType(Fill::FILL_SOLID) + ->getStartColor()->setRGB('ADD8E6'); // Light blue + $sheet->getStyle("A1")->getAlignment() + ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER) + ->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER); + + $sheet->getStyle("A1")->getFont()->setBold(true)->setSize(14); + + $sheet->getStyle("A1")->getFont() + ->getColor() + ->setRGB(Color::COLOR_WHITE); + + // /. A1 ends here + $currentRow = 2; // Start at row 2 + if($type == 1){ + $startCell = 'A' . $currentRow; + $lastcolrow = callHeader($sheet, $headersMain, $startCell,$headersSub); + $lastcolrow2 = callSkipRow($lastcolrow); + $lastcolrow3 = callData($sheet,$headersMain,$xldata,$lastcolrow2,$mergeEndCol); + $lastcolrow4 = callSkipRow($lastcolrow3); + if($footer){ + $lastcolrow5 = callFooter($sheet, $headersMain, $xldata, $lastcolrow4,'','',$mergeEndCol); + } + + + }else if($type == 2){ + // $final_Footer=[]; + // foreach($xldata as $i => $xl){ + // echo $i; + // echo "
"; + // print_r($xl[$i]); + // echo ""; + // // echo count($xl[$i])."**"; + // // $forFinalFooter + // } + // foreach ($xldata as $i => $xl) { + // $forFinalFooter[] = $xl[$i]; + // } + $final_Footer = isset($headlines['final_Footer']) && !empty($headlines['final_Footer']) ? $headlines['final_Footer'] : []; + + foreach ($xldata as $index => $data) { + if (!empty($data)) { + $startCell = 'A' . $currentRow; + + $lastcolrow = callHeader($sheet, $headersMain, $startCell,$headersSub); + $lastcolrow2 = callSkipRow($lastcolrow); + $lastcolrow3 = callData($sheet, $headersMain, $data, $lastcolrow2); + $lastcolrow4 = callSkipRow($lastcolrow3); + $lastcolrow5 = callFooter($sheet, $headersMain, $data, $lastcolrow4,'Total Amount Rs','228B22',$mergeEndCol); + $lastcolrow6 = callSkipRow($lastcolrow5); + + // Update currentRow for next iteration + $currentRow = (int) filter_var($lastcolrow6, FILTER_SANITIZE_NUMBER_INT); + } else { + $startCell = 'A' . $currentRow; + $lastcolrow = callHeader($sheet, $headersMain, $startCell,$headersSub); + $lastcolrow2 = callSkipRow($lastcolrow); + + $currentRow = (int) filter_var($lastcolrow2, FILTER_SANITIZE_NUMBER_INT); + } + } + + if(!empty($final_Footer)){ + $startCell = 'A' . $currentRow; + callFooter($sheet, $headersMain, $final_Footer[0], $startCell,'Final Net Salary Amount Rs','DC143C',$mergeEndCol); + // echo "cr".$currentRow;die; + } + + // $final_Footer + + } // Create Excel writer $writer = new Xlsx($spreadsheet); + $columnCount = count($headersMain); + for ($col = 1; $col <= $columnCount; $col++) { + $columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col); + $sheet->getColumnDimension($columnLetter)->setAutoSize(true); + } + + $highestColumn = $sheet->getHighestColumn(); // e.g., 'E' + $highestRow = $sheet->getHighestRow(); // e.g., 10 + + // Build the full range (e.g., 'A1:E10') + $range = 'A1:' . $highestColumn . $highestRow; + + // Apply border to that range + $sheet->getStyle($range)->applyFromArray([ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => Border::BORDER_THIN, + 'color' => ['argb' => 'FF000000'], + ], + ], + ]); try { + // Save Excel file to the specified path - $writer->save($filename); - return true; // Return true if file was successfully saved + ob_clean(); + header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + header("Content-Disposition: attachment; filename=\"$filename\""); + header('Cache-Control: max-age=0'); + + $writer->save('php://output'); // stream to browser + exit; // Return true if file was successfully saved + } catch (\Exception $e) { // Log or handle the exception return false; // Return false if there was an error saving the file } } } + + +function callHeader($sheet, $headersMain, $startCell, $headersSub = []) { + $rowNumber = (int) filter_var($startCell, FILTER_SANITIZE_NUMBER_INT); + + $startCol = 'A'; + $colCount = count($headersMain); + + // Calculate end column by character math (works up to 'ZZ') + $endCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colCount); + + // Check if sub-header has any non-empty value + $hasSubHeader = !empty(array_filter($headersSub, function ($val) { + return trim($val) !== ''; + })); + + // 1. Write Main Header + $sheet->fromArray([$headersMain], null, $startCell); + $mainHeaderRange = "{$startCol}{$rowNumber}:{$endCol}{$rowNumber}"; + + // Style Main Header + $sheet->getStyle($mainHeaderRange)->applyFromArray([ + 'font' => [ + 'bold' => true, + 'color' => ['rgb' => 'FF0000'], + 'size' => 12, + ], + 'alignment' => [ + 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, + 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, + ] + ]); + + if ($hasSubHeader) { + // 2. Write Sub Header + $subHeaderRow = $rowNumber + 1; + $sheet->fromArray([$headersSub], null, "A{$subHeaderRow}"); + + $subHeaderRange = "{$startCol}{$subHeaderRow}:{$endCol}{$subHeaderRow}"; + + + $sheet->getStyle($subHeaderRange)->applyFromArray([ + 'font' => [ + 'bold' => true, + 'color' => ['rgb' => 'FF0000'], + 'size' => 12, + ], + 'alignment' => [ + 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, + 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, + ] + ]); + + return 'A' . ($subHeaderRow + 1); + } else { + return 'A' . ($rowNumber + 1); + } +} + + + +function callData($sheet, $headers, $data, $startCell) { + + $startRow = (int) filter_var($startCell, FILTER_SANITIZE_NUMBER_INT); + $startCol = 'A'; + $sheet->fromArray($data, null, $startCell); + + $dataRowCount = count($data); + $lastDataRow = $startRow + $dataRowCount; + + // $dataColCount = count($headers); + // $lastDataColumn = getExcelColumnName($dataColCount - 1); + // $dataRange = "{$startCol}{$startRow}:{$lastDataColumn}{$lastDataRow}"; + // Set font color to black + // $sheet->getStyle($dataRange)->getFont()->getColor()->setRGB('000000'); + + return 'A' . ($lastDataRow + 1); // return next row +} + +function callSkipRow($startCell){ + $row = (int) filter_var($startCell, FILTER_SANITIZE_NUMBER_INT); + return 'A' . ($row + 1); // just skip a line +} + +// function callFooter($sheet, $headers, $data, $startCell,$mergeEndindex) { + +// $row = (int) filter_var($startCell, FILTER_SANITIZE_NUMBER_INT); + +// $startCol = preg_replace('/[0-9]/', '', $startCell); + +// // Determine numeric columns dynamically +// // $numericIndexes = []; +// // foreach ($data as $index => $val) { +// // foreach ($data as $rowData) { +// // if (isset($rowData[$index]) && is_numeric($rowData[$index])) { +// // $numericIndexes[] = $index; +// // break; +// // } +// // } +// // } +// if (!empty($data)) { +// // Look at the first row +// $firstRow = $data[0]; + +// foreach ($firstRow as $key => $value) { +// foreach ($data as $row) { +// if (isset($row[$key]) && is_numeric($row[$key])) { +// $numericIndexes[] = $key; // use the key (could be column name) +// break; +// } +// } +// } +// } + +// // Get first numeric column index for placing totals +// if (empty($numericIndexes)) return 'A' . ($row + 1); // Nothing to total + +// sort($numericIndexes); +// $firstNumericIndex = $numericIndexes[0]; +// $colCount = count($headers); + +// // Calculate end column by character math (works up to 'ZZ') +// if($mergeEndindex == ''){ +// $mergeEndCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colCount - 1); + +// }else{ +// $mergeEndCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex((int)$mergeEndindex); +// } + + + +// // echo gettype($row);die; + +// // Merge from A to column before first numeric column (for "TOTAL" label) +// $sheet->mergeCells("A{$row}:{$mergeEndCol}{$row}"); +// $sheet->setCellValue("A{$row}", 'TOTAL'); + +// // Style for TOTAL label +// $sheet->getStyle("A{$row}:{$mergeEndCol}{$row}")->applyFromArray([ +// 'font' => [ +// 'bold' => true, +// 'size' => 14, +// 'color' => ['rgb' => '228B22'] +// ], +// 'alignment' => [ +// 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, +// 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER +// ] +// ]); + +// // Total each numeric column and write to corresponding cell +// foreach ($numericIndexes as $index) { +// $total = 0; +// foreach ($data as $rowData) { +// $value = $rowData[$index] ?? 0; +// if (is_numeric($value)) { +// $total += $value; +// } +// } +// $colLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex((int)$index); +// $sheet->setCellValue("{$colLetter}{$row}", $total); +// } + +// return 'A' . ($row + 1); // Return next available row +// } +function callFooter($sheet, $headers, $data, $startCell,$label,$code,$mergeEndIndex = null) { + $row = (int) filter_var($startCell, FILTER_SANITIZE_NUMBER_INT); + $startCol = preg_replace('/[0-9]/', '', $startCell); + + $numericKeys = []; + $columnKeys = array_keys($data[0] ?? []); + $columnKeyToIndex = array_flip($columnKeys); // key => index + + // Detect numeric columns + foreach ($columnKeys as $key) { + foreach ($data as $rowData) { + if (isset($rowData[$key]) && is_numeric($rowData[$key])) { + $numericKeys[] = $key; + break; + } + } + } + + // If no numeric columns, skip total row + if (empty($numericKeys)) { + return $startCol . ($row + 1); + } + + // Determine where to end the merge for the TOTAL label + if ($mergeEndIndex === null || $mergeEndIndex === '') { + $firstNumericKey = $numericKeys[0]; + $firstNumericIndex = $columnKeyToIndex[$firstNumericKey]; + $mergeEndIndex = $firstNumericIndex > 0 ? $firstNumericIndex - 1 : 0; + } + + // Write totals for each numeric column + foreach ($numericKeys as $colKey) { + $total = 0; + foreach ($data as $rowData) { + $val = $rowData[$colKey] ?? 0; + if (is_numeric($val)) { + $total += $val; + } + } + + $colIndex = $columnKeyToIndex[$colKey]; + $colLetter = Coordinate::stringFromColumnIndex($colIndex + 1); + $sheet->setCellValue("{$colLetter}{$row}", $total); + $sheet->getStyle("{$colLetter}{$row}")->getNumberFormat()->setFormatCode('#,##0.00'); + $sheet->getStyle("{$colLetter}{$row}")->applyFromArray([ + 'font' => [ + 'bold' => true, + 'size' => 12 + ], + 'alignment' => [ + 'horizontal' => Alignment::HORIZONTAL_CENTER, + 'vertical' => Alignment::VERTICAL_CENTER + ] + ]); + + + } + + + $mergeEndCol = Coordinate::stringFromColumnIndex((int)$mergeEndIndex + 1); + $mergeRange = "{$startCol}{$row}:{$mergeEndCol}{$row}"; + + // Merge cells and write $label name = "TOTAL" + $sheet->mergeCells($mergeRange); + $sheet->setCellValue("{$startCol}{$row}", $label); + + // Style "TOTAL" label + $sheet->getStyle($mergeRange)->applyFromArray([ + 'font' => [ + 'bold' => true, + 'size' => 14, + 'color' => ['rgb' => $code] + ], + 'alignment' => [ + 'horizontal' => Alignment::HORIZONTAL_CENTER, + 'vertical' => Alignment::VERTICAL_CENTER + ] + ]); + + // Return next row cell reference + return $startCol . ($row + 1); +} + diff --git a/app/Models/Monthlypay_model.php b/app/Models/Monthlypay_model.php index d984d3d6..12903b92 100755 --- a/app/Models/Monthlypay_model.php +++ b/app/Models/Monthlypay_model.php @@ -103,7 +103,7 @@ class Monthlypay_model extends Model //echo $lastdate; //left join t_payroll on t_employee_details.EmpID = t_payroll.EmpID and month(t_payroll.PayOn) = month(?) and year(t_payroll.PayOn) = year(?) - $sql = "select t_emp_pay_data.EmpID,t_emp_pay_data.*,t_employee_details.FirstName,t_employee_details.DateofJoining,t_employee_details.Designation,t_employee_details.esi_applicable,t_employee_details.pf_applicable,t_employee_details.is_management_team,t_attendance.Days_Worked as Days_worked,t_attendance.Absent as LOP_Days,t_attendance.Paid_Leave as Paid_leave,t_attendance.Total_OTHrs as OT_Hrs_Worked,t_attendance.NoofDays,t_attendance.sunday_count,t_loan_master.Loan_ID,t_loan_master.Monthly_Due,t_loan_master.Due_Start_Date as DueDate,t_loan_master.Loan_Amount,t_loan_master.Paid_Amount,t_payroll.Id,t_monthly_pay_inputs.Loan_Recovered,t_monthly_pay_inputs.Estimate,t_monthly_pay_inputs.Festival_Bonus,t_monthly_pay_inputs.Other_Deductions,t_monthly_pay_inputs.is_payslip_generated,t_loan_history .Balance_Amount,t_employee_details.is_driver + $sql = "select t_emp_pay_data.EmpID,t_emp_pay_data.*,t_employee_details.work_location,t_employee_details.tds_applicable,t_employee_details.FirstName,t_employee_details.DateofJoining,t_employee_details.Designation,t_employee_details.esi_applicable,t_employee_details.pf_applicable,t_employee_details.is_management_team,t_attendance.Days_Worked as Days_worked,t_attendance.Absent as LOP_Days,t_attendance.Paid_Leave as Paid_leave,t_attendance.Total_OTHrs as OT_Hrs_Worked,t_attendance.NoofDays,t_attendance.sunday_count,t_loan_master.Loan_ID,t_loan_master.Monthly_Due,t_loan_master.Due_Start_Date as DueDate,t_loan_master.Loan_Amount,t_loan_master.Paid_Amount,t_payroll.Id,t_monthly_pay_inputs.Loan_Recovered,t_monthly_pay_inputs.Estimate,t_monthly_pay_inputs.Festival_Bonus,t_monthly_pay_inputs.Other_Deductions,t_monthly_pay_inputs.is_payslip_generated,t_loan_history .Balance_Amount,t_employee_details.is_driver from t_emp_pay_data left join t_employee_details on t_employee_details.EmpID = t_emp_pay_data.EmpID left join t_payroll on t_employee_details.EmpID = t_payroll.EmpID and t_payroll.PayOn = ? @@ -119,7 +119,7 @@ class Monthlypay_model extends Model $query = $this->db->query($sql, array($month, $month, $lastdate, $current, $current)); // Get the last executed query // $last_query = $this->db->getLastQuery(); - // echo $last_query; + // echo $last_query;die; return $query->getResult(); } diff --git a/app/Views/monthlypayinputs.php b/app/Views/monthlypayinputs.php index 1cb5f9e8..cc6704ee 100755 --- a/app/Views/monthlypayinputs.php +++ b/app/Views/monthlypayinputs.php @@ -201,6 +201,12 @@ + " + title=""> + + + @@ -949,6 +955,32 @@ $(document).ready(function () { }); } + function DataForExportExcel(){ + var my = $('#monthyear').val(); + $('#loader').show(); + $.ajax({ + data:{MY:my}, + type: "POST", + url: "exportMonthlyPayInputs", + success: function(data) { + if(data){ + alert("step1"); + }else{ + alert("false"); + } + }, + error:function(error){ + alert("error"); + console.log("error occured..!!" ,error); + }, + complete:function(){ + $('#loader').hide(); + console.log('ajax call completed..!!'); + } + }); + + } + $("#monthyear").change(function() {