Explorar el Código

feat: ✨ feat (afastamentos) criada funcao de importar afastamentos

foi criada a funcao de importar excel para afastar associados, com base no exato mesmo excel da importacao de associados

fase:dev | origin:escopo
Gustavo Zanatta hace 1 día
padre
commit
1fdb7fb02d

+ 20 - 0
app/Http/Controllers/AssociadoImportController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\Jobs\SyncAfastamentosJob;
 use App\Jobs\SyncAssociadosJob;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
@@ -29,4 +30,23 @@ class AssociadoImportController extends Controller
             code: 202,
         );
     }
+
+    public function importAfastamentos(Request $request): JsonResponse
+    {
+        $request->validate([
+            'file' => 'required|file|mimes:xlsx|max:10240',
+        ]);
+
+        $importId = Str::uuid()->toString();
+        $filePath = Storage::putFileAs('imports', $request->file('file'), $importId . '.xlsx');
+
+        Cache::put($importId, ['status' => 'pending'], now()->addDay());
+
+        SyncAfastamentosJob::dispatch($filePath, $importId, auth()->id());
+
+        return $this->successResponse(
+            payload: ['import_id' => $importId],
+            code: 202,
+        );
+    }
 }

+ 1 - 0
app/Jobs/BaseImportJob.php

@@ -40,6 +40,7 @@ abstract class BaseImportJob implements ShouldQueue
                 'created'     => $stats['created'] ?? 0,
                 'updated'     => $stats['updated'] ?? 0,
                 'inactivated' => $stats['inactivated'] ?? 0,
+                'on_leave'    => $stats['on_leave'] ?? 0,
                 'imported_at' => now(),
             ]);
 

+ 18 - 0
app/Jobs/SyncAfastamentosJob.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Services\AssociadoImportService;
+
+class SyncAfastamentosJob extends BaseImportJob
+{
+    protected function getImportType(): string
+    {
+        return 'afastamento';
+    }
+
+    protected function runSync(string $filePath): array
+    {
+        return app(AssociadoImportService::class)->syncAfastamentosFromExcel($filePath, $this->userId);
+    }
+}

+ 1 - 0
app/Models/ImportLog.php

@@ -14,6 +14,7 @@ class ImportLog extends Model
         'created',
         'updated',
         'inactivated',
+        'on_leave',
         'imported_at',
     ];
 

+ 65 - 0
app/Services/AssociadoImportService.php

@@ -102,6 +102,71 @@ class AssociadoImportService
         ];
     }
 
+    public function syncAfastamentosFromExcel(string $filePath, int $byUserId): array
+    {
+        $import = new AssociadoImport();
+        Excel::import($import, $filePath);
+        $rows = $import->rows ?? collect();
+
+        $today      = Carbon::today()->toDateString();
+        $expiryDate = Carbon::now()->endOfMonth()->toDateString();
+
+        $existing = User::where('type', UserTypeEnum::ASSOCIADO)
+            ->whereNotNull('registration')
+            ->get()
+            ->keyBy('registration');
+
+        $seenRegistrations = [];
+        $created  = 0;
+        $onLeave  = 0;
+
+        foreach ($rows as $row) {
+            $registration = $row['registration'];
+            $name         = $row['name'];
+
+            if (isset($seenRegistrations[$registration])) {
+                continue;
+            }
+            $seenRegistrations[$registration] = true;
+
+            if ($existing->has($registration)) {
+                $user = $existing->get($registration);
+
+                if ($user->status !== UserStatusEnum::ON_LEAVE) {
+                    $user->status              = UserStatusEnum::ON_LEAVE;
+                    $user->on_leave_at         = now();
+                    $user->on_leave_by_user_id = $byUserId;
+                    $user->save();
+
+                    $onLeave++;
+                }
+            } else {
+                $firstName = $this->extractFirstName($name);
+                $password  = "{$firstName}2026";
+
+                User::create([
+                    'name'                 => $name,
+                    'password'             => Hash::make($password),
+                    'type'                 => UserTypeEnum::ASSOCIADO,
+                    'status'               => UserStatusEnum::ON_LEAVE,
+                    'registration'         => $registration,
+                    'admission_date'       => $today,
+                    'expiry_date'          => $expiryDate,
+                    'on_leave_at'          => now(),
+                    'on_leave_by_user_id'  => $byUserId,
+                ]);
+
+                $created++;
+            }
+        }
+
+        return [
+            'total'    => $rows->count(),
+            'created'  => $created,
+            'on_leave' => $onLeave,
+        ];
+    }
+
     private function extractFirstName(string $fullName): string
     {
         $firstName = explode(' ', trim($fullName))[0];

+ 22 - 0
database/migrations/2026_07_28_000001_add_on_leave_to_import_logs_table.php

@@ -0,0 +1,22 @@
+<?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::table('import_logs', function (Blueprint $table) {
+            $table->unsignedInteger('on_leave')->default(0)->after('inactivated');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('import_logs', function (Blueprint $table) {
+            $table->dropColumn('on_leave');
+        });
+    }
+};

+ 1 - 0
routes/authRoutes/associado_import.php

@@ -5,4 +5,5 @@ use Illuminate\Support\Facades\Route;
 
 Route::controller(AssociadoImportController::class)->prefix('user')->group(function () {
     Route::post('/import/associados', 'importAndSync')->middleware('permission:config.user,add');
+    Route::post('/import/afastamentos', 'importAfastamentos')->middleware('permission:config.user,add');
 });