first(); if (!$marlon) { $this->command->error('❌ Company user marlon.domagtoy@sebconnexion.com not found. Please register this account first.'); return; } $this->companyId = $marlon->id; $this->userMap[1] = $marlon->id; // Map old user 1 (Marlon) to actual ID $this->command->info("Using company ID: {$this->companyId} (Marlon Domagtoy)"); DB::transaction(function () { $this->createAdminUser(); $this->importDepartments(); $this->importDesignations(); $this->importShifts(); $this->importLeaveTypes(); $this->importUsers(); $this->importEmployees(); $this->importAttendances(); $this->importAttendanceLogs(); $this->importPayGroups(); $this->importSalaryStructures(); $this->command->info("✅ SEB Connexion data import complete!"); $this->command->info(" Users: " . count($this->userMap)); $this->command->info(" Shifts: " . count($this->shiftMap)); $this->command->info(" Attendances: " . count($this->attendanceMap)); }); } private function createAdminUser(): void { $existing = User::where('email', 'admin@sebconnexion.com')->first(); if ($existing) { $this->command->warn('Admin user admin@sebconnexion.com already exists, skipping.'); return; } User::create([ 'name' => 'SEB Admin', 'email' => 'admin@sebconnexion.com', 'password' => Hash::make('123456'), 'type' => 'company', 'created_by' => $this->companyId, 'lang' => 'en', 'is_enable_login' => 1, 'is_disable' => 0, ]); $this->command->info('Created admin user: admin@sebconnexion.com'); } private function importDepartments(): void { $departments = [ ['old_id' => 1, 'department_name' => 'Head Office'], ['old_id' => 2, 'department_name' => 'Operations'], ]; foreach ($departments as $dept) { $record = DB::table('departments')->insertGetId([ 'department_name' => $dept['department_name'], 'created_by' => $this->companyId, 'created_at' => now(), 'updated_at' => now(), ]); $this->deptMap[$dept['old_id']] = $record; } $this->command->info("Imported " . count($departments) . " departments"); } private function importDesignations(): void { // Source: old_id, name, department_id (old) $designations = [ ['old_id' => 1, 'name' => 'Head of Operations', 'dept_old' => 1], ['old_id' => 2, 'name' => 'Restaurant Manager', 'dept_old' => 2], ['old_id' => 3, 'name' => 'Assistant Restaurant Manager', 'dept_old' => 2], ['old_id' => 4, 'name' => 'Restaurant Supervisor', 'dept_old' => 2], ['old_id' => 5, 'name' => 'Kitchen Staff', 'dept_old' => 2], ['old_id' => 6, 'name' => 'Dining Staff', 'dept_old' => 2], ['old_id' => 7, 'name' => 'Graphic Artist', 'dept_old' => 1], ['old_id' => 8, 'name' => 'Cashier', 'dept_old' => 1], ]; foreach ($designations as $d) { $record = DB::table('designations')->insertGetId([ 'designation_name' => $d['name'], 'department_id' => $this->deptMap[$d['dept_old']] ?? null, 'created_by' => $this->companyId, 'created_at' => now(), 'updated_at' => now(), ]); $this->desigMap[$d['old_id']] = $record; } $this->command->info("Imported " . count($designations) . " designations"); } private function importShifts(): void { $shifts = [ ['old_id' => 1, 'name' => 'OPS 12:00AM-09:00AM', 'start' => '00:00:00', 'end' => '09:00:00', 'night' => true], ['old_id' => 2, 'name' => 'OPS 12:30AM-09:30AM', 'start' => '00:30:00', 'end' => '09:30:00', 'night' => true], ['old_id' => 3, 'name' => 'OPS 01:00AM-10:00AM', 'start' => '01:00:00', 'end' => '10:00:00', 'night' => true], ['old_id' => 4, 'name' => 'OPS 01:30AM-10:30AM', 'start' => '01:30:00', 'end' => '10:30:00', 'night' => true], ['old_id' => 5, 'name' => 'OPS 02:00AM-11:00AM', 'start' => '02:00:00', 'end' => '11:00:00', 'night' => true], ['old_id' => 6, 'name' => 'OPS 02:30AM-11:30AM', 'start' => '02:30:00', 'end' => '11:30:00', 'night' => true], ['old_id' => 7, 'name' => 'OPS 03:00AM-12:00PM', 'start' => '03:00:00', 'end' => '12:00:00', 'night' => true], ['old_id' => 8, 'name' => 'OPS 03:30AM-12:30PM', 'start' => '03:30:00', 'end' => '12:30:00', 'night' => true], ['old_id' => 9, 'name' => 'OPS 04:00AM-01:00PM', 'start' => '04:00:00', 'end' => '13:00:00', 'night' => true], ['old_id' => 10, 'name' => 'OPS 04:30AM-01:30PM', 'start' => '04:30:00', 'end' => '13:30:00', 'night' => true], ['old_id' => 11, 'name' => 'OPS 05:00AM-02:00PM', 'start' => '05:00:00', 'end' => '14:00:00', 'night' => true], ['old_id' => 12, 'name' => 'OPS 05:30AM-02:30PM', 'start' => '05:30:00', 'end' => '14:30:00', 'night' => true], ['old_id' => 13, 'name' => 'OPS 06:00AM-03:00PM', 'start' => '06:00:00', 'end' => '15:00:00', 'night' => false], ['old_id' => 14, 'name' => 'OPS 06:30AM-03:30PM', 'start' => '06:30:00', 'end' => '15:30:00', 'night' => false], ['old_id' => 15, 'name' => 'OPS 07:00AM-04:00PM', 'start' => '07:00:00', 'end' => '16:00:00', 'night' => false], ['old_id' => 16, 'name' => 'OPS 07:30AM-04:30PM', 'start' => '07:30:00', 'end' => '16:30:00', 'night' => false], ['old_id' => 17, 'name' => 'OPS 08:00AM-05:00PM', 'start' => '08:00:00', 'end' => '17:00:00', 'night' => false], ['old_id' => 18, 'name' => 'OPS 08:30AM-05:30PM', 'start' => '08:30:00', 'end' => '17:30:00', 'night' => false], ['old_id' => 19, 'name' => 'OPS 09:00AM-06:00PM', 'start' => '09:00:00', 'end' => '18:00:00', 'night' => false], ['old_id' => 20, 'name' => 'OPS 09:30AM-06:30PM', 'start' => '09:30:00', 'end' => '18:30:00', 'night' => false], ['old_id' => 21, 'name' => 'OPS 10:00AM-07:00PM', 'start' => '10:00:00', 'end' => '19:00:00', 'night' => false], ['old_id' => 22, 'name' => 'OPS 10:30AM-07:30PM', 'start' => '10:30:00', 'end' => '19:30:00', 'night' => false], ['old_id' => 23, 'name' => 'OPS 11:00AM-08:00PM', 'start' => '11:00:00', 'end' => '20:00:00', 'night' => false], ['old_id' => 24, 'name' => 'OPS 11:30AM-08:30PM', 'start' => '11:30:00', 'end' => '20:30:00', 'night' => false], ['old_id' => 25, 'name' => 'OPS 12:00PM-09:00PM', 'start' => '12:00:00', 'end' => '21:00:00', 'night' => false], ['old_id' => 26, 'name' => 'OPS 12:30PM-09:30PM', 'start' => '12:30:00', 'end' => '21:30:00', 'night' => false], ['old_id' => 27, 'name' => 'OPS 01:00PM-10:00PM', 'start' => '13:00:00', 'end' => '22:00:00', 'night' => false], ['old_id' => 28, 'name' => 'OPS 01:30PM-10:30PM', 'start' => '13:30:00', 'end' => '22:30:00', 'night' => false], ['old_id' => 29, 'name' => 'OPS 02:00PM-11:00PM', 'start' => '14:00:00', 'end' => '23:00:00', 'night' => false], ['old_id' => 30, 'name' => 'OPS 02:30PM-11:30PM', 'start' => '14:30:00', 'end' => '23:30:00', 'night' => false], ['old_id' => 31, 'name' => 'OPS 03:00PM-12:00AM', 'start' => '15:00:00', 'end' => '00:00:00', 'night' => false], ['old_id' => 32, 'name' => 'OPS 03:30PM-12:30AM', 'start' => '15:30:00', 'end' => '00:30:00', 'night' => false], ['old_id' => 33, 'name' => 'OPS 04:00PM-01:00AM', 'start' => '16:00:00', 'end' => '01:00:00', 'night' => false], ['old_id' => 34, 'name' => 'OPS 04:30PM-01:30AM', 'start' => '16:30:00', 'end' => '01:30:00', 'night' => false], ['old_id' => 35, 'name' => 'OPS 05:00PM-02:00AM', 'start' => '17:00:00', 'end' => '02:00:00', 'night' => false], ['old_id' => 36, 'name' => 'OPS 05:30PM-02:30AM', 'start' => '17:30:00', 'end' => '02:30:00', 'night' => false], ['old_id' => 37, 'name' => 'OPS 06:00PM-03:00AM', 'start' => '18:00:00', 'end' => '03:00:00', 'night' => false], ['old_id' => 38, 'name' => 'OPS 06:30PM-03:30AM', 'start' => '18:30:00', 'end' => '03:30:00', 'night' => false], ['old_id' => 39, 'name' => 'OPS 07:00PM-04:00AM', 'start' => '19:00:00', 'end' => '04:00:00', 'night' => false], ['old_id' => 40, 'name' => 'OPS 07:30PM-04:30AM', 'start' => '19:30:00', 'end' => '04:30:00', 'night' => false], ['old_id' => 41, 'name' => 'OPS 08:00PM-05:00AM', 'start' => '20:00:00', 'end' => '05:00:00', 'night' => true], ['old_id' => 42, 'name' => 'OPS 08:30PM-05:30AM', 'start' => '20:30:00', 'end' => '05:30:00', 'night' => true], ['old_id' => 43, 'name' => 'OPS 09:00PM-06:00AM', 'start' => '21:00:00', 'end' => '06:00:00', 'night' => true], ['old_id' => 44, 'name' => 'OPS 09:30PM-06:30AM', 'start' => '21:30:00', 'end' => '06:30:00', 'night' => true], ['old_id' => 45, 'name' => 'OPS 10:00PM-07:00AM', 'start' => '22:00:00', 'end' => '07:00:00', 'night' => true], ['old_id' => 46, 'name' => 'OPS 10:30PM-07:30AM', 'start' => '22:30:00', 'end' => '07:30:00', 'night' => true], ['old_id' => 47, 'name' => 'OPS 11:00PM-08:00AM', 'start' => '23:00:00', 'end' => '08:00:00', 'night' => true], ['old_id' => 48, 'name' => 'OPS 11:30PM-08:30AM', 'start' => '23:30:00', 'end' => '08:30:00', 'night' => true], ]; foreach ($shifts as $s) { $record = DB::table('shifts')->insertGetId([ 'shift_name' => $s['name'], 'start_time' => $s['start'], 'end_time' => $s['end'], 'is_night_shift' => $s['night'], 'created_by' => $this->companyId, 'created_at' => now(), 'updated_at' => now(), ]); $this->shiftMap[$s['old_id']] = $record; } $this->command->info("Imported " . count($shifts) . " shifts"); } private function importLeaveTypes(): void { $leaveTypes = [ ['old_id' => 1, 'name' => 'Vacation Leave', 'max_days' => 11, 'is_paid' => true], ['old_id' => 2, 'name' => 'Sick Leave', 'max_days' => 11, 'is_paid' => true], ['old_id' => 3, 'name' => 'Birthday Leave', 'max_days' => 1, 'is_paid' => true], ['old_id' => 4, 'name' => 'Leave Without Pay', 'max_days' => 100, 'is_paid' => false], ]; foreach ($leaveTypes as $lt) { $record = DB::table('leave_types')->insertGetId([ 'name' => $lt['name'], 'max_days_per_year' => $lt['max_days'], 'is_paid' => $lt['is_paid'], 'created_by' => $this->companyId, 'created_at' => now(), 'updated_at' => now(), ]); $this->leaveTypeMap[$lt['old_id']] = $record; } $this->command->info("Imported " . count($leaveTypes) . " leave types"); } private function importUsers(): void { // Source users: id, name, email, phone, gender, dob, date_of_joining, shift_id(old), team_id(old), designation_id(old) $users = [ ['old_id' => 1, 'name' => 'Marlon Domagtoy', 'email' => 'marlon.domagtoy@sebconnexion.com', 'phone' => '9151784027', 'gender' => 'male', 'dob' => '1991-01-31', 'doj' => '2024-05-14', 'type' => 'hr', 'shift_old' => 1, 'dept_old' => 1, 'desig_old' => 1], ['old_id' => 2, 'name' => 'Ana Regina Mariano', 'email' => 'armariano@yahoo.com', 'phone' => '9955646175', 'gender' => 'female', 'dob' => '1985-04-25', 'doj' => '2019-08-27', 'type' => 'staff', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 2], ['old_id' => 3, 'name' => 'Rhea Jane Belchez', 'email' => 'eyajanepot0610@gmail.com', 'phone' => '9099491457', 'gender' => 'female', 'dob' => '1997-10-16', 'doj' => '2022-05-05', 'type' => 'staff', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 2], ['old_id' => 4, 'name' => 'Reynah Lyn Guevarra', 'email' => 'rbmguevarra@gmail.com', 'phone' => '9453746700', 'gender' => 'female', 'dob' => '1994-12-11', 'doj' => '2024-04-15', 'type' => 'staff', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 3], ['old_id' => 5, 'name' => 'Mart Ace Guano', 'email' => 'g_martace@yahoo.com', 'phone' => '9270790192', 'gender' => 'male', 'dob' => '1994-05-20', 'doj' => '2021-10-01', 'type' => 'staff', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 4], ['old_id' => 6, 'name' => 'Dinh Chavez', 'email' => 'hao.chavez@gmail.com', 'phone' => '9366136920', 'gender' => 'female', 'dob' => '1983-04-25', 'doj' => '2018-12-03', 'type' => 'staff', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 5], ['old_id' => 7, 'name' => 'Francis Eleazar Londonio', 'email' => 'eleazarfrancis112@gmail.com', 'phone' => '9503260264', 'gender' => 'male', 'dob' => '1996-12-12', 'doj' => '2022-11-04', 'type' => 'staff', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 5], ['old_id' => 8, 'name' => 'Paul Rei Paas', 'email' => 'paulreichase97@gmail.com', 'phone' => '9053023539', 'gender' => 'male', 'dob' => '1997-07-01', 'doj' => '2023-06-29', 'type' => 'staff', 'shift_old' => 17, 'dept_old' => 1, 'desig_old' => 7], ['old_id' => 9, 'name' => 'Princess Rose Acosta', 'email' => 'ladyrose021992@gmail.com', 'phone' => '9651422794', 'gender' => 'female', 'dob' => '1992-11-12', 'doj' => '2024-11-04', 'type' => 'staff', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 5], ['old_id' => 10, 'name' => 'Donna Marie Moreno', 'email' => 'donnamarie.moreno.1975@gmail.com', 'phone' => '9563008450', 'gender' => 'female', 'dob' => '1975-06-26', 'doj' => '2024-11-25', 'type' => 'staff', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 5], ]; $password = Hash::make('123456'); foreach ($users as $u) { // Skip if email already exists $existing = User::where('email', $u['email'])->first(); if ($existing) { $this->userMap[$u['old_id']] = $existing->id; $this->command->warn("User {$u['email']} already exists (ID: {$existing->id}), mapped."); continue; } $newUser = User::create([ 'name' => $u['name'], 'email' => $u['email'], 'password' => $password, 'type' => $u['type'], 'created_by' => $this->companyId, 'lang' => 'en', 'is_enable_login' => 1, 'is_disable' => 0, 'email_verified_at' => now(), ]); $this->userMap[$u['old_id']] = $newUser->id; } $this->command->info("Imported " . count($this->userMap) . " users"); } private function importEmployees(): void { $employees = [ ['old_id' => 1, 'emp_code' => 'SEB-001', 'gender' => 'male', 'dob' => '1991-01-31', 'doj' => '2024-05-14', 'shift_old' => 1, 'dept_old' => 1, 'desig_old' => 1], ['old_id' => 2, 'emp_code' => 'SEB2018-2008T', 'gender' => 'female', 'dob' => '1985-04-25', 'doj' => '2019-08-27', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 2], ['old_id' => 3, 'emp_code' => 'SEB2018-2024T', 'gender' => 'female', 'dob' => '1997-10-16', 'doj' => '2022-05-05', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 2], ['old_id' => 4, 'emp_code' => 'SEB2024-2101T', 'gender' => 'female', 'dob' => '1994-12-11', 'doj' => '2024-04-15', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 3], ['old_id' => 5, 'emp_code' => 'SEB2018-2023T', 'gender' => 'male', 'dob' => '1994-05-20', 'doj' => '2021-10-01', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 4], ['old_id' => 6, 'emp_code' => 'SEB2018-2013T', 'gender' => 'female', 'dob' => '1983-04-25', 'doj' => '2018-12-03', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 5], ['old_id' => 7, 'emp_code' => 'SEB2018-2033T', 'gender' => 'male', 'dob' => '1996-12-12', 'doj' => '2022-11-04', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 5], ['old_id' => 8, 'emp_code' => 'SEB2023-2068H', 'gender' => 'male', 'dob' => '1997-07-01', 'doj' => '2023-06-29', 'shift_old' => 17, 'dept_old' => 1, 'desig_old' => 7], ['old_id' => 9, 'emp_code' => 'SEB2024-2109T', 'gender' => 'female', 'dob' => '1992-11-12', 'doj' => '2024-11-04', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 5], ['old_id' => 10, 'emp_code' => 'SEB2024-2111T', 'gender' => 'female', 'dob' => '1975-06-26', 'doj' => '2024-11-25', 'shift_old' => 32, 'dept_old' => 2, 'desig_old' => 5], ]; foreach ($employees as $emp) { $userId = $this->userMap[$emp['old_id']] ?? null; if (!$userId) continue; // Skip if employee already exists for this user if (DB::table('employees')->where('user_id', $userId)->exists()) { continue; } DB::table('employees')->insert([ 'employee_id' => $emp['emp_code'], 'user_id' => $userId, 'date_of_birth' => $emp['dob'], 'gender' => $emp['gender'], 'date_of_joining' => $emp['doj'], 'department_id' => $this->deptMap[$emp['dept_old']] ?? null, 'designation_id' => $this->desigMap[$emp['desig_old']] ?? null, 'created_by' => $this->companyId, 'created_at' => now(), 'updated_at' => now(), ]); } $this->command->info("Imported " . count($employees) . " employee records"); } private function importAttendances(): void { // Read source attendance data from the SQL file dynamically $sourceFile = base_path('rame_seb.sql'); if (!file_exists($sourceFile)) { $this->command->error("Source file rame_seb.sql not found at: $sourceFile"); return; } $content = file_get_contents($sourceFile); // Status mapping: source → target enum('present','half day','absent') $statusMap = [ 'checked_in' => 'present', 'checked_out' => 'present', 'auto_checked_out' => 'present', 'present' => 'present', 'absent' => 'absent', 'leave' => 'absent', 'half-Day' => 'half day', ]; // Extract all INSERT blocks for `attendances` table preg_match_all( '/INSERT INTO `attendances`[^;]+;/s', $content, $insertBlocks ); $count = 0; foreach ($insertBlocks[0] as $block) { // Extract all value tuples preg_match_all('/\(([^)]+)\)/', $block, $tuples); foreach ($tuples[1] as $tuple) { // Skip the column list tuple (contains backticks) if (str_contains($tuple, '`')) continue; $values = str_getcsv($tuple, ',', "'"); $values = array_map('trim', $values); // Map: 0=id, 1=user_id, 2=date, 3=check_in_time, 4=check_out_time, 5=late_reason, // 6=shift_id, 7=early_checkout_reason, 8=working_hours, 9=break_hours, // 10=late_hours, 11=early_hours, 12=overtime_hours, 13=notes, // 14=is_holiday, 15=is_weekend, 16=is_half_day, 17=status, // 18=approved_by_id, 19=approved_at, 20=created_by_id, 21=updated_by_id, // 22=tenant_id, 23=deleted_at, 24=created_at, 25=updated_at $oldId = (int) $values[0]; $oldUserId = (int) $values[1]; $newUserId = $this->userMap[$oldUserId] ?? null; if (!$newUserId) continue; $oldShiftId = $values[6] !== 'NULL' ? (int) $values[6] : null; $newShiftId = $oldShiftId ? ($this->shiftMap[$oldShiftId] ?? null) : null; $checkIn = $values[3] !== 'NULL' ? $values[3] : null; $checkOut = $values[4] !== 'NULL' ? $values[4] : null; // Skip absent records with no clock_in — target DB requires NOT NULL if (!$checkIn) { continue; } // shift_id is NOT NULL in target — fall back to first shift if (!$newShiftId) { $newShiftId = reset($this->shiftMap) ?: 1; } $newAttId = DB::table('attendances')->insertGetId([ 'employee_id' => $newUserId, 'date' => $values[2], 'clock_in' => $checkIn, 'clock_out' => $checkOut, 'shift_id' => $newShiftId, 'working_hours' => (float) $values[8], 'break_hour' => (float) $values[9], 'late_hours' => (float) $values[10], 'early_hours' => (float) $values[11], 'overtime_hours' => (float) $values[12], 'total_hour' => (float) $values[8], 'notes' => $values[13] !== 'NULL' ? $values[13] : null, 'is_holiday' => (int) $values[14], 'is_weekend' => (int) $values[15], 'is_half_day' => (int) $values[16], 'status' => $statusMap[$values[17]] ?? 'absent', 'late_reason' => $values[5] !== 'NULL' ? $values[5] : null, 'early_checkout_reason' => $values[7] !== 'NULL' ? $values[7] : null, 'created_by' => $this->companyId, 'created_at' => $values[24] !== 'NULL' ? $values[24] : now(), 'updated_at' => $values[25] !== 'NULL' ? $values[25] : now(), ]); $this->attendanceMap[$oldId] = $newAttId; $count++; } } $this->command->info("Imported $count attendance records"); } private function importAttendanceLogs(): void { $sourceFile = base_path('rame_seb.sql'); $content = file_get_contents($sourceFile); // Build a lookup: new_attendance_id → {date, employee_id, clock_in} $attInfo = []; foreach ($this->attendanceMap as $oldId => $newId) { $row = DB::table('attendances')->where('id', $newId)->first(['date', 'employee_id', 'clock_in']); if ($row) { $attInfo[$newId] = $row; } } preg_match_all( '/INSERT INTO `attendance_logs`[^;]+;/s', $content, $insertBlocks ); $count = 0; foreach ($insertBlocks[0] as $block) { preg_match_all('/\(([^)]+)\)/', $block, $tuples); foreach ($tuples[1] as $tuple) { if (str_contains($tuple, '`')) continue; $values = str_getcsv($tuple, ',', "'"); $values = array_map('trim', $values); $oldAttId = (int) $values[1]; $newAttId = $this->attendanceMap[$oldAttId] ?? null; if (!$newAttId) continue; $info = $attInfo[$newAttId] ?? null; // Derive user_id from attendance record if source is NULL $oldUserId = $values[2] !== 'NULL' ? (int) $values[2] : null; $newUserId = $oldUserId ? ($this->userMap[$oldUserId] ?? null) : null; if (!$newUserId && $info) { $newUserId = $info->employee_id; } if (!$newUserId) continue; // Derive date: source → attendance record → created_at $date = $values[3] !== 'NULL' ? $values[3] : null; if (!$date && $info) { $date = $info->date; } if (!$date) { $date = $values[23] !== 'NULL' ? substr($values[23], 0, 10) : now()->toDateString(); } // Derive logged_at: source → clock_in → created_at $loggedAt = $values[5] !== 'NULL' ? $values[5] : null; if (!$loggedAt && $info) { $loggedAt = $info->clock_in; } if (!$loggedAt) { $loggedAt = $values[23] !== 'NULL' ? $values[23] : now()->toDateTimeString(); } $time = $values[4] !== 'NULL' ? $values[4] : null; DB::table('attendance_logs')->insert([ 'attendance_id' => $newAttId, 'user_id' => $newUserId, 'date' => $date, 'time' => $time, 'logged_at' => $loggedAt, 'type' => $values[6], 'source' => 'import', 'created_by' => $this->companyId, 'created_at' => $values[23] !== 'NULL' ? $values[23] : now(), 'updated_at' => $values[24] !== 'NULL' ? $values[24] : now(), ]); $count++; } } $this->command->info("Imported $count attendance log records"); } private function importPayGroups(): void { $payGroups = [ ['old_id' => 1, 'name' => 'Managerial / Exempt', 'type' => 'office', 'annual_working_days' => 312.00], ['old_id' => 2, 'name' => 'Daily Paid / Piece-Rate', 'type' => 'daily', 'annual_working_days' => 312.00], ['old_id' => 3, 'name' => 'Office Staff', 'type' => 'office', 'annual_working_days' => 261.00], ]; foreach ($payGroups as $pg) { $record = DB::table('pay_groups')->insertGetId([ 'name' => $pg['name'], 'type' => $pg['type'], 'annual_working_days' => $pg['annual_working_days'], 'created_by' => $this->companyId, 'created_at' => now(), 'updated_at' => now(), ]); $this->payGroupMap[$pg['old_id']] = $record; } $this->command->info("Imported " . count($payGroups) . " pay groups"); } private function importSalaryStructures(): void { // Only import the ACTIVE salary structures (latest per user) // Users 2,3,4,5 corrected to is_exempt=1 (Managerial/Exempt) $structures = [ // user_old, pay_group_old, gross_salary, daily_rate, pay_frequency, is_exempt ['user_old' => 1, 'pg_old' => 2, 'gross' => 1.00, 'daily' => 0.04, 'freq' => 'daily', 'exempt' => false], ['user_old' => 2, 'pg_old' => 1, 'gross' => 26000.00, 'daily' => 1000.00, 'freq' => 'semi-monthly', 'exempt' => true], ['user_old' => 3, 'pg_old' => 1, 'gross' => 26000.00, 'daily' => 1000.00, 'freq' => 'semi-monthly', 'exempt' => true], ['user_old' => 4, 'pg_old' => 1, 'gross' => 24000.00, 'daily' => 923.08, 'freq' => 'semi-monthly', 'exempt' => true], ['user_old' => 5, 'pg_old' => 1, 'gross' => 22000.00, 'daily' => 846.15, 'freq' => 'semi-monthly', 'exempt' => true], ['user_old' => 6, 'pg_old' => 2, 'gross' => 18360.00, 'daily' => 765.00, 'freq' => 'daily', 'exempt' => false], ['user_old' => 7, 'pg_old' => 2, 'gross' => 17760.00, 'daily' => 740.00, 'freq' => 'daily', 'exempt' => false], ['user_old' => 8, 'pg_old' => 3, 'gross' => 22000.00, 'daily' => 846.15, 'freq' => 'semi-monthly', 'exempt' => false], ['user_old' => 9, 'pg_old' => 2, 'gross' => 16680.00, 'daily' => 695.00, 'freq' => 'daily', 'exempt' => false], ['user_old' => 10, 'pg_old' => 2, 'gross' => 16680.00, 'daily' => 695.00, 'freq' => 'daily', 'exempt' => false], ]; $count = 0; foreach ($structures as $s) { $userId = $this->userMap[$s['user_old']] ?? null; if (!$userId) continue; // Skip if salary structure already exists for this user if (DB::table('employee_salary_structures')->where('user_id', $userId)->where('created_by', $this->companyId)->exists()) { continue; } DB::table('employee_salary_structures')->insert([ 'user_id' => $userId, 'gross_salary' => $s['gross'], 'daily_rate' => $s['daily'], 'pay_frequency' => $s['freq'], 'pay_group_id' => $this->payGroupMap[$s['pg_old']] ?? null, 'is_exempt' => $s['exempt'], 'status' => 'active', 'created_by' => $this->companyId, 'created_at' => now(), 'updated_at' => now(), ]); $count++; } $this->command->info("Imported $count salary structures (users 2,3,4,5 = exempt)"); } }