fix attendance
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
<?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
|
||||
{
|
||||
if (! Schema::hasTable('attendance_management_events')) {
|
||||
Schema::create('attendance_management_events', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('person_type', 32)->default('student');
|
||||
$table->unsignedBigInteger('person_id')->nullable();
|
||||
$table->string('person_name')->nullable();
|
||||
$table->string('role_grade', 128)->nullable();
|
||||
$table->string('badge_id', 128)->nullable()->index();
|
||||
$table->date('event_date')->index();
|
||||
$table->string('attendance_status', 48)->index();
|
||||
$table->string('report_status', 48)->default('pending_clarification')->index();
|
||||
$table->dateTime('entry_time')->nullable();
|
||||
$table->dateTime('exit_time')->nullable();
|
||||
$table->dateTime('official_entry_time')->nullable();
|
||||
$table->dateTime('official_exit_time')->nullable();
|
||||
$table->string('entry_method', 48)->nullable();
|
||||
$table->string('exit_method', 48)->nullable();
|
||||
$table->string('manual_reason')->nullable();
|
||||
$table->string('reason')->nullable();
|
||||
$table->string('scan_location')->nullable();
|
||||
$table->string('exit_location')->nullable();
|
||||
$table->string('authorized_by')->nullable();
|
||||
$table->unsignedBigInteger('entered_by')->nullable();
|
||||
$table->unsignedInteger('absence_count')->default(0);
|
||||
$table->unsignedInteger('late_count')->default(0);
|
||||
$table->unsignedInteger('early_dismissal_count')->default(0);
|
||||
$table->unsignedInteger('badge_exception_count')->default(0);
|
||||
$table->string('combination_code')->nullable();
|
||||
$table->string('risk_level', 32)->default('low');
|
||||
$table->boolean('follow_up_required')->default(false)->index();
|
||||
$table->boolean('follow_up_completed')->default(false)->index();
|
||||
$table->string('action_needed')->nullable();
|
||||
$table->text('notes')->nullable();
|
||||
$table->string('final_decision')->nullable();
|
||||
$table->json('audit')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['person_type', 'person_id', 'event_date'], 'ame_person_date_idx');
|
||||
$table->index(['attendance_status', 'report_status'], 'ame_status_report_idx');
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('badge_exceptions')) {
|
||||
Schema::create('badge_exceptions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('attendance_management_event_id')->nullable();
|
||||
$table->string('person_type', 32)->default('student');
|
||||
$table->unsignedBigInteger('person_id')->nullable();
|
||||
$table->string('person_name')->nullable();
|
||||
$table->date('exception_date')->index();
|
||||
$table->string('exception_type', 64);
|
||||
$table->string('badge_status', 64)->nullable();
|
||||
$table->unsignedInteger('exception_count')->default(1);
|
||||
$table->string('action')->nullable();
|
||||
$table->string('decision')->nullable();
|
||||
$table->unsignedBigInteger('recorded_by')->nullable();
|
||||
$table->text('notes')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['person_type', 'person_id', 'exception_date'], 'be_person_date_idx');
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('late_slip_reprints')) {
|
||||
Schema::create('late_slip_reprints', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('attendance_management_event_id')->nullable();
|
||||
$table->unsignedBigInteger('late_slip_log_id')->nullable();
|
||||
$table->unsignedBigInteger('student_id')->nullable();
|
||||
$table->string('student_name')->nullable();
|
||||
$table->string('slip_number')->nullable();
|
||||
$table->dateTime('reprinted_at');
|
||||
$table->unsignedBigInteger('reprinted_by')->nullable();
|
||||
$table->string('reason')->nullable();
|
||||
$table->unsignedInteger('reprint_count')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('late_slip_reprints');
|
||||
Schema::dropIfExists('badge_exceptions');
|
||||
Schema::dropIfExists('attendance_management_events');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (!Schema::hasTable('nav_items') || !Schema::hasTable('role_nav_items') || !Schema::hasTable('roles')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = now();
|
||||
$label = 'Badge Scanning List';
|
||||
$url = '/app/administrator/attendance/badge-scans';
|
||||
|
||||
$parentId = DB::table('nav_items')
|
||||
->whereNull('deleted_at')
|
||||
->whereRaw('LOWER(label) = ?', ['attendance'])
|
||||
->orderBy('id')
|
||||
->value('id');
|
||||
|
||||
$navId = DB::table('nav_items')
|
||||
->where('url', $url)
|
||||
->value('id');
|
||||
|
||||
if (!$navId) {
|
||||
$navId = DB::table('nav_items')->insertGetId([
|
||||
'menu_parent_id' => $parentId ?: null,
|
||||
'label' => $label,
|
||||
'url' => $url,
|
||||
'icon_class' => 'bi-upc-scan',
|
||||
'target' => null,
|
||||
'sort_order' => 50,
|
||||
'is_enabled' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
} else {
|
||||
DB::table('nav_items')
|
||||
->where('id', $navId)
|
||||
->update([
|
||||
'menu_parent_id' => $parentId ?: null,
|
||||
'label' => $label,
|
||||
'icon_class' => 'bi-upc-scan',
|
||||
'sort_order' => 50,
|
||||
'is_enabled' => 1,
|
||||
'updated_at' => $now,
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
$roleIds = DB::table('roles')
|
||||
->where('is_active', 1)
|
||||
->where(function ($query) {
|
||||
$query->whereIn(DB::raw('LOWER(name)'), ['administrator', 'admin'])
|
||||
->orWhereIn(DB::raw('LOWER(COALESCE(slug, ""))'), ['administrator', 'admin']);
|
||||
})
|
||||
->pluck('id')
|
||||
->map(fn ($id) => (int) $id)
|
||||
->filter(fn ($id) => $id > 0)
|
||||
->values();
|
||||
|
||||
foreach ($roleIds as $roleId) {
|
||||
$exists = DB::table('role_nav_items')
|
||||
->where('role_id', $roleId)
|
||||
->where('nav_item_id', $navId)
|
||||
->exists();
|
||||
|
||||
if (!$exists) {
|
||||
DB::table('role_nav_items')->insert([
|
||||
'role_id' => $roleId,
|
||||
'nav_item_id' => $navId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (!Schema::hasTable('nav_items')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$url = '/app/administrator/attendance/badge-scans';
|
||||
$navId = DB::table('nav_items')->where('url', $url)->value('id');
|
||||
|
||||
if ($navId && Schema::hasTable('role_nav_items')) {
|
||||
DB::table('role_nav_items')->where('nav_item_id', $navId)->delete();
|
||||
}
|
||||
|
||||
if ($navId) {
|
||||
DB::table('nav_items')->where('id', $navId)->delete();
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user