Showing AI reviews for army
Project AI Score ?
67%
Quality Avg ?
72%
Security Avg ?
54%
Reviews ?
37

Review Result ?

jattin01/army · 822ed213
The commit adds a new controller class with multiple payroll-related features including listing, generating, and printing bulk salaries. Input validation is present, business logic is modularized, and data retrieval is reasonably optimized with chunking. The code is generally clear and functional but there are opportunities to improve naming, input validation details, error handling, and security considerations.
Quality ?
75%
Security ?
70%
Business Value ?
80%
Maintainability ?
73%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Issue
Where commit message
Issue / Evidence issue
Suggested Fix provide a more descriptive commit message explaining what was changed and why to improve project documentation and reviewability
Magic Number Used For Default Month From N...
Where app/Http/Controllers/BulkSalaryController.php:21
Issue / Evidence magic number used for default month from now()
Suggested Fix consider extracting method or constant to clarify purpose and improve maintainability
Use Of $Request >Employee Category Id Dire...
Where app/Http/Controllers/BulkSalaryController.php:25
Issue / Evidence use of $request->employee_category_id directly
Suggested Fix ensure strict typing and validation to avoid injection or casting bugs
Missing Validation
Where app/Http/Controllers/BulkSalaryController.php:72
Issue / Evidence 'employee_ids' validation rule could be stricter by limiting max array size to prevent DOS with very large inputs
Suggested Fix Review and simplify this section.
Chunk Size Of 300 Is Hardcoded
Where app/Http/Controllers/BulkSalaryController.php:101
Issue / Evidence chunk size of 300 is hardcoded
Suggested Fix consider introducing a configuration constant for easier tuning
Direct Use Of Insert Without Error Handlin...
Where app/Http/Controllers/BulkSalaryController.php:120
Issue / Evidence direct use of insert without error handling
Suggested Fix wrap in try-catch and handle potential DB errors for robustness
Redirect With Success Message Is Basic
Where app/Http/Controllers/BulkSalaryController.php:125
Issue / Evidence redirect with success message is basic
Suggested Fix consider supporting error feedback paths for failed generation attempts
Magic Constants '450' And '9' For Printing...
Where app/Http/Controllers/BulkSalaryController.php:134
Issue / Evidence magic constants '450' and '9' for printing limits
Suggested Fix use named constants or configuration instead
Continue On Missing Snapshot Silently
Where app/Http/Controllers/BulkSalaryController.php:150
Issue / Evidence continue on missing snapshot silently
Suggested Fix log or handle this as a warning to aid debugging
Continue On Missing Staff Silently
Where app/Http/Controllers/BulkSalaryController.php:155
Issue / Evidence continue on missing staff silently
Suggested Fix log or handle as a warning for data integrity
Long Function
Where app/Http/Controllers/BulkSalaryController.php:163
Issue / Evidence complex array access with null coalescing could mask data issues
Suggested Fix validate salary JSON structure explicitly
Consider Adding Phpdoc Comments To Public...
Where app/Http/Controllers/BulkSalaryController.php:21 to app/Http/Controllers/BulkSalaryController.php:130
Issue / Evidence consider adding PHPDoc comments to public methods for improved code understanding and API clarity
Suggested Fix Review and simplify this section.
Code Change Preview · app/Http/Controllers/BulkSalaryController.php ?
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers;
+ 
+ use App\Models\EmployeeCategory;
+ use App\Models\FinanceDeductionTitle;
+ use App\Models\FinanceSalaryBatch;
+ use App\Models\FinanceSalaryBatchItem;
+ use App\Models\FinanceSalarySnapshot;
+ use App\Models\Holiday;
+ use App\Models\Staff;
+ use App\Services\SalaryCalculationService;
+ use App\Services\SalaryPrintService;
+ use Illuminate\Http\Request;
+ use Illuminate\Support\Facades\DB;
+ 
+ class BulkSalaryController extends Controller
+ {
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers;
+ 
+ use App\Models\FinanceDeductionTitle;
+ use Illuminate\Http\Request;
+ use Illuminate\Validation\Rule;
+ 
+ class FinanceDeductionTitleController extends Controller
+ {
+     public function index()
+     {
+         return $this->renderIndex();
+     }
+ 
+     public function create()
+     {
+         return $this->renderIndex();
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers;
+ 
+ use App\Models\EmployeeCategory;
+ use App\Models\FinancePaymentRecovery;
+ use App\Models\FinanceStaffDetail;
+ use App\Models\Staff;
+ use Illuminate\Http\Request;
+ 
+ class FinanceStaffDetailsController extends Controller
+ {
+     public function index(Request $request)
+     {
+         $staffs = Staff::with(['employeeCategory', 'user.group', 'financeDetail'])
+             ->when($request->filled('employee_number'), function ($query) use ($request) {
+                 $query->where('employee_number', 'LIKE', '%' . $request->employee_number . '%');
+             })
Removed / Before Commit
- 
- public function part2No(Request $request)
- {
-         $filters = $request->only(['start_date', 'end_date', 'staff_part_2_no', 'history_do_2_part_no']);
- $staff = collect();
- $groupedLeaves = collect();
- $leaveIds = collect();
-         $appliedLeaves = collect();
-         $history = collect();
- 
-         if ($request->filled('start_date') || $request->filled('end_date') || $request->filled('staff_part_2_no')) {
- $validated = $request->validate([
- 'start_date' => 'required|date',
- 'end_date' => 'required|date|after_or_equal:start_date',
-                 'staff_part_2_no' => 'required|string|max:255',
- ]);
- 
-             $staff = Staff::where('part_2_no', $validated['staff_part_2_no'])
Added / After Commit
+ 
+ public function part2No(Request $request)
+ {
+         $yearStart = Carbon::now()->startOfYear()->toDateString();
+         $yearEnd = Carbon::now()->endOfYear()->toDateString();
+         $filters = $request->only(['start_date', 'end_date', 'staff_part_2_no', 'existing_do_2_part_no']);
+         $searchType = $request->filled('existing_do_2_part_no') ? 'existing' : 'staff';
+ $staff = collect();
+ $groupedLeaves = collect();
+ $leaveIds = collect();
+ 
+         if ($request->filled('staff_part_2_no') || $request->filled('existing_do_2_part_no')) {
+ $validated = $request->validate([
+ 'start_date' => 'required|date',
+ 'end_date' => 'required|date|after_or_equal:start_date',
+                 'staff_part_2_no' => 'nullable|string|max:255|required_without:existing_do_2_part_no',
+                 'existing_do_2_part_no' => 'nullable|string|max:255|required_without:staff_part_2_no',
+ ]);
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers;
+ 
+ use App\Models\FinanceSalarySnapshot;
+ use App\Models\Staff;
+ use App\Services\SalaryCalculationService;
+ use Illuminate\Http\Request;
+ 
+ class SalaryController extends Controller
+ {
+     public function show(Request $request, Staff $staff, SalaryCalculationService $salaryService)
+     {
+         $month = (int) $request->input('month', now()->month);
+         $year = (int) $request->input('year', now()->year);
+         $force = $request->boolean('regenerate');
+         $existingBeforeGenerate = FinanceSalarySnapshot::where('employee_id', $staff->id)
+             ->where('month', $month)
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Factories\HasFactory;
+ use Illuminate\Database\Eloquent\Model;
+ 
+ class FinanceDeductionTitle extends Model
+ {
+     use HasFactory;
+ 
+     protected $fillable = [
+         'deduction_title',
+         'amount',
+         'month',
+         'year',
+     ];
+ 
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Factories\HasFactory;
+ use Illuminate\Database\Eloquent\Model;
+ 
+ class FinancePaymentRecovery extends Model
+ {
+     use HasFactory;
+ 
+     protected $fillable = [
+         'staff_id',
+         'gpf_adv_date',
+         'gpf_adv',
+         'gpf_per_inst',
+         'fes_adv_date',
+         'fes_adv',
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Factories\HasFactory;
+ use Illuminate\Database\Eloquent\Model;
+ 
+ class FinanceSalaryBatch extends Model
+ {
+     use HasFactory;
+ 
+     protected $fillable = [
+         'month',
+         'year',
+         'employee_category_id',
+         'cr_no',
+         'employee_count',
+         'gross_total',
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Factories\HasFactory;
+ use Illuminate\Database\Eloquent\Model;
+ 
+ class FinanceSalaryBatchItem extends Model
+ {
+     use HasFactory;
+ 
+     public $timestamps = false;
+ 
+     protected $fillable = [
+         'batch_id',
+         'salary_snapshot_id',
+         'employee_id',
+     ];
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Factories\HasFactory;
+ use Illuminate\Database\Eloquent\Model;
+ 
+ class FinanceSalarySnapshot extends Model
+ {
+     use HasFactory;
+ 
+     protected $fillable = [
+         'employee_id',
+         'month',
+         'year',
+         'salary_json',
+         'gross_total',
+         'deduction_total',
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Models;
+ 
+ use Illuminate\Database\Eloquent\Factories\HasFactory;
+ use Illuminate\Database\Eloquent\Model;
+ 
+ class FinanceStaffDetail extends Model
+ {
+     use HasFactory;
+ 
+     protected $fillable = [
+         'staff_id',
+         'cr_no',
+         'handicap',
+         'govt_accommodation',
+         'special_pay',
+         'risk_allowance',
Removed / Before Commit
- return $this->hasMany(StaffLeaveBalance::class, 'staff_id');
- }
- 
- }
Added / After Commit
+ return $this->hasMany(StaffLeaveBalance::class, 'staff_id');
+ }
+ 
+     public function financeDetail()
+     {
+         return $this->hasOne(FinanceStaffDetail::class, 'staff_id');
+     }
+ 
+     public function financePaymentRecovery()
+     {
+         return $this->hasOne(FinancePaymentRecovery::class, 'staff_id');
+     }
+ 
+     public function financeSalarySnapshots()
+     {
+         return $this->hasMany(FinanceSalarySnapshot::class, 'employee_id');
+     }
+ 
Removed / Before Commit
- 'route' => 'leave-part-2-no',
- 'children' => collect(),
- ],
- ]);
- };
Added / After Commit
+ 'route' => 'leave-part-2-no',
+ 'children' => collect(),
+ ],
+                     (object) [
+                         'name' => 'Finance Staff Details',
+                         'icon' => '<i class="fas fa-money-check-alt"></i>',
+                         'route' => 'finance-staff-details',
+                         'children' => collect(),
+                     ],
+ ]);
+ };
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Services;
+ 
+ use App\Models\DaRate;
+ use App\Models\Attendance;
+ use App\Models\FinanceDeductionTitle;
+ use App\Models\FinanceSalarySnapshot;
+ use App\Models\Staff;
+ use Carbon\Carbon;
+ use Illuminate\Support\Facades\DB;
+ 
+ class SalaryCalculationService
+ {
+     private ?array $rules = null;
+ 
+     public function generateForStaff(Staff $staff, int $month, int $year, bool $force = false, bool $deductionsRecoveriesOnly = false): FinanceSalarySnapshot
+     {
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Services;
+ 
+ use Illuminate\Support\Collection;
+ 
+ class SalaryPrintService
+ {
+     public function paginateNine(Collection $snapshots): array
+     {
+         $pages = [];
+ 
+         foreach ($snapshots->chunk(9) as $chunk) {
+             $pages[] = [
+                 'snapshots' => $chunk,
+                 'subtotal' => $this->totals($chunk),
+             ];
+         }
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     public function up(): void
+     {
+         Schema::create('finance_deduction_titles', function (Blueprint $table) {
+             $table->id();
+             $table->string('deduction_title');
+             $table->decimal('amount', 12, 2);
+             $table->unsignedTinyInteger('month');
+             $table->unsignedSmallInteger('year');
+             $table->timestamps();
+ 
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     public function up(): void
+     {
+         Schema::create('finance_salary_snapshots', function (Blueprint $table) {
+             $table->id();
+             $table->foreignId('employee_id')->constrained('staff')->cascadeOnDelete();
+             $table->unsignedTinyInteger('month');
+             $table->unsignedSmallInteger('year');
+             $table->json('salary_json');
+             $table->decimal('gross_total', 14, 2)->default(0);
+             $table->decimal('deduction_total', 14, 2)->default(0);
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     public function up(): void
+     {
+         Schema::create('finance_salary_batches', function (Blueprint $table) {
+             $table->id();
+             $table->unsignedTinyInteger('month');
+             $table->unsignedSmallInteger('year');
+             $table->foreignId('employee_category_id')->nullable()->constrained('employee_categories')->nullOnDelete();
+             $table->string('cr_no')->nullable();
+             $table->unsignedInteger('employee_count')->default(0);
+             $table->decimal('gross_total', 16, 2)->default(0);
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\DB;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     public function up(): void
+     {
+         Schema::create('finance_salary_rules', function (Blueprint $table) {
+             $table->id();
+             $table->string('rule_key')->unique();
+             $table->decimal('rule_value', 12, 2);
+             $table->string('description')->nullable();
+             $table->timestamps();
+         });
Removed / Before Commit

                                                
Added / After Commit
+ -- Review before running. Codex did not execute this SQL.
+ -- History table is intentionally not created.
+ 
+ CREATE TABLE IF NOT EXISTS finance_deduction_titles (
+     id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
+     deduction_title VARCHAR(255) NOT NULL,
+     amount DECIMAL(12,2) NOT NULL,
+     month TINYINT UNSIGNED NOT NULL,
+     year SMALLINT UNSIGNED NOT NULL,
+     created_at TIMESTAMP NULL DEFAULT NULL,
+     updated_at TIMESTAMP NULL DEFAULT NULL,
+     UNIQUE KEY finance_deduction_titles_unique_period (deduction_title, month, year)
+ );
+ 
+ -- Menu link: Finance > Deduction Titles
+ -- Creates the Finance parent if it is not already present.
+ INSERT INTO menus (name, icon, route, parent_id, created_at, updated_at)
+ SELECT
Removed / Before Commit

                                                
Added / After Commit
+ -- Review before running. Codex did not execute this SQL.
+ 
+ CREATE TABLE IF NOT EXISTS finance_salary_snapshots (
+     id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
+     employee_id BIGINT UNSIGNED NOT NULL,
+     month TINYINT UNSIGNED NOT NULL,
+     year SMALLINT UNSIGNED NOT NULL,
+     salary_json JSON NOT NULL,
+     gross_total DECIMAL(14,2) NOT NULL DEFAULT 0,
+     deduction_total DECIMAL(14,2) NOT NULL DEFAULT 0,
+     recovery_total DECIMAL(14,2) NOT NULL DEFAULT 0,
+     net_pay DECIMAL(14,2) NOT NULL DEFAULT 0,
+     pay_in_hand DECIMAL(14,2) NOT NULL DEFAULT 0,
+     generated_at TIMESTAMP NULL DEFAULT NULL,
+     created_at TIMESTAMP NULL DEFAULT NULL,
+     updated_at TIMESTAMP NULL DEFAULT NULL,
+     UNIQUE KEY finance_salary_snapshot_employee_period_unique (employee_id, month, year),
+     KEY finance_salary_snapshot_period_index (year, month),
Removed / Before Commit

                                                
Added / After Commit
+ -- Review before running. Codex did not execute this SQL.
+ 
+ -- If finance_staff_details table does not exist on your server, create it.
+ CREATE TABLE IF NOT EXISTS finance_staff_details (
+     id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
+     staff_id BIGINT UNSIGNED NOT NULL,
+     cr_no VARCHAR(255) NULL,
+     handicap TINYINT(1) NOT NULL DEFAULT 0,
+     govt_accommodation TINYINT(1) NOT NULL DEFAULT 0,
+     special_pay DECIMAL(12,2) NULL,
+     risk_allowance DECIMAL(12,2) NULL,
+     wash DECIMAL(12,2) NULL,
+     misc_nps DECIMAL(12,2) NULL,
+     misc_pay DECIMAL(12,2) NULL,
+     misc_deduction DECIMAL(12,2) NULL,
+     created_at TIMESTAMP NULL DEFAULT NULL,
+     updated_at TIMESTAMP NULL DEFAULT NULL,
+     UNIQUE KEY finance_staff_details_staff_id_unique (staff_id),
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('content')
+ @php
+     $monthNames = [
+         1 => 'January',
+         2 => 'February',
+         3 => 'March',
+         4 => 'April',
+         5 => 'May',
+         6 => 'June',
+         7 => 'July',
+         8 => 'August',
+         9 => 'September',
+         10 => 'October',
+         11 => 'November',
+         12 => 'December',
+     ];
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('content')
+ @php
+     $monthNames = [1=>'January',2=>'February',3=>'March',4=>'April',5=>'May',6=>'June',7=>'July',8=>'August',9=>'September',10=>'October',11=>'November',12=>'December'];
+     $isCurrent = (int) $month === now()->month && (int) $year === now()->year;
+ @endphp
+ 
+ <div class="card">
+     <div class="card-header py-3"><h4 class="mb-0"><b>Bulk Salary Generation</b></h4></div>
+     <div class="card-body">
+         <form method="GET" action="{{ route('finance-salaries.bulk.index') }}" class="row g-3 align-items-end mb-4">
+             <div class="col-md-2">
+                 <label class="form-label">Month</label>
+                 <select name="month" class="form-select">
+                     @foreach($monthNames as $number => $name)
+                         <option value="{{ $number }}" @selected($month == $number)>{{ $name }}</option>
+                     @endforeach
Removed / Before Commit

                                                
Added / After Commit
+ <!doctype html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <title>Checkroll Print</title>
+ <style>
+ @page { size: A4 landscape; margin: 5mm; }
+ body { font-family: "Courier New", monospace; font-size: 8px; color: #000; background: #f2f2f2; }
+ .toolbar { margin-bottom: 10px; font-family: Arial, sans-serif; }
+ .toolbar button { padding: 6px 14px; }
+ .page {
+     width: 287mm;
+     min-height: 200mm;
+     margin: 0 auto 12px;
+     padding: 4mm;
+     box-sizing: border-box;
+     background: #fff;
+     page-break-after: always;
Removed / Before Commit

                                                
Added / After Commit
+ <!doctype html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <title>Cooperative Summary Print</title>
+ <style>
+ @page { size: A4 landscape; margin: 6mm; }
+ body { margin: 0; font-family: "Times New Roman", serif; font-size: 10px; color: #000; background: #f2f2f2; }
+ .toolbar { padding: 8px; font-family: Arial, sans-serif; }
+ .toolbar button { padding: 6px 14px; }
+ .page {
+     width: 287mm;
+     min-height: 190mm;
+     margin: 0 auto 12px;
+     padding: 5mm;
+     box-sizing: border-box;
+     background: #fff;
+     border: 1px solid #ddd;
Removed / Before Commit

                                                
Added / After Commit
+ <!doctype html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <title>CR Summary Print</title>
+ <style>
+ @page { size: A4 landscape; margin: 6mm; }
+ body { margin: 0; font-family: "Times New Roman", serif; font-size: 11px; color: #000; background: #f2f2f2; }
+ .toolbar { padding: 8px; font-family: Arial, sans-serif; }
+ .toolbar button { padding: 6px 14px; }
+ .page {
+     width: 287mm;
+     min-height: 190mm;
+     margin: 0 auto 12px;
+     padding: 5mm;
+     box-sizing: border-box;
+     background: #fff;
+     border: 1px solid #ddd;
Removed / Before Commit
- \ No newline at end of file
Added / After Commit
+ <div class="header">
+     <h3>509 ARMY BASE WORKSHOP, AGRA-282001</h3>
+ 
+     <h4>
+         CHECKROLL OF {{ strtoupper($categoryName ?? 'INDUSTRIAL ESTABLISHMENT') }}
+     </h4>
+ 
+     <h4>
+         FOR THE MONTH OF {{ $monthText }}
+     </h4>
+ 
+     <div>
+         PAGE NO : {{ $pageNo }}
+     </div>
+ </div>
+ 
+ <div class="meta">
+     <div>
Removed / Before Commit

                                                
Added / After Commit
+ @php
+     $salary = $snapshot->salary_json;
+     $monthNames = [1=>'JAN',2=>'FEB',3=>'MAR',4=>'APR',5=>'MAY',6=>'JUN',7=>'JUL',8=>'AUG',9=>'SEP',10=>'OCT',11=>'NOV',12=>'DEC'];
+     $schemeLabel = array_key_exists('UPS GOVT CONT', $salary['allowances'] ?? []) ? 'UPS' : 'NPS';
+     $monthlyTitles = $salary['deductions_meta']['monthly_titles'] ?? [];
+     $allowanceRows = [
+         ['MONTH', ($monthNames[$salary['period']['month']] ?? $salary['period']['month']) . ' ' . $salary['period']['year']],
+         ['T No', $salary['employee']['employee_number'] ?? '-'],
+         ['Trade', $salary['employee']['designation'] ?? '-'],
+         ['Name', $salary['employee']['name'] ?? '-'],
+         ['DoB', $salary['employee']['dob'] ?? '-'],
+         ['W Day', $salary['employee']['total_working_days'] ?? '-'],
+         ['P DAY/LATE', ($salary['employee']['present_days'] ?? '-') . ' / 0'],
+         ['Level', $salary['employee']['pay_level'] ?? '-'],
+         ['Cell', $salary['employee']['pay_cell'] ?? '-'],
+         ['Pay Level', $salary['employee']['pay_level'] ?? '-'],
+         ['E Basic', $salary['employee']['earned_basic_pay'] ?? 0],
+         ['DA', $salary['allowances']['DA'] ?? 0],
Removed / Before Commit

                                                
Added / After Commit
+ @php
+     $salary = $snapshot->salary_json;
+     $monthNames = [1=>'Jan',2=>'Feb',3=>'Mar',4=>'Apr',5=>'May',6=>'Jun',7=>'Jul',8=>'Aug',9=>'Sep',10=>'Oct',11=>'Nov',12=>'Dec'];
+     $monthText = ($monthNames[$salary['period']['month']] ?? $salary['period']['month']) . '/' . $salary['period']['year'];
+     $dob = !empty($salary['employee']['dob']) ? \Carbon\Carbon::parse($salary['employee']['dob'])->format('d/M/Y') : '-';
+     $doa = !empty($salary['employee']['joining_date']) ? \Carbon\Carbon::parse($salary['employee']['joining_date'])->format('d/M/Y') : '-';
+     $dor = !empty($salary['employee']['dob']) ? \Carbon\Carbon::parse($salary['employee']['dob'])->addYears(60)->format('d/M/Y') : '-';
+     $govtContribution = $salary['allowances']['NPS GOVT CONT'] ?? ($salary['allowances']['UPS GOVT CONT'] ?? 0);
+     $govtDeduction = $salary['deductions']['NPS/(GOVT)'] ?? ($salary['deductions']['UPS (GOVT)'] ?? 0);
+     $cghsEis = ($salary['deductions']['CGHS'] ?? 0) + ($salary['deductions']['CGEGIS'] ?? 0);
+     $monthlyTitles = $salary['deductions_meta']['monthly_titles'] ?? [];
+ @endphp
+ 
+ <div class="salary-slip statement-format">
+     <div class="text-center">
+         <h3>509 ARMY BASE WORKSHOP, AGRA-282001</h3>
+         <h4>Monthly Statement of Account for the month of {{ $monthText }}</h4>
+     </div>
Removed / Before Commit

                                                
Added / After Commit
+ @php
+     $salary = $snapshot->salary_json;
+     $monthNames = [1=>'Jan',2=>'Feb',3=>'Mar',4=>'Apr',5=>'May',6=>'Jun',7=>'Jul',8=>'Aug',9=>'Sep',10=>'Oct',11=>'Nov',12=>'Dec'];
+ @endphp
+ <div class="salary-slip">
+     <div class="slip-title">509 ARMY BASE WORKSHOP, AGRA-282001</div>
+     <div class="slip-subtitle">Monthly Statement of Account for the month of {{ $monthNames[$salary['period']['month']] ?? $salary['period']['month'] }}-{{ $salary['period']['year'] }}</div>
+     <table class="slip-meta">
+         <tr>
+             <td><b>EMP NO:</b> {{ $salary['employee']['employee_number'] ?? '-' }}</td>
+             <td><b>NAME:</b> {{ $salary['employee']['name'] ?? '-' }}</td>
+             <td><b>GROUP:</b> {{ $salary['employee']['group'] ?? '-' }}</td>
+         </tr>
+         <tr>
+             <td><b>LEVEL/CELL/BASIC:</b> {{ $salary['employee']['pay_level'] ?? '-' }} / {{ $salary['employee']['pay_cell'] ?? '-' }} / {{ number_format($salary['employee']['basic_salary'] ?? 0, 0) }}</td>
+             <td><b>PAN NO:</b> {{ $salary['employee']['pan_no'] ?? '-' }}</td>
+             <td><b>BANK/CASH:</b> {{ $salary['employee']['bank_name'] ?? '-' }}</td>
+         </tr>
Removed / Before Commit

                                                
Added / After Commit
+ <!doctype html>
+ <html>
+ <head>
+     <meta charset="utf-8">
+     <title>Bulk Salary Print</title>
+     <style>
+         @page { size: A4 landscape; margin: 6mm; }
+         body { font-family: Arial, sans-serif; color: #000; font-size: 8px; }
+         .toolbar { margin-bottom: 10px; }
+         .toolbar button { padding: 6px 14px; }
+         .print-page { page-break-after: always; }
+         .salary-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
+         .salary-slip { border: 1px solid #000; padding: 3px; min-height: 60mm; page-break-inside: avoid; }
+         .slip-title { text-align: center; font-weight: 700; font-size: 8px; }
+         .slip-subtitle { text-align: center; text-decoration: underline; margin-bottom: 2px; }
+         table { width: 100%; border-collapse: collapse; }
+         td, th { border: 1px solid #000; padding: 1px 2px; }
+         .slip-meta { margin-bottom: 2px; }
Removed / Before Commit

                                                
Added / After Commit
+ <!doctype html>
+ <html>
+ <head>
+     <meta charset="utf-8">
+     <title>Salary Print Format 1</title>
+     <style>
+         @page { size: A4 landscape; margin: 8mm; }
+         body { font-family: Arial, sans-serif; color: #000; font-size: 12px; }
+         .toolbar { margin-bottom: 10px; }
+         .toolbar button { padding: 6px 14px; }
+         .format-one-slip { width: 100%; max-width: 270mm; margin: 0 auto; }
+         table { width: 100%; border-collapse: collapse; }
+         td, th { border: 1px solid #000; padding: 3px 5px; line-height: 1.15; }
+         th { text-align: center; font-size: 13px; }
+         .amount { text-align: right; min-width: 70px; }
+         .total { font-weight: 700; }
+         @media print { .toolbar { display: none; } }
+     </style>
Removed / Before Commit

                                                
Added / After Commit
+ <!doctype html>
+ <html>
+ <head>
+     <meta charset="utf-8">
+     <title>Salary Slip</title>
+     <style>
+         @page { size: A4 landscape; margin: 8mm; }
+         body { font-family: Arial, sans-serif; color: #000; font-size: 12px; }
+         .toolbar { margin-bottom: 10px; }
+         .toolbar button { padding: 6px 14px; }
+         .salary-slip { width: 100%; max-width: 270mm; margin: 0 auto; page-break-inside: avoid; }
+         .text-center { text-align: center; }
+         h3 { margin: 0; font-size: 17px; text-decoration: underline; }
+         h4 { margin: 2px 0 8px; font-size: 14px; text-decoration: underline; }
+         .top-info { display: grid; grid-template-columns: 1.25fr 1fr 1fr 1fr; gap: 4px 18px; margin-bottom: 6px; }
+         .leave-row { display: flex; justify-content: center; gap: 28px; margin-bottom: 6px; }
+         table { width: 100%; border-collapse: collapse; }
+         td, th { border: 1px solid #000; padding: 4px 6px; }
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('content')
+ @php
+     $salary = $snapshot->salary_json;
+     $monthNames = [1=>'January',2=>'February',3=>'March',4=>'April',5=>'May',6=>'June',7=>'July',8=>'August',9=>'September',10=>'October',11=>'November',12=>'December'];
+     $isCurrent = (int) $month === now()->month && (int) $year === now()->year;
+ @endphp
+ 
+ <div class="card">
+     <div class="card-header py-3">
+         <div class="d-flex justify-content-between align-items-center">
+             <h4 class="mb-0"><b>Salary Slip</b></h4>
+             <div class="d-flex gap-2">
+                 <a href="{{ route('finance-staff-details.index') }}" class="btn btn-secondary"><i class="fas fa-arrow-left"></i> Back</a>
+                 @if($isCurrent)
+                     <a href="{{ route('finance-salaries.show', [$staff, 'month' => $month, 'year' => $year, 'regenerate' => 1]) }}" class="btn btn-warning"><i class="fas fa-sync"></i> Regenerate</a>
+                 @endif
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('content')
+ @php
+     $displayDate = function ($date) {
+         return $date ? \Carbon\Carbon::parse($date)->format('d-m-Y') : '-';
+     };
+ 
+     $staffFields = [
+         'name' => 'Name',
+         'category' => 'Category',
+         'group_name' => 'Group Name',
+         'dob' => 'Date of Birth',
+         'joining_date' => 'Date of Joining',
+         'retirement_date' => 'Date of Retirement',
+         'father_name' => 'Father Name',
+         'pan_no' => 'PAN No',
+         'basic_salary' => 'Basic Salary',
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('content')
+ <div class="card">
+     <div class="card-header py-3">
+         <div class="row align-items-end">
+             <div class="col-md-4">
+                 <h4 class="mb-0"><b>Finance Staff Details</b></h4>
+             </div>
+             <div class="col-md-8">
+                 <form method="GET" action="{{ route('finance-staff-details.index') }}" class="row g-2 justify-content-end">
+                     <div class="col-md-3">
+                         <label class="form-label fw-bold">Employee ID</label>
+                         <input type="text" name="employee_number" class="form-control"
+                             value="{{ request('employee_number') }}" placeholder="Employee ID">
+                     </div>
+                     <div class="col-md-3">
+                         <label class="form-label fw-bold">Employee Category</label>
Removed / Before Commit

                                                
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('content')
+ @php
+     $displayDate = function ($date) {
+         return $date ? \Carbon\Carbon::parse($date)->format('d-m-Y') : '-';
+     };
+ 
+     $staffFields = [
+         'name' => 'Name',
+         'category' => 'Category',
+         'group_name' => 'Group Name',
+         'dob' => 'Date of Birth',
+         'joining_date' => 'Date of Joining',
+         'retirement_date' => 'Date of Retirement',
+         'father_name' => 'Father Name',
+         'pan_no' => 'PAN No',
+         'basic_salary' => 'Basic Salary',
Removed / Before Commit
- @extends('layouts.app')
- 
- @section('content')
- <div class="container-fluid">
- <div class="d-flex justify-content-between align-items-center mb-3">
- <h4 class="mb-0"><i class="fas fa-file-signature"></i> Leave Part 2 No</h4>
- <div class="card-body">
- <form action="{{ route('leave.part-2-no') }}" method="GET">
- <div class="row g-3 align-items-end">
-                     <div class="col-md-3">
- <label for="start_date" class="form-label">Start Date</label>
- <input type="date" name="start_date" id="start_date" class="form-control"
- value="{{ old('start_date', $filters['start_date'] ?? '') }}" required>
- </div>
-                     <div class="col-md-3">
- <label for="end_date" class="form-label">End Date</label>
- <input type="date" name="end_date" id="end_date" class="form-control"
- value="{{ old('end_date', $filters['end_date'] ?? '') }}" required>
Added / After Commit
+ @extends('layouts.app')
+ 
+ @section('content')
+ @php
+     $hasSearch = !empty($filters['staff_part_2_no']) || !empty($filters['existing_do_2_part_no']);
+     $isStaffSearch = $searchType === 'staff';
+     $selectedPartNo = $isStaffSearch ? ($filters['staff_part_2_no'] ?? '') : ($filters['existing_do_2_part_no'] ?? '');
+ @endphp
+ 
+ <div class="container-fluid">
+ <div class="d-flex justify-content-between align-items-center mb-3">
+ <h4 class="mb-0"><i class="fas fa-file-signature"></i> Leave Part 2 No</h4>
+ <div class="card-body">
+ <form action="{{ route('leave.part-2-no') }}" method="GET">
+ <div class="row g-3 align-items-end">
+                     <div class="col-md-2">
+ <label for="start_date" class="form-label">Start Date</label>
+ <input type="date" name="start_date" id="start_date" class="form-control"
Removed / Before Commit
- use App\Http\Controllers\CommonController;
- use App\Http\Controllers\LpoFundController;
- use App\Http\Controllers\FinancialPowerController;
- use App\Http\Controllers\UrgencyController;
- use App\Http\Controllers\DashboardController;
- use App\Http\Controllers\OldDataController;
- Route::post('attendance/upload', [AttendanceController::class, 'upload'])->name('attendance.upload');
- Route::put('attendance/{id}', [AttendanceController::class, 'update'])->name('attendance.update');
- Route::delete('attendance/{id}', [AttendanceController::class, 'destroy'])->name('attendance.destroy');
- 
- Route::post('get-employee-leave', [AttendanceController::class, 'getEmployeeLeave'])->name('get-employee-leave');
- Route::post('get-leave-types-with-balance', [AttendanceController::class, 'getLeaveTypesWithBalance'])->name('get-leave-types-with-balance');
- Route::get('leave-part-2-no', [LeaveController::class, 'part2No'])->name('leave.part-2-no');
- Route::post('leave-part-2-no/apply', [LeaveController::class, 'applyPart2No'])->name('leave.part-2-no.apply');
- Route::get('leave-part-2-no/history/export', [LeaveController::class, 'exportPart2NoHistory'])->name('leave.part-2-no.history.export');
- Route::get('leave-approve', [LeaveApprovalController::class, 'index'])->name('leave.approve.index');
- Route::post('leave-approve/{id}/approve', [LeaveApprovalController::class, 'approve'])->name('leave.approve');
- Route::post('leave-approve/{id}/reject', [LeaveApprovalController::class, 'reject'])->name('leave.reject');
Added / After Commit
+ use App\Http\Controllers\CommonController;
+ use App\Http\Controllers\LpoFundController;
+ use App\Http\Controllers\FinancialPowerController;
+ use App\Http\Controllers\FinanceDeductionTitleController;
+ use App\Http\Controllers\FinanceStaffDetailsController;
+ use App\Http\Controllers\SalaryController;
+ use App\Http\Controllers\BulkSalaryController;
+ use App\Http\Controllers\UrgencyController;
+ use App\Http\Controllers\DashboardController;
+ use App\Http\Controllers\OldDataController;
+ Route::post('attendance/upload', [AttendanceController::class, 'upload'])->name('attendance.upload');
+ Route::put('attendance/{id}', [AttendanceController::class, 'update'])->name('attendance.update');
+ Route::delete('attendance/{id}', [AttendanceController::class, 'destroy'])->name('attendance.destroy');
+         Route::get('finance-staff-details', [FinanceStaffDetailsController::class, 'index'])->name('finance-staff-details.index');
+         Route::get('finance-staff-details/{staff}/edit', [FinanceStaffDetailsController::class, 'edit'])->name('finance-staff-details.edit');
+         Route::put('finance-staff-details/{staff}', [FinanceStaffDetailsController::class, 'update'])->name('finance-staff-details.update');
+         Route::get('finance-staff-details/{staff}/payment-recovery', [FinanceStaffDetailsController::class, 'paymentRecovery'])->name('finance-staff-details.payment-recovery');
+         Route::put('finance-staff-details/{staff}/payment-recovery', [FinanceStaffDetailsController::class, 'updatePaymentRecovery'])->name('finance-staff-details.payment-recovery.update');