This commit is contained in:
+188
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use App\Support\Enrollment\DeliberationDecision;
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddSchoolYearTransitionEnrollmentFields extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if ($this->db->tableExists('student_decisions') && ! $this->db->fieldExists('deliberation_decision_standard', 'student_decisions')) {
|
||||
$this->forge->addColumn('student_decisions', [
|
||||
'deliberation_decision_standard' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 40,
|
||||
'null' => true,
|
||||
'after' => 'decision',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
if ($this->db->tableExists('student_decisions') && $this->db->fieldExists('deliberation_decision_standard', 'student_decisions')) {
|
||||
$rows = $this->db->table('student_decisions')
|
||||
->select('id, decision')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$standard = DeliberationDecision::normalize($row['decision'] ?? null);
|
||||
if ($standard === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->db->table('student_decisions')
|
||||
->where('id', (int) $row['id'])
|
||||
->update(['deliberation_decision_standard' => $standard]);
|
||||
}
|
||||
}
|
||||
|
||||
if (! $this->db->tableExists('enrollments')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fields = [];
|
||||
$this->addFieldIfMissing($fields, 'source_school_year', [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 20,
|
||||
'null' => true,
|
||||
'after' => 'school_year',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'deliberation_decision', [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 40,
|
||||
'null' => true,
|
||||
'after' => 'source_school_year',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'source_grade_id', [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
'after' => 'deliberation_decision',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'assigned_grade_id', [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
'after' => 'source_grade_id',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'source_class_section_id', [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
'after' => 'assigned_grade_id',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'assigned_class_section_id', [
|
||||
'type' => 'INT',
|
||||
'constraint' => 11,
|
||||
'unsigned' => true,
|
||||
'null' => true,
|
||||
'after' => 'source_class_section_id',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'placement_status', [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 40,
|
||||
'null' => true,
|
||||
'after' => 'assigned_class_section_id',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'age_reference_date', [
|
||||
'type' => 'DATE',
|
||||
'null' => true,
|
||||
'after' => 'placement_status',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'age_on_reference_date', [
|
||||
'type' => 'INT',
|
||||
'constraint' => 3,
|
||||
'null' => true,
|
||||
'after' => 'age_reference_date',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'adult_student', [
|
||||
'type' => 'TINYINT',
|
||||
'constraint' => 1,
|
||||
'default' => 0,
|
||||
'after' => 'age_on_reference_date',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'parent_enrollment_allowed', [
|
||||
'type' => 'TINYINT',
|
||||
'constraint' => 1,
|
||||
'default' => 1,
|
||||
'after' => 'adult_student',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'student_self_enrollment_allowed', [
|
||||
'type' => 'TINYINT',
|
||||
'constraint' => 1,
|
||||
'default' => 0,
|
||||
'after' => 'parent_enrollment_allowed',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'exception_required', [
|
||||
'type' => 'TINYINT',
|
||||
'constraint' => 1,
|
||||
'default' => 0,
|
||||
'after' => 'student_self_enrollment_allowed',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'exception_reason', [
|
||||
'type' => 'TEXT',
|
||||
'null' => true,
|
||||
'after' => 'exception_required',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'registration_submitted_at', [
|
||||
'type' => 'DATETIME',
|
||||
'null' => true,
|
||||
'after' => 'exception_reason',
|
||||
]);
|
||||
$this->addFieldIfMissing($fields, 'registration_confirmed_at', [
|
||||
'type' => 'DATETIME',
|
||||
'null' => true,
|
||||
'after' => 'registration_submitted_at',
|
||||
]);
|
||||
|
||||
if ($fields !== []) {
|
||||
$this->forge->addColumn('enrollments', $fields);
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if ($this->db->tableExists('student_decisions') && $this->db->fieldExists('deliberation_decision_standard', 'student_decisions')) {
|
||||
$this->forge->dropColumn('student_decisions', 'deliberation_decision_standard');
|
||||
}
|
||||
|
||||
if (! $this->db->tableExists('enrollments')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ([
|
||||
'source_school_year',
|
||||
'deliberation_decision',
|
||||
'source_grade_id',
|
||||
'assigned_grade_id',
|
||||
'source_class_section_id',
|
||||
'assigned_class_section_id',
|
||||
'placement_status',
|
||||
'age_reference_date',
|
||||
'age_on_reference_date',
|
||||
'adult_student',
|
||||
'parent_enrollment_allowed',
|
||||
'student_self_enrollment_allowed',
|
||||
'exception_required',
|
||||
'exception_reason',
|
||||
'registration_submitted_at',
|
||||
'registration_confirmed_at',
|
||||
] as $field) {
|
||||
if ($this->db->fieldExists($field, 'enrollments')) {
|
||||
$this->forge->dropColumn('enrollments', $field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addFieldIfMissing(array &$fields, string $name, array $definition): void
|
||||
{
|
||||
if (! $this->db->fieldExists($name, 'enrollments')) {
|
||||
$fields[$name] = $definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class CreateEnrollmentPhaseTwoTables extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if ($this->db->tableExists('school_years')) {
|
||||
$schoolYearFields = [];
|
||||
$this->addColumnIfMissing($schoolYearFields, 'school_years', 'registration_opens_at', ['type' => 'DATETIME', 'null' => true, 'after' => 'registration_starts_on']);
|
||||
$this->addColumnIfMissing($schoolYearFields, 'school_years', 'registration_deadline_at', ['type' => 'DATETIME', 'null' => true, 'after' => 'registration_ends_on']);
|
||||
$this->addColumnIfMissing($schoolYearFields, 'school_years', 'late_registration_blocked', ['type' => 'TINYINT', 'constraint' => 1, 'default' => 1, 'after' => 'registration_deadline_at']);
|
||||
$this->addColumnIfMissing($schoolYearFields, 'school_years', 'administrative_exceptions_permitted', ['type' => 'TINYINT', 'constraint' => 1, 'default' => 1, 'after' => 'late_registration_blocked']);
|
||||
$this->addColumnIfMissing($schoolYearFields, 'school_years', 'registration_exception_roles', ['type' => 'TEXT', 'null' => true, 'after' => 'administrative_exceptions_permitted']);
|
||||
$this->addColumnIfMissing($schoolYearFields, 'school_years', 'adult_student_registration_enabled', ['type' => 'TINYINT', 'constraint' => 1, 'default' => 0, 'after' => 'registration_exception_roles']);
|
||||
if ($schoolYearFields !== []) {
|
||||
$this->forge->addColumn('school_years', $schoolYearFields);
|
||||
}
|
||||
}
|
||||
|
||||
if (! $this->db->tableExists('enrollment_age_rules')) {
|
||||
$this->forge->addField([
|
||||
'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
|
||||
'school_year' => ['type' => 'VARCHAR', 'constraint' => 20],
|
||||
'campus' => ['type' => 'VARCHAR', 'constraint' => 100, 'null' => true],
|
||||
'grade_class_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true],
|
||||
'education_level' => ['type' => 'VARCHAR', 'constraint' => 80, 'null' => true],
|
||||
'minimum_age' => ['type' => 'INT', 'constraint' => 3, 'null' => true],
|
||||
'maximum_age' => ['type' => 'INT', 'constraint' => 3, 'null' => true],
|
||||
'age_reference_date' => ['type' => 'DATE', 'null' => true],
|
||||
'behavior' => ['type' => 'VARCHAR', 'constraint' => 20, 'default' => 'blocking'],
|
||||
'exceptions_allowed' => ['type' => 'TINYINT', 'constraint' => 1, 'default' => 0],
|
||||
'exception_roles' => ['type' => 'TEXT', 'null' => true],
|
||||
'created_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
'updated_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->addKey(['school_year', 'grade_class_id']);
|
||||
$this->forge->createTable('enrollment_age_rules');
|
||||
}
|
||||
|
||||
if (! $this->db->tableExists('enrollment_flags')) {
|
||||
$this->forge->addField([
|
||||
'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
|
||||
'flag_type' => ['type' => 'VARCHAR', 'constraint' => 80],
|
||||
'student_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true],
|
||||
'school_year' => ['type' => 'VARCHAR', 'constraint' => 20],
|
||||
'source_school_year' => ['type' => 'VARCHAR', 'constraint' => 20, 'null' => true],
|
||||
'status' => ['type' => 'VARCHAR', 'constraint' => 40, 'default' => 'open'],
|
||||
'priority' => ['type' => 'VARCHAR', 'constraint' => 20, 'default' => 'normal'],
|
||||
'assigned_to' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true],
|
||||
'details_json' => ['type' => 'TEXT', 'null' => true],
|
||||
'created_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
'resolved_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
'resolution_notes' => ['type' => 'TEXT', 'null' => true],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->addKey(['student_id', 'school_year', 'flag_type']);
|
||||
$this->forge->createTable('enrollment_flags');
|
||||
}
|
||||
|
||||
if (! $this->db->tableExists('enrollment_transition_audits')) {
|
||||
$this->forge->addField([
|
||||
'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
|
||||
'student_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true],
|
||||
'school_year' => ['type' => 'VARCHAR', 'constraint' => 20],
|
||||
'source_school_year' => ['type' => 'VARCHAR', 'constraint' => 20, 'null' => true],
|
||||
'action' => ['type' => 'VARCHAR', 'constraint' => 80],
|
||||
'performed_by' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true],
|
||||
'original_values_json' => ['type' => 'TEXT', 'null' => true],
|
||||
'new_values_json' => ['type' => 'TEXT', 'null' => true],
|
||||
'reason' => ['type' => 'TEXT', 'null' => true],
|
||||
'created_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->addKey(['student_id', 'school_year', 'created_at']);
|
||||
$this->forge->createTable('enrollment_transition_audits');
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable('enrollment_transition_audits', true);
|
||||
$this->forge->dropTable('enrollment_flags', true);
|
||||
$this->forge->dropTable('enrollment_age_rules', true);
|
||||
|
||||
if (! $this->db->tableExists('school_years')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ([
|
||||
'registration_opens_at',
|
||||
'registration_deadline_at',
|
||||
'late_registration_blocked',
|
||||
'administrative_exceptions_permitted',
|
||||
'registration_exception_roles',
|
||||
'adult_student_registration_enabled',
|
||||
] as $field) {
|
||||
if ($this->db->fieldExists($field, 'school_years')) {
|
||||
$this->forge->dropColumn('school_years', $field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addColumnIfMissing(array &$fields, string $table, string $name, array $definition): void
|
||||
{
|
||||
if (! $this->db->fieldExists($name, $table)) {
|
||||
$fields[$name] = $definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddRegistrationExperienceFinancialFields extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (! $this->db->tableExists('school_years')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fields = [];
|
||||
$this->addColumnIfMissing($fields, 'registration_fee', ['type' => 'DECIMAL', 'constraint' => '10,2', 'default' => 0, 'after' => 'adult_student_registration_enabled']);
|
||||
$this->addColumnIfMissing($fields, 'tuition_due_at_registration', ['type' => 'DECIMAL', 'constraint' => '10,2', 'default' => 0, 'after' => 'registration_fee']);
|
||||
$this->addColumnIfMissing($fields, 'mandatory_fees', ['type' => 'DECIMAL', 'constraint' => '10,2', 'default' => 0, 'after' => 'tuition_due_at_registration']);
|
||||
$this->addColumnIfMissing($fields, 'carry_over_balance_behavior', ['type' => 'VARCHAR', 'constraint' => 60, 'default' => 'information_only', 'after' => 'mandatory_fees']);
|
||||
$this->addColumnIfMissing($fields, 'financial_policy_message', ['type' => 'TEXT', 'null' => true, 'after' => 'carry_over_balance_behavior']);
|
||||
$this->addColumnIfMissing($fields, 'payment_plan_available', ['type' => 'TINYINT', 'constraint' => 1, 'default' => 0, 'after' => 'financial_policy_message']);
|
||||
|
||||
if ($fields !== []) {
|
||||
$this->forge->addColumn('school_years', $fields);
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if (! $this->db->tableExists('school_years')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ([
|
||||
'registration_fee',
|
||||
'tuition_due_at_registration',
|
||||
'mandatory_fees',
|
||||
'carry_over_balance_behavior',
|
||||
'financial_policy_message',
|
||||
'payment_plan_available',
|
||||
] as $field) {
|
||||
if ($this->db->fieldExists($field, 'school_years')) {
|
||||
$this->forge->dropColumn('school_years', $field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addColumnIfMissing(array &$fields, string $name, array $definition): void
|
||||
{
|
||||
if (! $this->db->fieldExists($name, 'school_years')) {
|
||||
$fields[$name] = $definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class CreateEnrollmentEmailRecords extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if ($this->db->tableExists('school_years')) {
|
||||
$fields = [];
|
||||
$this->addSchoolYearColumnIfMissing($fields, 'registration_launch_approved_at', ['type' => 'DATETIME', 'null' => true, 'after' => 'payment_plan_available']);
|
||||
$this->addSchoolYearColumnIfMissing($fields, 'registration_launch_approved_by', ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true, 'after' => 'registration_launch_approved_at']);
|
||||
$this->addSchoolYearColumnIfMissing($fields, 'registration_email_template_version', ['type' => 'VARCHAR', 'constraint' => 80, 'null' => true, 'after' => 'registration_launch_approved_by']);
|
||||
if ($fields !== []) {
|
||||
$this->forge->addColumn('school_years', $fields);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->db->tableExists('enrollment_email_records')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->forge->addField([
|
||||
'id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
|
||||
'school_year' => ['type' => 'VARCHAR', 'constraint' => 20],
|
||||
'school_year_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true],
|
||||
'family_account_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true],
|
||||
'parent_user_id' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true],
|
||||
'recipient_addresses_json' => ['type' => 'TEXT'],
|
||||
'template_version' => ['type' => 'VARCHAR', 'constraint' => 80, 'null' => true],
|
||||
'generated_subject' => ['type' => 'VARCHAR', 'constraint' => 255],
|
||||
'generated_body' => ['type' => 'LONGTEXT'],
|
||||
'student_ids_included_json' => ['type' => 'TEXT', 'null' => true],
|
||||
'generated_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
'sent_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
'delivery_status' => ['type' => 'VARCHAR', 'constraint' => 40, 'default' => 'generated'],
|
||||
'failure_reason' => ['type' => 'TEXT', 'null' => true],
|
||||
'retry_count' => ['type' => 'INT', 'constraint' => 11, 'default' => 0],
|
||||
'created_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
'updated_at' => ['type' => 'DATETIME', 'null' => true],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->addKey(['school_year', 'parent_user_id']);
|
||||
$this->forge->createTable('enrollment_email_records');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->forge->dropTable('enrollment_email_records', true);
|
||||
|
||||
if (! $this->db->tableExists('school_years')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (['registration_launch_approved_at', 'registration_launch_approved_by', 'registration_email_template_version'] as $field) {
|
||||
if ($this->db->fieldExists($field, 'school_years')) {
|
||||
$this->forge->dropColumn('school_years', $field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addSchoolYearColumnIfMissing(array &$fields, string $name, array $definition): void
|
||||
{
|
||||
if (! $this->db->fieldExists($name, 'school_years')) {
|
||||
$fields[$name] = $definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddEnrollmentAdministrationNavItem extends Migration
|
||||
{
|
||||
private string $label = 'Enrollment Administration';
|
||||
private string $url = 'administrator/enrollment-admin';
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
if (! $this->db->tableExists('nav_items')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$parentColumn = $this->parentColumn();
|
||||
$parent = $this->studentAffairsParent($parentColumn);
|
||||
$navItemId = $this->navItemId($parentColumn, $parent);
|
||||
|
||||
if ($navItemId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->grantRoles($navItemId, [
|
||||
'administrator',
|
||||
'principal',
|
||||
'vice_principal',
|
||||
'head of department (education)',
|
||||
]);
|
||||
|
||||
cache()->clean();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (! $this->db->tableExists('nav_items')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$row = $this->db->table('nav_items')
|
||||
->where('url', $this->url)
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
if ($row === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->db->tableExists('role_nav_items')) {
|
||||
$this->db->table('role_nav_items')
|
||||
->where('nav_item_id', (int) $row['id'])
|
||||
->delete();
|
||||
}
|
||||
|
||||
$this->db->table('nav_items')
|
||||
->where('id', (int) $row['id'])
|
||||
->delete();
|
||||
|
||||
cache()->clean();
|
||||
}
|
||||
|
||||
private function navItemId(?string $parentColumn, ?array $parent): int
|
||||
{
|
||||
$existing = $this->db->table('nav_items')
|
||||
->where('url', $this->url)
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
if ($existing !== null) {
|
||||
$updates = [
|
||||
'label' => $this->label,
|
||||
'is_enabled' => 1,
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
if ($parentColumn !== null && ! empty($parent['id'])) {
|
||||
$updates[$parentColumn] = (int) $parent['id'];
|
||||
}
|
||||
|
||||
$this->db->table('nav_items')
|
||||
->where('id', (int) $existing['id'])
|
||||
->update($updates);
|
||||
|
||||
return (int) $existing['id'];
|
||||
}
|
||||
|
||||
$insert = [
|
||||
'label' => $this->label,
|
||||
'url' => $this->url,
|
||||
'sort_order' => 6,
|
||||
'is_enabled' => 1,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
if ($this->db->fieldExists('icon_class', 'nav_items')) {
|
||||
$insert['icon_class'] = 'bi bi-diagram-3';
|
||||
}
|
||||
if ($parentColumn !== null && ! empty($parent['id'])) {
|
||||
$insert[$parentColumn] = (int) $parent['id'];
|
||||
}
|
||||
|
||||
$this->db->table('nav_items')->insert($insert);
|
||||
|
||||
return (int) $this->db->insertID();
|
||||
}
|
||||
|
||||
private function studentAffairsParent(?string $parentColumn): ?array
|
||||
{
|
||||
$builder = $this->db->table('nav_items')->where('label', 'Student-Affairs');
|
||||
if ($parentColumn !== null) {
|
||||
$builder->where($parentColumn, null);
|
||||
}
|
||||
|
||||
return $builder->get()->getRowArray();
|
||||
}
|
||||
|
||||
private function grantRoles(int $navItemId, array $roleNames): void
|
||||
{
|
||||
if (! $this->db->tableExists('role_nav_items')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->db->fieldExists('role_id', 'role_nav_items') && $this->db->tableExists('roles')) {
|
||||
foreach ($roleNames as $roleName) {
|
||||
$roleBuilder = $this->db->table('roles')->select('id');
|
||||
$roleBuilder->groupStart()
|
||||
->where('LOWER(name)', strtolower($roleName));
|
||||
if ($this->db->fieldExists('slug', 'roles')) {
|
||||
$roleBuilder->orWhere('LOWER(slug)', strtolower($roleName));
|
||||
}
|
||||
$role = $roleBuilder->groupEnd()
|
||||
->limit(1)
|
||||
->get()
|
||||
->getRowArray();
|
||||
if ($role === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$exists = $this->db->table('role_nav_items')
|
||||
->where('role_id', (int) $role['id'])
|
||||
->where('nav_item_id', $navItemId)
|
||||
->countAllResults() > 0;
|
||||
if (! $exists) {
|
||||
$this->db->table('role_nav_items')->insert([
|
||||
'role_id' => (int) $role['id'],
|
||||
'nav_item_id' => $navItemId,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->db->fieldExists('role', 'role_nav_items')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($roleNames as $roleName) {
|
||||
$roleName = strtolower($roleName);
|
||||
$exists = $this->db->table('role_nav_items')
|
||||
->where('role', $roleName)
|
||||
->where('nav_item_id', $navItemId)
|
||||
->countAllResults() > 0;
|
||||
if (! $exists) {
|
||||
$this->db->table('role_nav_items')->insert([
|
||||
'role' => $roleName,
|
||||
'nav_item_id' => $navItemId,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function parentColumn(): ?string
|
||||
{
|
||||
if ($this->db->fieldExists('menu_parent_id', 'nav_items')) {
|
||||
return 'menu_parent_id';
|
||||
}
|
||||
|
||||
if ($this->db->fieldExists('parent_id', 'nav_items')) {
|
||||
return 'parent_id';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class SyncEnrollmentAdministrationNavRoles extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! $this->db->tableExists('nav_items') || ! $this->db->tableExists('role_nav_items')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nav = $this->db->table('nav_items')
|
||||
->select('id')
|
||||
->where('url', 'administrator/enrollment-admin')
|
||||
->limit(1)
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
if ($nav === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->grantRoles((int) $nav['id'], [
|
||||
'administrator',
|
||||
'principal',
|
||||
'vice_principal',
|
||||
'head of department (education)',
|
||||
]);
|
||||
|
||||
cache()->clean();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
|
||||
private function grantRoles(int $navItemId, array $roleNames): void
|
||||
{
|
||||
if (! $this->db->fieldExists('role_id', 'role_nav_items') || ! $this->db->tableExists('roles')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($roleNames as $roleName) {
|
||||
$roleBuilder = $this->db->table('roles')->select('id');
|
||||
$roleBuilder->groupStart()
|
||||
->where('LOWER(name)', strtolower($roleName));
|
||||
if ($this->db->fieldExists('slug', 'roles')) {
|
||||
$roleBuilder->orWhere('LOWER(slug)', strtolower($roleName));
|
||||
}
|
||||
$role = $roleBuilder->groupEnd()
|
||||
->limit(1)
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
if ($role === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$exists = $this->db->table('role_nav_items')
|
||||
->where('role_id', (int) $role['id'])
|
||||
->where('nav_item_id', $navItemId)
|
||||
->countAllResults() > 0;
|
||||
|
||||
if (! $exists) {
|
||||
$this->db->table('role_nav_items')->insert([
|
||||
'role_id' => (int) $role['id'],
|
||||
'nav_item_id' => $navItemId,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddReviewDecisionEnrollmentStatus extends Migration
|
||||
{
|
||||
private const STATUSES_WITH_REVIEW_DECISION = [
|
||||
'admission under review',
|
||||
'review & decision',
|
||||
'payment pending',
|
||||
'enrolled',
|
||||
'withdraw under review',
|
||||
'refund pending',
|
||||
'withdrawn',
|
||||
'waitlist',
|
||||
'denied',
|
||||
];
|
||||
|
||||
private const STATUSES_WITHOUT_REVIEW_DECISION = [
|
||||
'admission under review',
|
||||
'payment pending',
|
||||
'enrolled',
|
||||
'withdraw under review',
|
||||
'refund pending',
|
||||
'withdrawn',
|
||||
'waitlist',
|
||||
'denied',
|
||||
];
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->modifyEnrollmentStatusEnum(self::STATUSES_WITH_REVIEW_DECISION);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if ($this->db->tableExists('enrollments')) {
|
||||
$this->db->table('enrollments')
|
||||
->where('enrollment_status', 'review & decision')
|
||||
->update(['enrollment_status' => 'admission under review']);
|
||||
}
|
||||
|
||||
$this->modifyEnrollmentStatusEnum(self::STATUSES_WITHOUT_REVIEW_DECISION);
|
||||
}
|
||||
|
||||
private function modifyEnrollmentStatusEnum(array $statuses): void
|
||||
{
|
||||
if (! $this->db->tableExists('enrollments') || ! $this->db->fieldExists('enrollment_status', 'enrollments')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! in_array($this->db->DBDriver, ['MySQLi', 'MySQL'], true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$enumValues = implode(',', array_map(static fn (string $status): string => "'" . str_replace("'", "''", $status) . "'", $statuses));
|
||||
$this->db->query(
|
||||
"ALTER TABLE `enrollments` MODIFY `enrollment_status` ENUM({$enumValues}) NOT NULL DEFAULT 'admission under review'"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -67,13 +67,14 @@ class NavSeeder extends Seeder
|
||||
['parent'=>'Student-Affairs','label'=>'Attendance Scans','url'=>'rfid_coming_soon','sort_order'=>3],
|
||||
['parent'=>'Student-Affairs','label'=>'Classes List','url'=>'administrator/class_assignment','sort_order'=>4],
|
||||
['parent'=>'Student-Affairs','label'=>'Emergency Contact','url'=>'administrator/emergency_contact','sort_order'=>5],
|
||||
['parent'=>'Student-Affairs','label'=>'Enrollment-Withdrawal','url'=>'enroll_withdraw/enrollment_withdrawal','sort_order'=>6],
|
||||
['parent'=>'Student-Affairs','label'=>'Flags Management','url'=>'flags/flags_management','sort_order'=>7],
|
||||
['parent'=>'Student-Affairs','label'=>'School Calendar','url'=>'administrator/calendar_view','sort_order'=>8],
|
||||
['parent'=>'Student-Affairs','label'=>'Score Analysis','url'=>'report/combined','sort_order'=>9],
|
||||
['parent'=>'Student-Affairs','label'=>'Score Management','url'=>'grading','sort_order'=>10],
|
||||
['parent'=>'Student-Affairs','label'=>'Student Class Assignment','url'=>'administrator/student_class_assignment','sort_order'=>11],
|
||||
['parent'=>'Student-Affairs','label'=>'Student Profile','url'=>'administrator/student_profiles','sort_order'=>12],
|
||||
['parent'=>'Student-Affairs','label'=>'Enrollment Administration','url'=>'administrator/enrollment-admin','sort_order'=>6],
|
||||
['parent'=>'Student-Affairs','label'=>'Enrollment-Withdrawal','url'=>'enroll_withdraw/enrollment_withdrawal','sort_order'=>7],
|
||||
['parent'=>'Student-Affairs','label'=>'Flags Management','url'=>'flags/flags_management','sort_order'=>8],
|
||||
['parent'=>'Student-Affairs','label'=>'School Calendar','url'=>'administrator/calendar_view','sort_order'=>9],
|
||||
['parent'=>'Student-Affairs','label'=>'Score Analysis','url'=>'report/combined','sort_order'=>10],
|
||||
['parent'=>'Student-Affairs','label'=>'Score Management','url'=>'grading','sort_order'=>11],
|
||||
['parent'=>'Student-Affairs','label'=>'Student Class Assignment','url'=>'administrator/student_class_assignment','sort_order'=>12],
|
||||
['parent'=>'Student-Affairs','label'=>'Student Profile','url'=>'administrator/student_profiles','sort_order'=>13],
|
||||
|
||||
// Classes
|
||||
['parent'=>'Classes','label'=>'Classes List','url'=>'administrator/class_assignment','sort_order'=>1],
|
||||
@@ -155,7 +156,7 @@ class NavSeeder extends Seeder
|
||||
}
|
||||
|
||||
// Example: HOD Education (Student-Affairs group)
|
||||
$hodEduLabels = ['Student-Affairs','Attendance Management','Classes List','Emergency Contact','Enrollment-Withdrawal','Flags Management','School Calendar','Score Analysis','Score Management','Student Class Assignment','Student Profile'];
|
||||
$hodEduLabels = ['Student-Affairs','Attendance Management','Classes List','Emergency Contact','Enrollment Administration','Enrollment-Withdrawal','Flags Management','School Calendar','Score Analysis','Score Management','Student Class Assignment','Student Profile'];
|
||||
foreach ($navRows as $row) {
|
||||
if (in_array($row['label'], $hodEduLabels, true)) {
|
||||
$roleMap->insert([
|
||||
|
||||
Reference in New Issue
Block a user