initial: bootstrap from BukidBountyApp base

This commit is contained in:
Jonathan Sykes
2026-06-06 18:43:00 +08:00
commit eb4a5731fb
5674 changed files with 160857 additions and 0 deletions

BIN
database/database.sqlite Normal file

Binary file not shown.

View File

@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
use App\Models\User;
use Carbon\Carbon;
use Faker\Generator as Faker;
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->unique()->name(),
'email' => $faker->unique()->safeEmail(),
'email_verified_at' => Carbon::now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
];
});

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('fullname')->nullable();
$table->string('hashkey', 300)->unique();
$table->string('mobile_number');
$table->string('landline')->nullable();
$table->string('nickname')->nullable();
$table->string('username')->unique()->nullable();
$table->string('email')->unique()->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->timestamp('mobile_verified_at')->nullable();
$table->string('password');
$table->string('acct_type');
$table->unsignedBigInteger('total_balance')->default(0);
$table->bigInteger('total_credit')->default(0);
$table->bigInteger('created_by')->constrained('users', 'id')->nullable();
$table->bigInteger('updated_by')->constrained('users', 'id')->nullable();
$table->boolean('active')->default(true);
$table->bigInteger('parentuid')->constrained('users', 'id')->nullable();
$table->json('targetuids')->nullable();
$table->text('notes')->nullable();
$table->text('exec_command')->nullable();
$table->json('settings')->nullable();
$table->boolean('multiple_logins')->default(false);
$table->string('referralcode', 150)->nullable();
$table->json('photourl')->nullable();
$table->json('logs')->nullable();
$table->json('cart')->nullable();
$table->json('details')->nullable();
$table->json('additional_roles')->json()->nullable();
$table->json('denied_roles')->json()->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users');
}
};

View File

@@ -0,0 +1,89 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('file_content', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->string('filehash', 300)->unique();
$table->string('titlename', 2000)->default('');
$table->text('description')->nullable();
$table->unsignedBigInteger('size_in_bytes')->default(0);
$table->json('details')->nullable();
// $table->binary('content');
if (Schema::getConnection()->getDriverName() === 'pgsql') {
$table->binary('content');
} else {
$table->longText('content');
}
$table->text('mimetype')->nullable();
$table->text('filelocation')->nullable();
// $table->bigInteger('created_by')->constrained('users', 'id')->nullable();
// $table->bigInteger('updated_by')->constrained('users', 'id')->nullable();
$table->foreignId('created_by')
->nullable()
->constrained('users', 'id')
->nullOnDelete();
$table->foreignId('updated_by')
->nullable()
->constrained('users', 'id')
->nullOnDelete();
$table->timestamps();
});
Schema::create('file_list', function (Blueprint $table) {
$table->id();
$table->json('useruid_access_list')->nullable();
$table->string('hashkey', 300)->unique();
$table->foreignId('contentuid')
->constrained('file_content', 'id')
->cascadeOnDelete();
$table->string('title', 300)->default('');
$table->string('filename', 300)->default('');
$table->text('description')->nullable();
$table->string('tags', 600)->default('');
$table->integer('hidden')->default(0);
$table->text('categories')->nullable();
$table->foreignId('created_by')
->nullable()
->constrained('users', 'id')
->nullOnDelete();
$table->foreignId('updated_by')
->nullable()
->constrained('users', 'id')
->nullOnDelete();
$table->json('details')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('file_content');
Schema::dropIfExists('file_list');
}
};

View File

@@ -0,0 +1,240 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('str', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->string('storecode', 50)->default('');
$table->string('name', 150)->nullable();
$table->text('description')->nullable();
$table->timestamps();
$table->json('store_type')->nullable();
$table->string('status', 50)->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->foreign('created_by')->references('id')->on('users');
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('updated_by')->references('id')->on('users');
$table->unsignedBigInteger('created_for')->nullable();
$table->foreign('created_for')->references('id')->on('users');
// $table->foreignId('created_by')->constrained('users')->nullable();
// $table->foreignId('updated_by')->constrained('users')->nullable();
// $table->foreignId('created_for')->constrained('users')->nullable();
$table->string('remarks', 50)->nullable();
$table->longText('logs')->nullable();
$table->json('specs')->nullable();
$table->longText('additionaldata')->nullable();
// $table->foreignId('owner_id')->constrained('users')->nullable();
// $table->foreignId('manager_id')->constrained('users')->nullable();
$table->unsignedBigInteger('owner_id')->nullable();
$table->foreign('owner_id')->references('id')->on('users');
$table->unsignedBigInteger('manager_id')->nullable();
$table->foreign('manager_id')->references('id')->on('users');
$table->string('category', 50)->nullable();
$table->string('subcategory', 50)->nullable();
$table->json('photourl')->nullable();
$table->text('address')->nullable();
$table->boolean('is_active')->default(true);
// Indexes
$table->index('storecode');
$table->index('name');
$table->index('status');
$table->index('created_by');
$table->index('created_for');
$table->index('owner_id');
$table->index('manager_id');
});
Schema::create('prd_items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->timestamps();
// $table->foreignId('created_by')->constrained('users')->nullable();
// $table->foreignId('updated_by')->constrained('users')->nullable();
// $table->foreignId('created_for')->constrained('users')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->foreign('created_by')->references('id')->on('users');
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('updated_by')->references('id')->on('users');
$table->unsignedBigInteger('created_for')->nullable();
$table->foreign('created_for')->references('id')->on('users');
$table->string('category', 50)->nullable();
$table->string('subcategory', 50)->nullable();
$table->longText('logs')->nullable();
$table->json('specs')->nullable();
$table->string('product_type')->nullable();
$table->json('photourl')->nullable();
$table->integer('available')->nullable();
$table->integer('sold')->nullable();
$table->bigInteger('price')->nullable();
// $table->foreignId('store_id')->constrained('stores')->nullable();
// $table->foreignId('owner_id')->constrained('users')->nullable();
$table->unsignedBigInteger('owner_id')->nullable();
$table->foreign('owner_id')->references('id')->on('users');
$table->boolean('is_active')->default(true);
$table->bigInteger('views')->nullable();
$table->string('name', 300)->nullable();
$table->longText('description')->nullable();
$table->json('reviews')->nullable();
$table->string('barcode', 50)->nullable();
$table->string('status', 50)->nullable();
$table->string('remarks', 150)->nullable();
$table->string('unitname', 300)->nullable();
$table->integer('rating')->nullable();
$table->string('sku', 50)->nullable();
$table->string('qrcode', 300)->nullable();
$table->string('shortcode', 50)->nullable();
$table->string('shortname', 50)->nullable();
$table->index('created_by');
$table->index('updated_by');
$table->index('created_for');
// $table->index('store_id');
$table->index('owner_id');
$table->index('category');
$table->index('subcategory');
});
// Products Transactions table
Schema::create('prd_trx', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->timestamps();
$table->text('description')->nullable();
$table->text('notes')->nullable();
$table->tinyInteger('transaction_type')->default(0);
$table->unsignedBigInteger('created_by')->nullable();
$table->foreign('created_by')->references('id')->on('users');
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('updated_by')->references('id')->on('users');
$table->unsignedBigInteger('created_for')->nullable();
$table->foreign('created_for')->references('id')->on('users');
$table->bigInteger('store_id')->nullable();
$table->string('transactiontype', 50)->nullable();
$table->bigInteger('product_id')->nullable();
$table->longText('transactiondata')->nullable();
$table->string('subtype', 50)->nullable();
$table->string('name', 300)->nullable();
// $table->bigInteger('owner_id')->nullable();
$table->unsignedBigInteger('owner_id')->nullable();
$table->foreign('owner_id')->references('id')->on('users');
$table->string('transactionsessionhash', 300)->unique()->nullable();
$table->bigInteger('quantity')->nullable();
$table->longText('logs')->nullable();
$table->string('remarks', 50)->nullable();
$table->integer('price')->nullable();
$table->boolean('is_void')->default(false);
$table->bigInteger('last_total_price')->nullable();
$table->bigInteger('last_total_discount')->nullable();
$table->index('created_by');
$table->index('updated_by');
$table->index('created_for');
$table->index('name');
$table->index('transactionsessionhash');
});
// Products Transactions Sessions table
Schema::create('prd_trx_ses', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->timestamps();
$table->string('name', 300)->nullable();
$table->text('description')->nullable();
$table->longText('logs')->nullable();
$table->string('remarks', 300)->nullable();
$table->text('notes')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->foreign('created_by')->references('id')->on('users');
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('updated_by')->references('id')->on('users');
$table->unsignedBigInteger('created_for')->nullable();
$table->foreign('created_for')->references('id')->on('users');
$table->string('subtype', 50)->nullable();
$table->longText('additionaldata')->nullable();
$table->string('category', 50)->nullable();
$table->bigInteger('store_id')->nullable();
$table->string('status', 50)->nullable();
$table->boolean('is_void')->default(false);
$table->bigInteger('last_total_price')->nullable();
$table->bigInteger('last_total_discount')->nullable();
$table->index('hashkey');
$table->index('created_by');
$table->index('updated_by');
$table->index('created_for');
});
Schema::create('prd_trx_ses_arc', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('name')->nullable();
$table->text('description')->nullable();
$table->json('details')->nullable();
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('transactions_sessions_id')->nullable();
$table->foreign('transactions_sessions_id')->references('id')->on('prd_trx_ses');
$table->text('notes')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->foreign('created_by')->references('id')->on('users');
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('updated_by')->references('id')->on('users');
$table->unsignedBigInteger('created_for')->nullable();
$table->foreign('created_for')->references('id')->on('users');
$table->json('transactions_snapshot')->nullable();
$table->index('created_by');
$table->index('updated_by');
$table->index('created_for');
$table->index('hashkey');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('prd_trx_ses_arc');
Schema::dropIfExists('prd_trx_ses');
Schema::dropIfExists('prd_trx');
Schema::dropIfExists('prd_items_arc');
Schema::dropIfExists('prd_items');
Schema::dropIfExists('str');
}
};

View File

@@ -0,0 +1,44 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('prd_str', function (Blueprint $table) {
$table->id();
$table->foreignId('product_id')->constrained('prd_items')->onDelete('cascade');
$table->foreignId('store_id')->constrained('str')->onDelete('cascade');
// Optional extra data per store-product relation
$table->integer('available')->nullable();
$table->bigInteger('price')->nullable();
$table->bigInteger('sold')->nullable();
$table->longText('logs')->nullable();
$table->json('reviews')->nullable();
$table->string('status', 50)->nullable();
$table->string('remarks', 150)->nullable();
$table->longText('description')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
$table->unique(['product_id', 'store_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('prd_str');
}
};

View File

@@ -0,0 +1,41 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('table_logs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->string('table_name')->index();
$table->unsignedBigInteger('target_id')->index();
$table->json('original_data')->nullable();
$table->json('new_data')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->foreign('created_by')->references('id')->on('users');
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('updated_by')->references('id')->on('users');
$table->timestamps();
$table->index(['table_name', 'target_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('table_logs');
}
};

View File

@@ -0,0 +1,72 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
/**
* CHART OF ACCOUNTS (Self-Referencing)
*/
Schema::create('accounts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
// Self-referencing foreign key for nested accounts
$table->unsignedBigInteger('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('accounts')->cascadeOnDelete();
$table->string('name')->index();
$table->string('type')->index(); // e.g., 'REVENUE', 'EXPENSE'
$table->string('description')->nullable();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('created_by')->references('id')->on('users')->nullOnDelete();
$table->foreign('updated_by')->references('id')->on('users')->nullOnDelete();
$table->timestamps();
});
/**
* ACCOUNT TRANSACTIONS
*/
Schema::create('account_transactions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
// Link to the lowest-level account
$table->unsignedBigInteger('account_id');
$table->foreign('account_id')->references('id')->on('accounts')->cascadeOnDelete();
$table->string('item')->index()->nullable();
$table->unsignedBigInteger('target_id')->nullable()->index(); // optional target (user, vendor)
$table->decimal('amount', 15, 2)->default(0);
$table->dateTime('transaction_date')->index();
$table->string('reference')->nullable()->index(); // external reference / invoice no.
$table->json('additional_details')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('created_by')->references('id')->on('users')->nullOnDelete();
$table->foreign('updated_by')->references('id')->on('users')->nullOnDelete();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('account_transactions');
Schema::dropIfExists('accounts');
}
};

View File

@@ -0,0 +1,35 @@
<?php
use Hypervel\Database\Migrations\Migration;
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('announcements', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->string('type')->default('info'); // info, success, warning, danger
$table->boolean('is_active')->default(true);
$table->timestamp('starts_at')->nullable();
$table->timestamp('ends_at')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->timestamps();
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('announcements');
}
};

View File

@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('announcements', function (Blueprint $table) {
$table->string('hashkey', 300)->unique()->nullable()->after('id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('announcements', function (Blueprint $table) {
$table->dropColumn('hashkey');
});
}
};

View File

@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('announcements', function (Blueprint $table) {
$table->unsignedBigInteger('updated_by')->nullable()->after('created_by');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('announcements', function (Blueprint $table) {
$table->dropForeign(['updated_by']);
$table->dropColumn('updated_by');
});
}
};

View File

@@ -0,0 +1,27 @@
<?php
use Hypervel\Database\Migrations\Migration;
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('announcements', function (Blueprint $table) {
$table->string('photo')->nullable()->after('content');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('announcements', function (Blueprint $table) {
$table->dropColumn('photo');
});
}
};

View File

@@ -0,0 +1,46 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('global_transactions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('user_id')->index();
$table->decimal('amount', 15, 2)->default(0);
$table->integer('type')->default(0); // ProductTransactionType::UNKNOWN
$table->string('status', 50)->default('completed');
$table->text('description')->nullable();
$table->unsignedBigInteger('product_id')->nullable()->index();
$table->unsignedBigInteger('store_id')->nullable()->index();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('product_id')->references('id')->on('prd_items')->onDelete('set null');
$table->foreign('store_id')->references('id')->on('str')->onDelete('set null');
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('global_transactions');
}
};

View File

@@ -0,0 +1,76 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('pos_sessions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->string('access_key', 300)->unique(); // Guest access key
$table->unsignedBigInteger('store_id')->index();
$table->unsignedBigInteger('created_by')->nullable()->index();
$table->unsignedBigInteger('updated_by')->nullable()->index();
$table->string('customer_name', 300)->nullable();
$table->bigInteger('total_amount')->default(0);
$table->bigInteger('received_amount')->default(0);
$table->bigInteger('change_amount')->default(0);
$table->string('payment_method', 50)->nullable();
$table->json('payment_details')->nullable();
$table->string('status', 50)->default('active'); // active, completed, voided, pending
$table->boolean('is_void')->default(false);
$table->text('notes')->nullable();
$table->longText('additionaldata')->nullable();
$table->timestamps();
$table->foreign('created_by')->references('id')->on('users');
// Assuming a stores table exists, but following legacy pattern where it's bigint
});
Schema::create('pos_transactions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('pos_session_id')->index();
$table->unsignedBigInteger('product_id')->index();
$table->integer('quantity')->default(1);
$table->bigInteger('price_at_sale')->default(0);
$table->bigInteger('discount')->default(0);
$table->bigInteger('total_price')->default(0);
$table->boolean('is_void')->default(false);
$table->string('remarks', 300)->nullable();
$table->timestamps();
$table->foreign('pos_session_id')->references('id')->on('pos_sessions')->onDelete('cascade');
// product_id references prd_items.id
});
Schema::create('pos_sessions_archive', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('pos_session_id')->index();
$table->string('hashkey', 300)->index();
$table->json('session_snapshot')->nullable();
$table->json('transactions_snapshot')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->string('remarks', 300)->nullable();
$table->timestamps();
$table->foreign('pos_session_id')->references('id')->on('pos_sessions')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('pos_sessions_archive');
Schema::dropIfExists('pos_transactions');
Schema::dropIfExists('pos_sessions');
}
};

View File

@@ -0,0 +1,36 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('pos_access_keys', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->string('access_key', 300)->unique();
$table->unsignedBigInteger('store_id')->index();
$table->string('name', 255)->nullable();
$table->string('status', 50)->default('active');
$table->timestamp('last_used_at')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->timestamps();
$table->foreign('store_id')->references('id')->on('str')->onDelete('cascade');
$table->foreign('created_by')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('pos_access_keys');
}
};

View File

@@ -0,0 +1,21 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::table('pos_access_keys', function (Blueprint $table) {
$table->timestamp('expires_at')->nullable()->after('status');
});
}
public function down(): void
{
Schema::table('pos_access_keys', function (Blueprint $table) {
$table->dropColumn('expires_at');
});
}
};

View File

@@ -0,0 +1,39 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('pos_sessions', function (Blueprint $table) {
if (!Schema::hasColumn('pos_sessions', 'updated_by')) {
$table->unsignedBigInteger('updated_by')->nullable()->after('created_by')->index();
}
});
Schema::table('pos_sessions_archive', function (Blueprint $table) {
if (!Schema::hasColumn('pos_sessions_archive', 'updated_by')) {
$table->unsignedBigInteger('updated_by')->nullable()->after('created_by');
}
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pos_sessions', function (Blueprint $table) {
$table->dropColumn('updated_by');
});
Schema::table('pos_sessions_archive', function (Blueprint $table) {
$table->dropColumn('updated_by');
});
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('pos_transactions', function (Blueprint $table) {
$table->string('hashkey', 300)->nullable()->unique()->after('id');
$table->unsignedBigInteger('created_by')->nullable()->after('remarks')->index();
$table->unsignedBigInteger('updated_by')->nullable()->after('created_by')->index();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pos_transactions', function (Blueprint $table) {
$table->dropColumn(['hashkey', 'created_by', 'updated_by']);
});
}
};

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('pos_access_keys', function (Blueprint $table) {
$table->unsignedBigInteger('updated_by')->nullable()->after('created_by');
$table->boolean('is_active')->default(true)->after('status');
$table->foreign('updated_by')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pos_access_keys', function (Blueprint $table) {
$table->dropForeign(['updated_by']);
$table->dropColumn(['updated_by', 'is_active']);
});
}
};

View File

@@ -0,0 +1,27 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('global_transactions', function (Blueprint $table) {
$table->integer('flow')->default(0)->after('type'); // App\Enums\Market\TransactionFlow::NEUTRAL
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('global_transactions', function (Blueprint $table) {
$table->dropColumn('flow');
});
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::create('cst', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->string('name', 255);
$table->string('phone', 50)->nullable();
$table->string('email', 255)->nullable();
$table->unsignedBigInteger('store_id')->nullable();
$table->unsignedBigInteger('user_id')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('cst');
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('pos_sessions', function (Blueprint $table) {
$table->dropUnique('pos_sessions_access_key_unique');
$table->index('access_key');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pos_sessions', function (Blueprint $table) {
$table->dropIndex(['access_key']);
$table->unique('access_key');
});
}
};

View File

@@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
if (!Schema::hasTable('properties')) {
Schema::create('properties', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->string('name')->index();
$table->string('location')->nullable();
$table->decimal('price', 15, 2)->default(0);
$table->string('status')->default('available')->index();
$table->json('details')->nullable();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('created_by')->references('id')->on('users')->nullOnDelete();
$table->foreign('updated_by')->references('id')->on('users')->nullOnDelete();
$table->timestamps();
});
}
if (!Schema::hasTable('referral_keys')) {
Schema::create('referral_keys', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('user_id')->index();
$table->string('key')->unique()->index();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
$table->foreign('created_by')->references('id')->on('users')->nullOnDelete();
$table->foreign('updated_by')->references('id')->on('users')->nullOnDelete();
$table->timestamps();
});
}
if (!Schema::hasTable('referrals')) {
Schema::create('referrals', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('property_id')->index();
$table->unsignedBigInteger('referrer_id')->index();
$table->unsignedBigInteger('referred_id')->nullable()->index(); // Can be null if it's just a lead
$table->string('referred_name')->nullable();
$table->string('referred_contact')->nullable();
$table->string('status')->default('pending')->index();
$table->json('details')->nullable();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('property_id')->references('id')->on('properties')->cascadeOnDelete();
$table->foreign('referrer_id')->references('id')->on('users')->cascadeOnDelete();
$table->foreign('referred_id')->references('id')->on('users')->nullOnDelete();
$table->foreign('created_by')->references('id')->on('users')->nullOnDelete();
$table->foreign('updated_by')->references('id')->on('users')->nullOnDelete();
$table->timestamps();
});
}
}
public function down(): void
{
Schema::dropIfExists('referrals');
Schema::dropIfExists('referral_keys');
Schema::dropIfExists('properties');
}
};

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('couriers', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->string('name');
$table->string('contact_number')->nullable();
$table->string('type', 50)->default('INTERNAL'); // INTERNAL, EXTERNAL
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('couriers');
}
};

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('shipments', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('transaction_id')->index();
$table->unsignedBigInteger('store_id')->nullable()->index();
$table->unsignedBigInteger('customer_id')->nullable()->index();
$table->unsignedBigInteger('courier_id')->nullable()->index();
$table->string('tracking_number')->unique()->nullable();
$table->string('status', 50)->default('PENDING'); // PENDING, PICKED_UP, IN_TRANSIT, DELIVERED, FAILED, RETURNED
$table->text('origin_address')->nullable();
$table->text('destination_address')->nullable();
$table->timestamp('estimated_delivery_date')->nullable();
$table->timestamp('actual_delivery_date')->nullable();
$table->decimal('shipping_fee', 15, 2)->default(0);
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('transaction_id')->references('id')->on('global_transactions')->onDelete('cascade');
$table->foreign('store_id')->references('id')->on('str')->onDelete('set null');
$table->foreign('customer_id')->references('id')->on('cst')->onDelete('set null');
$table->foreign('courier_id')->references('id')->on('couriers')->onDelete('set null');
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('shipments');
}
};

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('organizations', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->string('name');
$table->string('type', 50)->default('COOPERATIVE'); // COOPERATIVE, ASSOCIATION, COMPANY
$table->text('address')->nullable();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
Schema::create('farmer_profiles', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('user_id')->index();
$table->unsignedBigInteger('organization_id')->nullable()->index();
$table->string('farm_name')->nullable();
$table->text('farm_location')->nullable();
$table->json('main_crops')->nullable();
$table->string('verification_status', 50)->default('UNVERIFIED'); // UNVERIFIED, PENDING, VERIFIED, REJECTED
$table->json('certification_details')->nullable();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('organization_id')->references('id')->on('organizations')->onDelete('set null');
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('farmer_profiles');
Schema::dropIfExists('organizations');
}
};

View File

@@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
use Hypervel\Support\Facades\DB;
use Hypervel\Support\Str;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_infos', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('user_id')->unique();
$table->string('firstname')->nullable();
$table->string('middlename')->nullable();
$table->string('lastname')->nullable();
$table->string('fullname')->nullable();
$table->string('landline')->nullable();
$table->string('mobile')->nullable();
$table->string('email')->nullable();
$table->string('alt_email')->nullable();
$table->string('alt_landline')->nullable();
$table->string('alt_mobile')->nullable();
$table->string('facebook_url')->nullable();
$table->json('bank_details')->nullable();
$table->json('addresses')->nullable();
$table->json('other_details')->nullable();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
// Backfill existing users
$users = DB::table('users')->get();
foreach ($users as $user) {
DB::table('user_infos')->insert([
'hashkey' => Str::uuid()->toString() . Str::random(100),
'user_id' => $user->id,
'fullname' => $user->fullname ?? $user->name,
'email' => $user->email,
'mobile' => $user->mobile_number,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
'is_active' => true,
]);
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_infos');
}
};

View File

@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('cooperative_members', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('organization_id');
$table->unsignedBigInteger('user_id');
$table->string('role', 50)->default('MEMBER'); // MEMBER, OFFICER, ADMIN
$table->timestamp('joined_at')->nullable();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('organization_id')->references('id')->on('organizations')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('cooperative_members');
}
};

View File

@@ -0,0 +1,34 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('logs', function (Blueprint $table) {
$table->bigIncrements('uid');
$table->string('log_type')->index();
$table->string('log_category')->index();
$table->text('description')->nullable();
$table->json('server_data')->nullable();
$table->json('session_data')->nullable();
$table->string('useruid')->nullable()->index();
$table->timestamp('log_time')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('logs');
}
};

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('db_backups', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->string('file_content_hashkey', 300);
$table->string('filename', 300);
$table->bigInteger('size_in_bytes');
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamps();
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
$table->foreign('updated_by')->references('id')->on('users')->onDelete('set null');
// file_content_hashkey is linked to file_content table's hashkey (string)
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('db_backups');
}
};

View File

@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('db_backups', function (Blueprint $table) {
$table->string('name', 300)->after('hashkey')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('db_backups', function (Blueprint $table) {
$table->dropColumn('name');
});
}
};

View File

@@ -0,0 +1,37 @@
<?php
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('system_settings', function (Blueprint $table) {
$table->id();
$table->string('key')->unique()->index();
$table->text('value')->nullable();
$table->string('type')->default('text'); // text, image, json, number, boolean
$table->string('group')->default('general')->index();
$table->string('label')->nullable();
$table->text('description')->nullable();
$table->string('hashkey', 300)->unique()->index();
$table->string('created_by')->nullable();
$table->string('updated_by')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('system_settings');
}
};

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('carts', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->foreignId('user_id')->constrained('users')->onDelete('cascade');
$table->boolean('is_active')->default(true);
$table->bigInteger('created_by')->nullable();
$table->bigInteger('updated_by')->nullable();
$table->timestamps();
});
Schema::create('cart_items', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->foreignId('cart_id')->constrained('carts')->onDelete('cascade');
$table->foreignId('product_id')->constrained('prd_items')->onDelete('cascade');
$table->integer('quantity')->default(1);
$table->decimal('price', 15, 2);
$table->boolean('is_active')->default(true);
$table->bigInteger('created_by')->nullable();
$table->bigInteger('updated_by')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('cart_items');
Schema::dropIfExists('carts');
}
};

View File

@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('organizations', function (Blueprint $table) {
$table->string('registration_number')->nullable()->after('address');
$table->string('cin')->nullable()->after('registration_number');
$table->string('tin')->nullable()->after('cin');
$table->string('cooperative_type')->nullable()->after('tin'); // e.g., Multi-purpose, Credit
$table->string('cooperative_category')->nullable()->after('cooperative_type'); // Micro, Small, Medium, Large
$table->date('registration_date')->nullable()->after('cooperative_category');
$table->string('contact_person')->nullable()->after('registration_date');
$table->string('contact_number')->nullable()->after('contact_person');
$table->string('contact_email')->nullable()->after('contact_number');
$table->string('compliance_status')->default('UNKNOWN')->after('contact_email');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('organizations', function (Blueprint $table) {
$table->dropColumn([
'registration_number',
'cin',
'tin',
'cooperative_type',
'cooperative_category',
'registration_date',
'contact_person',
'contact_number',
'contact_email',
'compliance_status',
]);
});
}
};

View File

@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class AddCompoundIndexToPosTransactions extends Migration
{
public function up(): void
{
Schema::table('pos_transactions', function (Blueprint $table) {
// Compound index for the updateOrCreate lookup pattern used in PosController::addItem
$table->index(['pos_session_id', 'product_id'], 'pos_tx_session_product_idx');
});
}
public function down(): void
{
Schema::table('pos_transactions', function (Blueprint $table) {
$table->dropIndex('pos_tx_session_product_idx');
});
}
}

View File

@@ -0,0 +1,95 @@
<?php
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('user_infos', function (Blueprint $table) {
// Personal Info
if (!Schema::hasColumn('user_infos', 'firstname')) $table->string('firstname')->nullable();
if (!Schema::hasColumn('user_infos', 'middlename')) $table->string('middlename')->nullable();
if (!Schema::hasColumn('user_infos', 'lastname')) $table->string('lastname')->nullable();
$table->string('suffix')->nullable();
$table->string('gender')->nullable();
$table->date('dob')->nullable();
$table->string('priority_sector')->nullable();
// Social Accounts
$table->string('messenger_id')->nullable();
$table->string('viber_number')->nullable();
$table->string('tiktok_username')->nullable();
// Address Fragments
$table->string('region')->nullable();
$table->string('province')->nullable();
$table->string('city')->nullable();
$table->string('barangay')->nullable();
// Family & Education
$table->string('civil_status')->nullable();
$table->integer('children_count')->default(0);
$table->integer('dependent_count')->nullable();
$table->string('education_level')->nullable();
$table->string('course')->nullable();
$table->string('school')->nullable();
$table->string('year_last_attended')->nullable();
// Livelihood
$table->string('livelihood_source')->nullable();
$table->string('last_company')->nullable();
$table->string('employer_name')->nullable();
$table->string('last_position')->nullable();
$table->string('occupation')->nullable();
$table->decimal('monthly_income', 15, 2)->nullable();
$table->string('last_employment_year')->nullable();
// Government Info
$table->string('tin')->nullable();
$table->string('philhealth_id')->nullable();
$table->string('gov_id')->nullable();
$table->string('id_type')->nullable();
$table->string('id_number')->nullable();
$table->string('beneficiary_type')->nullable();
// Emergency Contact Info
$table->string('emergency_contact_name')->nullable();
$table->string('emergency_contact_address')->nullable();
$table->string('emergency_contact_phone')->nullable();
$table->string('emergency_contact_relation')->nullable();
$table->integer('emergency_contact_user_id')->nullable();
// Financial Info
$table->string('bank_account_no')->nullable();
// Note: emergency_contact_user_id is not set as actual FK to avoid issues if the user is deleted
// but we'll treat it as such in the model.
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('user_infos', function (Blueprint $table) {
$table->dropColumn([
'firstname', 'middlename', 'lastname', 'suffix', 'gender', 'dob',
'messenger_id', 'viber_number', 'tiktok_username',
'region', 'province', 'city', 'barangay',
'civil_status', 'children_count', 'education_level', 'course', 'school', 'year_last_attended',
'livelihood_source', 'last_company', 'last_position', 'last_employment_year',
'tin', 'philhealth_id', 'gov_id', 'id_type', 'id_number', 'beneficiary_type',
'priority_sector', 'employer_name', 'occupation', 'monthly_income', 'dependent_count',
'bank_account_no',
'emergency_contact_name', 'emergency_contact_address', 'emergency_contact_phone', 'emergency_contact_relation', 'emergency_contact_user_id'
]);
});
}
};

View File

@@ -0,0 +1,57 @@
<?php
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('cooperative_members', function (Blueprint $table) {
if (!Schema::hasColumn('cooperative_members', 'membership_type')) {
$table->string('membership_type')->nullable()->after('role');
}
if (!Schema::hasColumn('cooperative_members', 'membership_level')) {
$table->string('membership_level')->nullable()->after('membership_type');
}
if (!Schema::hasColumn('cooperative_members', 'officer_position')) {
$table->string('officer_position')->nullable()->after('membership_level');
}
if (!Schema::hasColumn('cooperative_members', 'officer_level')) {
$table->string('officer_level')->nullable()->after('officer_position');
}
if (!Schema::hasColumn('cooperative_members', 'concurrent_position')) {
$table->string('concurrent_position')->nullable()->after('officer_level');
}
if (!Schema::hasColumn('cooperative_members', 'concurrent_level')) {
$table->string('concurrent_level')->nullable()->after('concurrent_position');
}
if (!Schema::hasColumn('cooperative_members', 'cooperative_name_alt')) {
$table->string('cooperative_name_alt')->nullable()->after('organization_id');
}
if (!Schema::hasColumn('cooperative_members', 'cooperative_position')) {
$table->string('cooperative_position')->nullable()->after('cooperative_name_alt');
}
if (!Schema::hasColumn('cooperative_members', 'year_beginning')) {
$table->string('year_beginning')->nullable()->after('cooperative_position');
}
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('cooperative_members', function (Blueprint $table) {
$table->dropColumn([
'membership_type', 'membership_level', 'officer_position', 'officer_level',
'concurrent_position', 'concurrent_level', 'cooperative_name_alt', 'cooperative_position', 'year_beginning'
]);
});
}
};

View File

@@ -0,0 +1,37 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('store_managers', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('store_id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
// Foreign keys
$table->foreign('store_id')->references('id')->on('str')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('store_managers');
}
};

View File

@@ -0,0 +1,34 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('landing_pages', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->longText('html_content');
$table->text('description')->nullable();
$table->string('hashkey', 300)->unique()->index();
$table->string('created_by')->nullable();
$table->string('updated_by')->nullable();
$table->boolean('is_active')->default(false);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('landing_pages');
}
};

View File

@@ -0,0 +1,38 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateGroupsTable extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('groups', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->string('name');
$table->string('type'); // e.g., COOPERATIVE, ASSOCIATION, NGO
$table->text('description')->nullable();
$table->boolean('is_active')->default(true);
$table->bigInteger('created_by')->nullable();
$table->bigInteger('updated_by')->nullable();
$table->timestamps();
$table->index('created_by');
$table->index('updated_by');
$table->index('type');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('groups');
}
}

View File

@@ -0,0 +1,41 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateGroupMembersTable extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('group_members', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('group_id');
$table->unsignedBigInteger('user_id');
$table->string('role')->default('MEMBER');
$table->string('membership_type')->nullable();
$table->json('extra_details')->nullable();
$table->boolean('is_active')->default(true);
$table->bigInteger('created_by')->nullable();
$table->bigInteger('updated_by')->nullable();
$table->timestamps();
$table->foreign('group_id')->references('id')->on('groups')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->index('created_by');
$table->index('updated_by');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('group_members');
}
}

View File

@@ -0,0 +1,37 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('cooperative_resolutions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->bigInteger('organization_id')->index();
$table->string('title');
$table->text('description')->nullable();
$table->date('date_approved')->nullable();
$table->string('document_url')->nullable();
$table->enum('status', ['PROPOSED', 'APPROVED', 'RESCINDED'])->default('PROPOSED');
$table->bigInteger('created_by')->nullable();
$table->bigInteger('updated_by')->nullable();
$table->boolean('is_active')->default(true);
$table->datetimes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('cooperative_resolutions');
}
};

View File

@@ -0,0 +1,36 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('cooperative_votes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->bigInteger('resolution_id')->index();
$table->bigInteger('user_id')->index();
$table->enum('vote_cast', ['YES', 'NO', 'ABSTAIN'])->default('ABSTAIN');
$table->bigInteger('created_by')->nullable();
$table->bigInteger('updated_by')->nullable();
$table->boolean('is_active')->default(true);
$table->datetimes();
$table->unique(['resolution_id', 'user_id']); // Ensure one vote per member per resolution
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('cooperative_votes');
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('cooperative_documents', function (Blueprint $table) {
$table->id();
$table->string('hashkey', 300)->unique();
$table->foreignId('organization_id')->constrained('organizations')->cascadeOnDelete();
$table->string('file_hashkey', 300); // References file_list.hashkey
$table->string('document_type')->nullable(); // e.g. 'RESOLUTION', 'BYLAWS', 'FINANCIAL', 'OTHERS'
$table->foreignId('created_by')->nullable()->constrained('users');
$table->foreignId('updated_by')->nullable()->constrained('users');
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('cooperative_documents');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('cooperative_documents', function (Blueprint $table) {
$table->string('parent_hashkey', 300)->nullable()->after('hashkey');
$table->integer('version_number')->default(1)->after('parent_hashkey');
$table->text('revision_note')->nullable()->after('document_type');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('cooperative_documents', function (Blueprint $table) {
$table->dropColumn(['parent_hashkey', 'version_number', 'revision_note']);
});
}
};

View File

@@ -0,0 +1,39 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('member_ledgers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->bigInteger('user_id')->index();
$table->bigInteger('organization_id')->index()->nullable(); // Nullable if it's a platform-wide balance
$table->decimal('amount', 15, 2);
$table->string('transaction_type'); // SHARE_CAPITAL, SAVINGS, DIVIDEND, TOP_UP, WITHDRAWAL, PURCHASE
$table->enum('flow', ['IN', 'OUT']);
$table->decimal('balance_after', 15, 2);
$table->text('description')->nullable();
$table->string('reference_id')->nullable(); // e.g., global_transaction hashkey
$table->bigInteger('created_by')->nullable();
$table->bigInteger('updated_by')->nullable();
$table->boolean('is_active')->default(true);
$table->datetimes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('member_ledgers');
}
};

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class ExpandCooperativeMembersProgramData extends Migration
{
public function up(): void
{
Schema::table('cooperative_members', function (Blueprint $table) {
// Priority & classification
$table->string('priority_sector')->nullable()->after('year_beginning');
$table->string('common_bond')->nullable()->after('priority_sector'); // Residential/Institutional/Occupational/Associational
$table->json('vulnerability_classifications')->nullable()->after('common_bond'); // IP, PWD, Senior, Solo Parent, OSY, etc.
// Government IDs (cooperative context)
$table->string('philsys_id')->nullable()->after('vulnerability_classifications');
$table->string('sss_number')->nullable()->after('philsys_id');
$table->string('pagibig_number')->nullable()->after('sss_number');
// SLP (Sustainable Livelihood Program)
$table->string('slp_track')->nullable()->after('pagibig_number'); // MD / EF
$table->string('slp_association_name')->nullable()->after('slp_track');
$table->string('listahanan_id')->nullable()->after('slp_association_name');
$table->string('fourtps_household_id')->nullable()->after('listahanan_id');
// TUPAD (DOLE)
$table->string('tupad_category')->nullable()->after('fourtps_household_id'); // Underemployed/Displaced/etc.
$table->string('tupad_insurance_beneficiary_name')->nullable()->after('tupad_category');
$table->string('tupad_insurance_beneficiary_relation')->nullable()->after('tupad_insurance_beneficiary_name');
// OSEC / NSRP Employment
$table->string('preferred_occupation')->nullable()->after('tupad_insurance_beneficiary_relation');
$table->json('nsrp_skills')->nullable()->after('preferred_occupation'); // Array of skill strings
$table->string('employment_status')->nullable()->after('nsrp_skills'); // Employed/Underemployed/Unemployed
// Program flags
$table->json('program_participation')->nullable()->after('employment_status'); // ['SLP','TUPAD','OSEC',...]
});
}
public function down(): void
{
Schema::table('cooperative_members', function (Blueprint $table) {
$table->dropColumn([
'priority_sector', 'common_bond', 'vulnerability_classifications',
'philsys_id', 'sss_number', 'pagibig_number',
'slp_track', 'slp_association_name', 'listahanan_id', 'fourtps_household_id',
'tupad_category', 'tupad_insurance_beneficiary_name', 'tupad_insurance_beneficiary_relation',
'preferred_occupation', 'nsrp_skills', 'employment_status', 'program_participation',
]);
});
}
}

View File

@@ -0,0 +1,17 @@
<?php
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
DB::statement('ALTER TABLE cooperative_members MODIFY COLUMN priority_sector JSON NULL');
}
public function down(): void
{
DB::statement('ALTER TABLE cooperative_members MODIFY COLUMN priority_sector VARCHAR(255) NULL');
}
};

View File

@@ -0,0 +1,22 @@
<?php
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('system_settings', function (Blueprint $table) {
$table->text('options')->nullable()->after('type');
});
}
public function down(): void
{
Schema::table('system_settings', function (Blueprint $table) {
$table->dropColumn('options');
});
}
};

View File

@@ -0,0 +1,35 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateChaptersTable extends Migration
{
public function up(): void
{
Schema::create('chapters', function (Blueprint $table) {
$table->id();
$table->string('hashkey')->unique();
$table->string('name');
$table->enum('level', ['national', 'region', 'province', 'city', 'barangay']);
$table->unsignedBigInteger('parent_id')->nullable();
$table->string('location_key')->nullable()->comment('Normalized slug for auto-matching UserInfo address fields');
$table->decimal('lat', 10, 7)->nullable();
$table->decimal('lng', 10, 7)->nullable();
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamps();
$table->foreign('parent_id')->references('id')->on('chapters')->nullOnDelete();
$table->index(['level', 'is_active']);
$table->index('location_key');
});
}
public function down(): void
{
Schema::dropIfExists('chapters');
}
}

View File

@@ -0,0 +1,37 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreateChapterMembersTable extends Migration
{
public function up(): void
{
Schema::create('chapter_members', function (Blueprint $table) {
$table->id();
$table->string('hashkey')->unique();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('chapter_id');
$table->string('position')->nullable()->comment('Position title from chapter_positions system setting');
$table->boolean('is_manual_override')->default(false)->comment('True if manually assigned, overriding address-based auto-assignment');
$table->boolean('is_active')->default(true);
$table->unsignedBigInteger('assigned_by')->nullable();
$table->timestamp('assigned_at')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
$table->foreign('chapter_id')->references('id')->on('chapters')->cascadeOnDelete();
$table->unique(['user_id', 'chapter_id']);
$table->index(['chapter_id', 'is_active']);
$table->index('user_id');
});
}
public function down(): void
{
Schema::dropIfExists('chapter_members');
}
}

View File

@@ -0,0 +1,29 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::create('org_str', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('organization_id');
$table->unsignedBigInteger('store_id');
$table->timestamps();
$table->foreign('organization_id')->references('id')->on('organizations')->onDelete('cascade');
$table->foreign('store_id')->references('id')->on('str')->onDelete('cascade');
$table->unique(['organization_id', 'store_id']);
$table->index('organization_id');
$table->index('store_id');
});
}
public function down(): void
{
Schema::dropIfExists('org_str');
}
};

View File

@@ -0,0 +1,32 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::create('main_organizations', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('organization_id');
$table->string('role')->comment('cooperative, ngo, corporation, sponsor, etc.');
$table->unsignedSmallInteger('priority')->default(0)->comment('0 = primary; higher values = secondary mains in same role');
$table->boolean('is_active')->default(true);
$table->json('metadata')->nullable()->comment('display name overrides, branding, tagline');
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamps();
$table->foreign('organization_id')->references('id')->on('organizations')->onDelete('cascade');
$table->index(['role', 'is_active']);
$table->index('organization_id');
$table->unique(['role', 'priority', 'is_active'], 'main_orgs_role_priority_active_unique');
});
}
public function down(): void
{
Schema::dropIfExists('main_organizations');
}
};

View File

@@ -0,0 +1,23 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::table('accounts', function (Blueprint $table) {
$table->string('theme_key')->nullable()->index()->after('description');
$table->string('theme_account_code')->nullable()->index()->after('theme_key');
});
}
public function down(): void
{
Schema::table('accounts', function (Blueprint $table) {
$table->dropColumn(['theme_key', 'theme_account_code']);
});
}
};

View File

@@ -0,0 +1,31 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
use Hypervel\Support\Facades\DB;
return new class extends Migration {
public function up(): void
{
Schema::table('accounts', function (Blueprint $table) {
$table->string('default_flow', 16)->nullable()->index()->after('type');
});
// Backfill existing rows from the old hardcoded rule so behavior is unchanged.
DB::table('accounts')
->whereIn('type', ['Revenue', 'REVENUE', 'Liability', 'LIABILITY'])
->update(['default_flow' => 'INCOME']);
DB::table('accounts')
->whereNull('default_flow')
->update(['default_flow' => 'EXPENSE']);
}
public function down(): void
{
Schema::table('accounts', function (Blueprint $table) {
$table->dropColumn('default_flow');
});
}
};

View File

@@ -0,0 +1,22 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::table('file_list', function (Blueprint $table) {
$table->string('cdn_url', 1024)->nullable()->after('filename');
});
}
public function down(): void
{
Schema::table('file_list', function (Blueprint $table) {
$table->dropColumn('cdn_url');
});
}
};

View File

@@ -0,0 +1,23 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::table('file_list', function (Blueprint $table) {
$table->boolean('is_public')->default(false)->index()->after('cdn_url');
$table->string('file_type', 100)->nullable()->index()->after('is_public');
});
}
public function down(): void
{
Schema::table('file_list', function (Blueprint $table) {
$table->dropColumn(['is_public', 'file_type']);
});
}
};

View File

@@ -0,0 +1,38 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
class CreatePersonalAccessTokensTable extends Migration
{
public function up(): void
{
Schema::dropIfExists('personal_access_tokens');
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->string('name');
$table->string('description')->nullable();
$table->string('token', 64)->unique();
$table->json('abilities')->nullable();
$table->json('allowed_ips')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->string('last_used_ip', 45)->nullable();
$table->timestamp('expires_at')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('revoked_by')->nullable();
$table->timestamp('revoked_at')->nullable();
$table->timestamps();
$table->index('expires_at');
$table->index('revoked_at');
});
}
public function down(): void
{
Schema::dropIfExists('personal_access_tokens');
}
}

View File

@@ -0,0 +1,35 @@
<?php
use Hyperf\Database\Schema\Blueprint;
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
// Scope accounts to a specific store (NULL = global / Big-3 managed)
Schema::table('accounts', function (Blueprint $table) {
$table->unsignedBigInteger('store_id')->nullable()->index()->after('parent_id');
$table->foreign('store_id')->references('id')->on('str')->nullOnDelete();
});
// Add missing columns referenced by AccountingController / AccountTransaction model
Schema::table('account_transactions', function (Blueprint $table) {
$table->string('flow', 16)->nullable()->index()->after('amount');
$table->string('notes', 500)->nullable()->after('flow');
});
}
public function down(): void
{
Schema::table('account_transactions', function (Blueprint $table) {
$table->dropColumn(['flow', 'notes']);
});
Schema::table('accounts', function (Blueprint $table) {
$table->dropForeign(['store_id']);
$table->dropColumn('store_id');
});
}
};

View File

@@ -0,0 +1,98 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::create('subscription_plans', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->string('name')->index();
$table->string('description')->nullable();
$table->decimal('price', 15, 2)->default(0);
$table->unsignedInteger('duration_days')->default(30);
// 'restrict' | 'warn' | 'auto_deduct'
$table->string('expiry_action')->default('warn');
$table->boolean('active')->default(true)->index();
$table->json('additional_details')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('created_by')->references('id')->on('users')->nullOnDelete();
$table->foreign('updated_by')->references('id')->on('users')->nullOnDelete();
$table->timestamps();
});
Schema::create('subscriptions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('user_id')->index();
$table->unsignedBigInteger('plan_id');
$table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
$table->foreign('plan_id')->references('id')->on('subscription_plans')->cascadeOnDelete();
// 'active' | 'expired' | 'cancelled' | 'pending'
$table->string('status')->default('pending')->index();
$table->dateTime('starts_at')->nullable();
$table->dateTime('expires_at')->nullable()->index();
// 'wallet' | 'gcash' | 'paymaya' — extensible for future gateways
$table->string('payment_method')->default('wallet');
$table->json('additional_details')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('created_by')->references('id')->on('users')->nullOnDelete();
$table->foreign('updated_by')->references('id')->on('users')->nullOnDelete();
$table->timestamps();
});
Schema::create('subscription_invoices', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('hashkey', 300)->unique();
$table->unsignedBigInteger('subscription_id');
$table->unsignedBigInteger('user_id')->index();
$table->foreign('subscription_id')->references('id')->on('subscriptions')->cascadeOnDelete();
$table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
$table->decimal('amount', 15, 2)->default(0);
// 'pending' | 'paid' | 'failed'
$table->string('status')->default('pending')->index();
$table->dateTime('paid_at')->nullable();
// 'wallet' | 'gcash' | 'paymaya'
$table->string('payment_method')->default('wallet');
// external gateway transaction ID, QR reference, etc.
$table->string('payment_reference')->nullable()->index();
$table->json('additional_details')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->foreign('created_by')->references('id')->on('users')->nullOnDelete();
$table->foreign('updated_by')->references('id')->on('users')->nullOnDelete();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('subscription_invoices');
Schema::dropIfExists('subscriptions');
Schema::dropIfExists('subscription_plans');
}
};

View File

@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Facades\Schema;
use Hypervel\Support\Str;
class AddDefaultOrgTypeSystemSetting extends Migration
{
public function up(): void
{
$exists = \DB::table('system_settings')->where('key', 'default_org_type')->exists();
if (!$exists) {
\DB::table('system_settings')->insert([
'hashkey' => (string) Str::uuid() . Str::random(100),
'key' => 'default_org_type',
'value' => 'COOPERATIVE',
'type' => 'select',
'options' => json_encode(['COOPERATIVE', 'NGO', 'CORPORATION']),
'group' => 'general',
'label' => 'Default Organization Type',
'description' => 'Pre-selected type when creating a new organization. Options: Cooperative, NGO, Corporation/Company.',
'created_at' => now(),
'updated_at' => now(),
]);
}
}
public function down(): void
{
\DB::table('system_settings')->where('key', 'default_org_type')->delete();
}
}

View File

@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
use Hypervel\Database\Migrations\Migration;
use Hypervel\Support\Str;
class AddBibleVerseSystemSettings extends Migration
{
public function up(): void
{
if (!\DB::table('system_settings')->where('key', 'bible_verse_text')->exists()) {
\DB::table('system_settings')->insert([
'hashkey' => (string) Str::uuid() . Str::random(100),
'key' => 'bible_verse_text',
'value' => '',
'type' => 'textarea',
'group' => 'content',
'label' => 'Bible Verse of the Day',
'description' => 'The verse text displayed on the homepage for all users. Leave empty to hide.',
'created_at' => now(),
'updated_at' => now(),
]);
}
if (!\DB::table('system_settings')->where('key', 'bible_verse_reference')->exists()) {
\DB::table('system_settings')->insert([
'hashkey' => (string) Str::uuid() . Str::random(100),
'key' => 'bible_verse_reference',
'value' => '',
'type' => 'text',
'group' => 'content',
'label' => 'Bible Verse Reference',
'description' => 'The book, chapter, and verse (e.g. "John 3:16 NIV").',
'created_at' => now(),
'updated_at' => now(),
]);
}
}
public function down(): void
{
\DB::table('system_settings')->whereIn('key', ['bible_verse_text', 'bible_verse_reference'])->delete();
}
}

View File

@@ -0,0 +1,25 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::table('chapters', function (Blueprint $table) {
$table->unsignedBigInteger('cooperative_id')->nullable()->after('name');
$table->foreign('cooperative_id')->references('id')->on('organizations')->nullOnDelete();
$table->index('cooperative_id');
});
}
public function down(): void
{
Schema::table('chapters', function (Blueprint $table) {
$table->dropForeign(['cooperative_id']);
$table->dropIndex(['cooperative_id']);
$table->dropColumn('cooperative_id');
});
}
};

View File

@@ -0,0 +1,22 @@
<?php
use Hyperf\Database\Schema\Schema;
use Hyperf\Database\Schema\Blueprint;
use Hyperf\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
Schema::table('chapter_members', function (Blueprint $table) {
$table->string('role')->nullable()->after('position')
->comment('Officer role: PRESIDENT, VICE_PRESIDENT, SECRETARY, TREASURER, AUDITOR, BOARD_MEMBER, MEMBER');
});
}
public function down(): void
{
Schema::table('chapter_members', function (Blueprint $table) {
$table->dropColumn('role');
});
}
};

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Seeders\Seeder;
use App\Support\AccountingTheme;
class AccountSeeder extends Seeder
{
/**
* Seed the chart of accounts from the active theme.
*
* Idempotent: existing accounts are matched by (theme_key, theme_account_code)
* with a parent+name fallback for pre-theme rows. User-added accounts (theme_key
* NULL) and user-renamed accounts are never touched.
*/
public function run(): void
{
AccountingTheme::apply();
}
}

View File

@@ -0,0 +1,16 @@
<?php
class DatabaseSeeder extends \Hyperf\Database\Seeders\Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
(new UserSeeder)->run();
(new SystemSettingSeeder)->run();
(new UpdateUserInfoSeeder)->run();
(new AccountSeeder)->run();
(new LandingPageSeeder)->run();
}
}

View File

@@ -0,0 +1,699 @@
<?php
use App\Models\LandingPage;
class LandingPageSeeder extends \Hyperf\Database\Seeders\Seeder
{
public function run(): void
{
foreach ($this->templates() as $tpl) {
$existing = LandingPage::where('title', $tpl['title'])->first();
if ($existing) {
$existing->update([
'html_content' => $tpl['html_content'],
'description' => $tpl['description'],
]);
} else {
LandingPage::create([
'title' => $tpl['title'],
'html_content' => $tpl['html_content'],
'description' => $tpl['description'],
'is_active' => false,
]);
}
}
}
private function templates(): array
{
return [
[
'title' => 'Bigkis Inc | Bisigco',
'description' => 'National agricultural cooperative landing page — Bigkis Inc & Bisigco (Philippines).',
'html_content' => $this->bigkisTemplate(),
],
[
'title' => 'Bigkis Inc | Bisigco v2',
'description' => 'Modern, dynamic, and premium landing page for Bigkis Inc & Bisigco.',
'html_content' => $this->bigkisTemplateV2(),
],
];
}
private function bigkisTemplate(): string
{
return <<<'HTML'
<section style="background: linear-gradient(135deg, #0038a8 0%, #0a4dbd 50%, #ce1126 100%); color: #fff; padding: 80px 20px; text-align: center; position: relative; overflow: hidden;">
<div style="position: absolute; inset: 0; background: radial-gradient(circle at 20% 30%, rgba(252,209,22,0.18) 0%, transparent 50%), radial-gradient(circle at 80% 70%, rgba(255,255,255,0.12) 0%, transparent 50%);"></div>
<div style="position: relative; max-width: 1100px; margin: 0 auto;">
<div style="display: flex; justify-content: center; align-items: center; gap: 24px; margin-bottom: 24px;">
<img src="https://cdn.jsdelivr.net/gh/telemagnadon/publicforCDN@latest/assets/bigkis_logo.jpg" alt="Bigkis Inc Logo" style="width: 180px; height: 180px; border-radius: 50%; background: #fff; padding: 8px; box-shadow: 0 12px 40px rgba(0,0,0,0.35); object-fit: cover;">
<div style="width: 3px; height: 120px; background: rgba(252,209,22,0.8); border-radius: 2px;"></div>
<img src="https://cdn.jsdelivr.net/gh/telemagnadon/publicforCDN@latest/assets/bisigco.png" alt="Bisigco Logo" style="width: 180px; height: 180px; border-radius: 50%; background: #fff; padding: 8px; box-shadow: 0 12px 40px rgba(0,0,0,0.35); object-fit: cover;">
</div>
<div style="display: inline-block; background: rgba(252,209,22,0.95); color: #0038a8; padding: 6px 18px; border-radius: 999px; font-weight: 800; font-size: 0.85rem; letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 16px;">Est. 2022 &middot; Philippines</div>
<h1 style="font-size: 3.25rem; font-weight: 900; margin-bottom: 12px; line-height: 1.05; text-shadow: 0 4px 20px rgba(0,0,0,0.3);">BIGKIS INC <span style="opacity: 0.85;">|</span> BISIGCO</h1>
<p style="font-size: 1.35rem; font-weight: 700; color: #fcd116; margin-bottom: 8px; letter-spacing: 0.05em;">Bigkis Bayanihang Masa &middot; Sincere Advocacy &middot; Responsible Action</p>
<p style="font-size: 1.1rem; max-width: 760px; margin: 0 auto 36px; opacity: 0.95; line-height: 1.6;">A national agricultural cooperative uniting <strong style="color: #fcd116;">over 1 million members worldwide</strong> &mdash; empowering Filipino farmers, growers, and communities through unity, livelihood, and shared prosperity.</p>
<div style="display: flex; gap: 14px; justify-content: center; flex-wrap: wrap;">
<a href="/login" style="display: inline-block; background: #fcd116; color: #0038a8; padding: 16px 42px; border-radius: 50px; font-weight: 800; text-decoration: none; font-size: 1.05rem; box-shadow: 0 8px 24px rgba(252,209,22,0.45);">Become a Member</a>
<a href="#about" style="display: inline-block; background: rgba(255,255,255,0.15); color: #fff; padding: 16px 42px; border-radius: 50px; font-weight: 800; text-decoration: none; font-size: 1.05rem; border: 2px solid rgba(255,255,255,0.4); backdrop-filter: blur(8px);">Learn More</a>
</div>
</div>
</section>
<section style="background: #fff; padding: 30px 20px; border-bottom: 4px solid #fcd116;">
<div style="max-width: 1100px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 24px; text-align: center;">
<div><div style="font-size: 2.4rem; font-weight: 900; color: #0038a8;">1M+</div><div style="font-size: 0.9rem; color: #555; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;">Members Worldwide</div></div>
<div><div style="font-size: 2.4rem; font-weight: 900; color: #ce1126;">81</div><div style="font-size: 0.9rem; color: #555; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;">Provinces Reached</div></div>
<div><div style="font-size: 2.4rem; font-weight: 900; color: #0a8a3e;">100%</div><div style="font-size: 0.9rem; color: #555; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;">Filipino-Led</div></div>
<div><div style="font-size: 2.4rem; font-weight: 900; color: #b8860b;">2022</div><div style="font-size: 0.9rem; color: #555; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;">Year Established</div></div>
</div>
</section>
<section id="about" style="padding: 80px 20px; background: linear-gradient(180deg, #f7faff 0%, #fff 100%);">
<div style="max-width: 1100px; margin: 0 auto;">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 48px; align-items: center;">
<div>
<div style="display: inline-block; color: #ce1126; font-weight: 800; font-size: 0.9rem; letter-spacing: 0.15em; text-transform: uppercase; margin-bottom: 12px;">About the Cooperative</div>
<h2 style="font-size: 2.4rem; font-weight: 900; color: #0038a8; margin-bottom: 18px; line-height: 1.15;">Unity in Action. Livelihood for All.</h2>
<p style="font-size: 1.05rem; line-height: 1.75; color: #333; margin-bottom: 16px;"><strong>Bigkis Inc</strong> (Bigkis Bayanihang Masa, Sincere Advocacy, Responsible Action Incorporated) is a nationwide cooperative movement built on the Filipino spirit of <em>bayanihan</em> &mdash; collective effort for the common good.</p>
<p style="font-size: 1.05rem; line-height: 1.75; color: #333; margin-bottom: 16px;">Together with <strong>BISIGCO</strong> (Bigkis Agri-Livelihood &amp; Growers Cooperative), we provide farmers, fisherfolk, and growers with access to markets, fair pricing, capacity-building, and dignified livelihood opportunities.</p>
<p style="font-size: 1.05rem; line-height: 1.75; color: #333;">From rice paddies in Luzon to upland farms in Mindanao, our members stand united &mdash; feeding the nation and uplifting their families.</p>
</div>
<div style="text-align: center;">
<img src="https://cdn.jsdelivr.net/gh/telemagnadon/publicforCDN@latest/assets/bigkis_bisigco.jpg" alt="Bigkis Inc and Bisigco — Unity in Action, Livelihood for All" style="width: 100%; max-width: 520px; border-radius: 20px; box-shadow: 0 20px 50px rgba(0,56,168,0.25);">
</div>
</div>
</div>
</section>
<section style="padding: 80px 20px; background: #fff;">
<div style="max-width: 1100px; margin: 0 auto;">
<div style="text-align: center; margin-bottom: 48px;">
<div style="display: inline-block; color: #0a8a3e; font-weight: 800; font-size: 0.9rem; letter-spacing: 0.15em; text-transform: uppercase; margin-bottom: 12px;">Our Programs</div>
<h2 style="font-size: 2.2rem; font-weight: 900; color: #0038a8; margin: 0;">What We Do for Our Members</h2>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px;">
<div style="background: #fff; padding: 36px 28px; border-radius: 18px; box-shadow: 0 8px 30px rgba(0,56,168,0.08); border-top: 5px solid #0038a8;">
<div style="font-size: 2.8rem; margin-bottom: 14px;">🌾</div>
<h3 style="font-weight: 800; color: #0038a8; margin-bottom: 10px; font-size: 1.2rem;">Agri-Livelihood</h3>
<p style="color: #555; line-height: 1.65; margin: 0;">Farm inputs, training, and market access for rice, corn, vegetables, livestock, and high-value crops.</p>
</div>
<div style="background: #fff; padding: 36px 28px; border-radius: 18px; box-shadow: 0 8px 30px rgba(0,56,168,0.08); border-top: 5px solid #ce1126;">
<div style="font-size: 2.8rem; margin-bottom: 14px;">🤝</div>
<h3 style="font-weight: 800; color: #ce1126; margin-bottom: 10px; font-size: 1.2rem;">Bayanihan Network</h3>
<p style="color: #555; line-height: 1.65; margin: 0;">A nationwide grassroots network connecting members across barangays, municipalities, and provinces.</p>
</div>
<div style="background: #fff; padding: 36px 28px; border-radius: 18px; box-shadow: 0 8px 30px rgba(0,56,168,0.08); border-top: 5px solid #fcd116;">
<div style="font-size: 2.8rem; margin-bottom: 14px;">💰</div>
<h3 style="font-weight: 800; color: #b8860b; margin-bottom: 10px; font-size: 1.2rem;">Fair Trade Marketplace</h3>
<p style="color: #555; line-height: 1.65; margin: 0;">Direct-to-consumer selling that removes middlemen and ensures fair prices for growers.</p>
</div>
<div style="background: #fff; padding: 36px 28px; border-radius: 18px; box-shadow: 0 8px 30px rgba(0,56,168,0.08); border-top: 5px solid #0a8a3e;">
<div style="font-size: 2.8rem; margin-bottom: 14px;">📚</div>
<h3 style="font-weight: 800; color: #0a8a3e; margin-bottom: 10px; font-size: 1.2rem;">Capacity Building</h3>
<p style="color: #555; line-height: 1.65; margin: 0;">Skills training, financial literacy, and modern farming workshops for sustainable growth.</p>
</div>
<div style="background: #fff; padding: 36px 28px; border-radius: 18px; box-shadow: 0 8px 30px rgba(0,56,168,0.08); border-top: 5px solid #6f42c1;">
<div style="font-size: 2.8rem; margin-bottom: 14px;">🛡️</div>
<h3 style="font-weight: 800; color: #6f42c1; margin-bottom: 10px; font-size: 1.2rem;">Member Protection</h3>
<p style="color: #555; line-height: 1.65; margin: 0;">Cooperative insurance, mutual aid, and advocacy for farmers' rights at every level of government.</p>
</div>
<div style="background: #fff; padding: 36px 28px; border-radius: 18px; box-shadow: 0 8px 30px rgba(0,56,168,0.08); border-top: 5px solid #17a2b8;">
<div style="font-size: 2.8rem; margin-bottom: 14px;">🌏</div>
<h3 style="font-weight: 800; color: #17a2b8; margin-bottom: 10px; font-size: 1.2rem;">Global OFW Bridge</h3>
<p style="color: #555; line-height: 1.65; margin: 0;">Connecting overseas Filipinos with cooperative ventures back home &mdash; investment with impact.</p>
</div>
</div>
</div>
</section>
<section style="padding: 80px 20px; background: linear-gradient(135deg, #0038a8 0%, #0a4dbd 100%); color: #fff;">
<div style="max-width: 1000px; margin: 0 auto; text-align: center;">
<div style="font-size: 4rem; line-height: 1; opacity: 0.4; margin-bottom: -10px;">&ldquo;</div>
<p style="font-size: 1.5rem; font-weight: 600; line-height: 1.5; max-width: 800px; margin: 0 auto 28px; font-style: italic;">When Filipinos stand together &mdash; farmer beside farmer, neighbor beside neighbor &mdash; no challenge is too great. This is the spirit of <span style="color: #fcd116;">Bigkis</span>.</p>
<div style="width: 60px; height: 3px; background: #fcd116; margin: 0 auto 16px;"></div>
<div style="font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; font-size: 0.9rem; opacity: 0.9;">&mdash; The Bigkis Inc Movement</div>
</div>
</section>
<section style="padding: 80px 20px; background: #fcd116; text-align: center;">
<div style="max-width: 800px; margin: 0 auto;">
<h2 style="font-size: 2.4rem; font-weight: 900; color: #0038a8; margin-bottom: 14px;">Join the Movement</h2>
<p style="font-size: 1.15rem; color: #1a1a2e; margin-bottom: 32px; line-height: 1.6;">Become part of a million-strong cooperative reshaping Philippine agriculture &mdash; one bayanihan at a time.</p>
<div style="display: flex; gap: 14px; justify-content: center; flex-wrap: wrap;">
<a href="/login" style="display: inline-block; background: #0038a8; color: #fff; padding: 16px 44px; border-radius: 50px; font-weight: 800; text-decoration: none; font-size: 1.05rem; box-shadow: 0 8px 24px rgba(0,56,168,0.35);">Member Login / Sign Up</a>
<a href="/login" style="display: inline-block; background: #ce1126; color: #fff; padding: 16px 44px; border-radius: 50px; font-weight: 800; text-decoration: none; font-size: 1.05rem; box-shadow: 0 8px 24px rgba(206,17,38,0.35);">Apply for Membership</a>
</div>
</div>
</section>
<footer style="background: #1a1a2e; color: #b8c0d0; padding: 48px 20px 28px;">
<div style="max-width: 1100px; margin: 0 auto;">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 32px; margin-bottom: 32px;">
<div>
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 14px;">
<div style="display: flex; gap: 8px;">
<img src="https://cdn.jsdelivr.net/gh/telemagnadon/publicforCDN@latest/assets/bigkis_logo.jpg" alt="Bigkis Inc" style="width: 56px; height: 56px; border-radius: 50%; background: #fff; padding: 4px;">
<img src="https://cdn.jsdelivr.net/gh/telemagnadon/publicforCDN@latest/assets/bisigco.png" alt="Bisigco" style="width: 56px; height: 56px; border-radius: 50%; background: #fff; padding: 4px;">
</div>
<div>
<div style="font-weight: 900; color: #fff; font-size: 1.05rem;">BIGKIS INC</div>
<div style="font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase; color: #fcd116;">Est. 2022</div>
</div>
</div>
<p style="font-size: 0.9rem; line-height: 1.6; margin: 0;">Bigkis Bayanihang Masa, Sincere Advocacy, Responsible Action Incorporated &mdash; a national agricultural cooperative serving Filipino farmers and communities.</p>
</div>
<div>
<div style="font-weight: 800; color: #fff; text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.85rem; margin-bottom: 12px;">Cooperative</div>
<div style="display: flex; flex-direction: column; gap: 8px; font-size: 0.92rem;">
<a href="#about" style="color: #b8c0d0; text-decoration: none;">About Bigkis</a>
<a href="#" style="color: #b8c0d0; text-decoration: none;">BISIGCO Programs</a>
<a href="#" style="color: #b8c0d0; text-decoration: none;">Membership</a>
<a href="#" style="color: #b8c0d0; text-decoration: none;">Governance</a>
</div>
</div>
<div>
<div style="font-weight: 800; color: #fff; text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.85rem; margin-bottom: 12px;">Connect</div>
<div style="display: flex; flex-direction: column; gap: 8px; font-size: 0.92rem;">
<span>📍 Republic of the Philippines</span>
<span>✉️ info@bigkis.ph</span>
<span>📞 Member Hotline</span>
</div>
</div>
</div>
<div style="border-top: 1px solid rgba(255,255,255,0.1); padding-top: 20px; text-align: center; font-size: 0.85rem;">
&copy; 2026 Bigkis Inc &amp; BISIGCO &mdash; Unity in Action. Livelihood for All. 🇵🇭
</div>
</div>
</footer>
HTML;
}
private function bigkisTemplateV2(): string
{
return <<<'HTML'
<div class="v2-landing">
<style>
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800;900&display=swap');
.v2-landing {
font-family: 'Outfit', sans-serif;
color: #1e293b;
line-height: 1.6;
overflow-x: hidden;
background-color: #f8fafc;
}
.v2-landing * {
box-sizing: border-box;
}
.v2-hero {
position: relative;
padding: 160px 20px 200px;
background: #0f172a;
color: #fff;
text-align: center;
overflow: hidden;
}
.v2-hero::before {
content: '';
position: absolute;
top: -50%; left: -50%;
width: 200%; height: 200%;
background: radial-gradient(circle at 30% 30%, rgba(0,56,168,0.5) 0%, transparent 40%),
radial-gradient(circle at 70% 70%, rgba(206,17,38,0.4) 0%, transparent 40%);
animation: v2-rotateBg 25s linear infinite;
z-index: 0;
}
@keyframes v2-rotateBg {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.v2-hero-content {
position: relative;
z-index: 1;
max-width: 1000px;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 32px;
}
.v2-glass-badge {
display: inline-flex;
align-items: center;
gap: 12px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 50px;
padding: 8px 24px;
font-weight: 600;
font-size: 0.9rem;
letter-spacing: 1px;
text-transform: uppercase;
color: #fcd116;
box-shadow: 0 4px 20px rgba(0,0,0,0.2);
}
.v2-logos {
display: flex;
justify-content: center;
align-items: center;
gap: 32px;
margin-bottom: 10px;
}
.v2-logo-wrap {
width: 140px;
height: 140px;
border-radius: 50%;
background: #fff;
padding: 6px;
box-shadow: 0 0 30px rgba(252,209,22,0.2);
transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.5s ease;
cursor: pointer;
}
.v2-logo-wrap:hover {
transform: translateY(-10px) scale(1.08);
box-shadow: 0 20px 40px rgba(252,209,22,0.5);
}
.v2-logo-wrap img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
.v2-divider {
width: 3px;
height: 60px;
background: #fcd116;
border-radius: 4px;
box-shadow: 0 0 15px #fcd116;
}
.v2-title {
font-size: 5rem;
font-weight: 900;
line-height: 1.1;
margin: 0;
background: linear-gradient(135deg, #ffffff 0%, #cbd5e1 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-transform: uppercase;
letter-spacing: -2px;
text-shadow: 0 10px 30px rgba(0,0,0,0.3);
}
.v2-subtitle {
font-size: 1.6rem;
font-weight: 600;
color: #fcd116;
margin: 0;
letter-spacing: 2px;
}
.v2-desc {
font-size: 1.25rem;
color: #e2e8f0;
max-width: 750px;
font-weight: 300;
line-height: 1.8;
margin: 0;
}
.v2-actions {
display: flex;
gap: 20px;
flex-wrap: wrap;
justify-content: center;
margin-top: 16px;
}
.v2-btn-primary {
background: #fcd116;
color: #0038a8;
padding: 18px 48px;
border-radius: 50px;
font-size: 1.1rem;
font-weight: 800;
text-decoration: none;
transition: all 0.3s ease;
box-shadow: 0 10px 30px rgba(252,209,22,0.4);
text-transform: uppercase;
letter-spacing: 1px;
}
.v2-btn-primary:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(252,209,22,0.6);
background: #fff;
}
.v2-btn-secondary {
background: transparent;
color: #fff;
padding: 16px 46px;
border-radius: 50px;
font-size: 1.1rem;
font-weight: 800;
text-decoration: none;
transition: all 0.3s ease;
border: 2px solid rgba(255,255,255,0.3);
backdrop-filter: blur(10px);
text-transform: uppercase;
letter-spacing: 1px;
}
.v2-btn-secondary:hover {
background: rgba(255,255,255,0.15);
border-color: #fff;
transform: translateY(-5px);
}
.v2-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 30px;
max-width: 1200px;
margin: -100px auto 0;
padding: 0 20px;
position: relative;
z-index: 10;
}
.v2-stat-card {
background: #fff;
border-radius: 24px;
padding: 40px 20px;
text-align: center;
box-shadow: 0 20px 50px rgba(0,0,0,0.1);
transition: transform 0.4s ease, box-shadow 0.4s ease;
border-bottom: 6px solid #0038a8;
}
.v2-stat-card:hover {
transform: translateY(-15px);
box-shadow: 0 30px 60px rgba(0,0,0,0.15);
}
.v2-stat-val {
font-size: 3.5rem;
font-weight: 900;
color: #0038a8;
margin-bottom: 8px;
line-height: 1;
}
.v2-stat-label {
font-size: 1rem;
font-weight: 700;
color: #64748b;
text-transform: uppercase;
letter-spacing: 1.5px;
}
.v2-stat-card:nth-child(2) { border-color: #ce1126; }
.v2-stat-card:nth-child(2) .v2-stat-val { color: #ce1126; }
.v2-stat-card:nth-child(3) { border-color: #10b981; }
.v2-stat-card:nth-child(3) .v2-stat-val { color: #10b981; }
.v2-stat-card:nth-child(4) { border-color: #f59e0b; }
.v2-stat-card:nth-child(4) .v2-stat-val { color: #f59e0b; }
.v2-section {
padding: 120px 20px;
}
.v2-container {
max-width: 1200px;
margin: 0 auto;
}
.v2-header {
text-align: center;
margin-bottom: 70px;
}
.v2-tag {
display: inline-block;
padding: 10px 20px;
background: rgba(0,56,168,0.08);
color: #0038a8;
border-radius: 50px;
font-weight: 800;
font-size: 0.95rem;
text-transform: uppercase;
letter-spacing: 2px;
margin-bottom: 24px;
}
.v2-h2 {
font-size: 3.5rem;
font-weight: 900;
color: #0f172a;
margin: 0;
line-height: 1.2;
}
.v2-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 40px;
}
.v2-card {
background: #fff;
border-radius: 30px;
padding: 48px 40px;
box-shadow: 0 10px 30px rgba(0,0,0,0.04);
transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
position: relative;
z-index: 1;
overflow: hidden;
}
.v2-card::before {
content: '';
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
background: linear-gradient(135deg, rgba(0,56,168,0.05) 0%, transparent 100%);
z-index: -1;
opacity: 0;
transition: opacity 0.4s ease;
}
.v2-card:hover {
transform: translateY(-20px);
box-shadow: 0 30px 60px rgba(0,56,168,0.1);
}
.v2-card:hover::before {
opacity: 1;
}
.v2-icon {
width: 80px;
height: 80px;
background: #f8fafc;
border-radius: 24px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2.5rem;
margin-bottom: 30px;
box-shadow: inset 0 2px 10px rgba(0,0,0,0.05);
transition: transform 0.4s ease;
}
.v2-card:hover .v2-icon {
transform: scale(1.1) rotate(5deg);
}
.v2-card-title {
font-size: 1.7rem;
font-weight: 800;
margin-bottom: 16px;
color: #0f172a;
}
.v2-card-desc {
color: #64748b;
font-size: 1.1rem;
line-height: 1.7;
margin: 0;
}
.v2-cta {
background: linear-gradient(135deg, #0038a8 0%, #1e3a8a 100%);
padding: 120px 20px;
text-align: center;
color: #fff;
position: relative;
border-radius: 40px;
margin: 0 20px 100px;
overflow: hidden;
}
.v2-cta::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: url('data:image/svg+xml;utf8,<svg width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg"><circle cx="30" cy="30" r="20" stroke="rgba(255,255,255,0.05)" stroke-width="1.5" fill="none"/></svg>') 0 0 / 60px 60px;
}
.v2-cta-content {
position: relative;
z-index: 2;
max-width: 800px;
margin: 0 auto;
}
.v2-cta-title {
font-size: 3.5rem;
font-weight: 900;
margin-bottom: 24px;
}
.v2-cta-desc {
font-size: 1.3rem;
color: #bfdbfe;
margin-bottom: 40px;
line-height: 1.6;
}
@media (max-width: 768px) {
.v2-title { font-size: 3.2rem; }
.v2-subtitle { font-size: 1.2rem; }
.v2-hero { padding: 120px 20px 160px; }
.v2-h2 { font-size: 2.5rem; }
.v2-cta-title { font-size: 2.5rem; }
.v2-logos { flex-direction: column; gap: 20px; }
.v2-divider { width: 60px; height: 3px; }
}
</style>
<header class="v2-hero">
<div class="v2-hero-content">
<div class="v2-glass-badge">
<span style="font-size:1.2rem">🌟</span> Premium Design Interface
</div>
<div class="v2-logos">
<div class="v2-logo-wrap">
<img src="https://cdn.jsdelivr.net/gh/telemagnadon/publicforCDN@latest/assets/bigkis_logo.jpg" alt="Bigkis Inc">
</div>
<div class="v2-divider"></div>
<div class="v2-logo-wrap">
<img src="https://cdn.jsdelivr.net/gh/telemagnadon/publicforCDN@latest/assets/bisigco.png" alt="Bisigco">
</div>
</div>
<div>
<h1 class="v2-title">Bigkis <span style="opacity:0.5;font-weight:300;">|</span> Bisigco</h1>
<h2 class="v2-subtitle">Sincere Advocacy &middot; Responsible Action</h2>
</div>
<p class="v2-desc">
A revolutionary national agricultural cooperative uniting millions across the Philippines. We empower farmers, elevate communities, and build a sustainable future through genuine <strong>bayanihan</strong>.
</p>
<div class="v2-actions">
<a href="/login" class="v2-btn-primary">Get Started Now</a>
<a href="#explore" class="v2-btn-secondary">Explore Programs</a>
</div>
</div>
</header>
<section class="v2-stats">
<div class="v2-stat-card">
<div class="v2-stat-val">1M+</div>
<div class="v2-stat-label">Active Members</div>
</div>
<div class="v2-stat-card">
<div class="v2-stat-val">81</div>
<div class="v2-stat-label">Provinces Reached</div>
</div>
<div class="v2-stat-card">
<div class="v2-stat-val">100%</div>
<div class="v2-stat-label">Filipino-Led</div>
</div>
<div class="v2-stat-card">
<div class="v2-stat-val">2022</div>
<div class="v2-stat-label">Est. Year</div>
</div>
</section>
<section id="explore" class="v2-section" style="background: #fff;">
<div class="v2-container">
<div class="v2-header">
<div class="v2-tag">Impact & Programs</div>
<h2 class="v2-h2">Empowering Growth</h2>
</div>
<div class="v2-grid">
<div class="v2-card">
<div class="v2-icon" style="color: #0038a8;">🌾</div>
<h3 class="v2-card-title">Agri-Livelihood</h3>
<p class="v2-card-desc">State-of-the-art farm inputs, comprehensive training, and exclusive market access to elevate local agriculture.</p>
</div>
<div class="v2-card">
<div class="v2-icon" style="color: #ce1126;">🤝</div>
<h3 class="v2-card-title">Bayanihan Network</h3>
<p class="v2-card-desc">A highly connected grassroots infrastructure linking members from barangays to provincial hubs seamlessly.</p>
</div>
<div class="v2-card">
<div class="v2-icon" style="color: #f59e0b;">💰</div>
<h3 class="v2-card-title">Fair Trade Hub</h3>
<p class="v2-card-desc">An optimized direct-to-consumer marketplace eliminating middlemen to maximize grower profitability.</p>
</div>
<div class="v2-card">
<div class="v2-icon" style="color: #10b981;">📚</div>
<h3 class="v2-card-title">Capacity Mastery</h3>
<p class="v2-card-desc">Advanced skill acquisition, robust financial literacy, and modern agronomy workshops.</p>
</div>
<div class="v2-card">
<div class="v2-icon" style="color: #8b5cf6;">🛡️</div>
<h3 class="v2-card-title">Member Protection</h3>
<p class="v2-card-desc">Comprehensive cooperative insurance, mutual aid funds, and unwavering advocacy for farmers' rights.</p>
</div>
<div class="v2-card">
<div class="v2-icon" style="color: #0ea5e9;">🌏</div>
<h3 class="v2-card-title">Global OFW Bridge</h3>
<p class="v2-card-desc">Strategic investment channels for overseas Filipinos to fund and grow domestic cooperative ventures.</p>
</div>
</div>
</div>
</section>
<div class="v2-container">
<div class="v2-cta">
<div class="v2-cta-content">
<h2 class="v2-cta-title">Ready to Make an Impact?</h2>
<p class="v2-cta-desc">Join our million-strong movement. Transform agriculture, secure your livelihood, and uplift the nation with Bigkis and Bisigco.</p>
<a href="/login" class="v2-btn-primary" style="background: #fff; color: #0038a8; box-shadow: 0 10px 30px rgba(255,255,255,0.3);">Become a Member</a>
</div>
</div>
</div>
</div>
HTML;
}
}

View File

@@ -0,0 +1,183 @@
<?php
use App\Models\SystemSetting;
class SystemSettingSeeder extends \Hyperf\Database\Seeders\Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$settings = [
// General Settings
[
'key' => 'app_name',
'value' => 'BukidBounty',
'type' => 'text',
'group' => 'general',
'label' => 'Application Name',
'description' => 'The public name of the platform.'
],
[
'key' => 'app_description',
'value' => 'Agricultural Management Platform & Marketplace ecosystem for modern farming communities.',
'type' => 'text',
'group' => 'general',
'label' => 'Application Description',
'description' => 'Brief description of the application.'
],
[
'key' => 'app_tagline',
'value' => 'Bounty of the Fields at Your Fingertips',
'type' => 'text',
'group' => 'general',
'label' => 'Tagline',
'description' => 'Application tagline or slogan.'
],
// Branding Settings
[
'key' => 'app_logo',
'value' => null,
'type' => 'image',
'group' => 'branding',
'label' => 'Application Logo',
'description' => 'Upload a logo to replace the default icon.'
],
[
'key' => 'primary_color',
'value' => '#0d6efd',
'type' => 'text',
'group' => 'branding',
'label' => 'Primary Color',
'description' => 'Global primary accent color for the theme. Auto-derived from the uploaded logo.'
],
[
'key' => 'accent_color',
'value' => '#533dea',
'type' => 'text',
'group' => 'branding',
'label' => 'Accent Color',
'description' => 'Secondary accent color. Auto-derived from the uploaded logo.'
],
[
'key' => 'background_tint',
'value' => '#f5f4ff',
'type' => 'text',
'group' => 'branding',
'label' => 'Background Tint',
'description' => 'Soft background tint derived from the logo for hero/home backgrounds.'
],
// Advanced Settings
[
'key' => 'footer_text',
'value' => '&copy; 2026 BukidBounty Ecosystem. All rights reserved.',
'type' => 'text',
'group' => 'advanced',
'label' => 'Footer Text',
'description' => 'Text displayed in the application footer.'
],
[
'key' => 'maintenance_mode',
'value' => 'false',
'type' => 'boolean',
'group' => 'advanced',
'label' => 'Maintenance Mode',
'description' => 'Enable or disable maintenance mode globally.'
],
[
'key' => 'priority_sectors',
'value' => json_encode(['INDIGENT', "PWD's", 'SENIOR', 'Solo Parents', "OFW's", 'Indigenious Youth', 'Farmers', 'FISHERMEN', 'Calamity', 'Retrenchment', 'Former Rebels', 'Former Violent Extremist Groups']),
'type' => 'json',
'group' => 'general',
'label' => 'Priority Sectors',
'description' => 'List of sectors eligible for priority programs and assistance.'
],
[
'key' => 'group_types',
'value' => json_encode(['COOPERATIVE', 'ASSOCIATION', 'CORPORATION', 'NGO', 'OTHER']),
'type' => 'json',
'group' => 'general',
'label' => 'Group Types',
'description' => 'Types of organizations or associations members can belong to.'
],
[
'key' => 'default_address_fields',
'value' => json_encode(['house_no', 'street', 'barangay', 'city', 'province', 'region', 'country', 'zipcode']),
'type' => 'json',
'group' => 'general',
'label' => 'Default Address Fields',
'description' => 'Standard fields for address objects in the system.'
],
[
'key' => 'app_mode',
'value' => 'corporate',
'type' => 'select',
'options' => json_encode(['corporate', 'cooperative', 'ngo', 'tandem', 'others']),
'group' => 'general',
'label' => 'Application Mode',
'description' => 'Defines the operational mode of the platform, which affects available features and terminology.'
],
[
'key' => 'main_organization',
'value' => null,
'type' => 'organization',
'group' => 'general',
'label' => 'Main Cooperative / Organization',
'description' => 'Designates the primary cooperative or organization for the platform. Used mostly when Application Mode is set to cooperative.'
],
[
'key' => 'chapter_positions',
'value' => json_encode(['National Director', 'Regional Director', 'Provincial Coordinator', 'City/Municipal Officer', 'Barangay Captain', 'Secretary', 'Treasurer', 'Auditor', 'Member']),
'type' => 'json',
'group' => 'general',
'label' => 'Chapter Positions',
'description' => 'Available position titles that can be assigned to members within regional chapters.'
],
[
'key' => 'accounting_theme',
'value' => 'blank',
'type' => 'select',
'options' => json_encode(['blank', 'general_business', 'retail_pos', 'service_business', 'agri_coop']),
'group' => 'general',
'label' => 'Accounting Theme',
'description' => 'Starter Chart of Accounts preset for this deployment. Defined in config/accounting/themes.php. Switching only changes the theme tag used for branching and drift detection — it does not migrate existing accounts.'
],
[
'key' => 'top_up_enabled',
'value' => 'false',
'type' => 'boolean',
'group' => 'advanced',
'label' => 'Top Up Enabled',
'description' => 'Enable or disable the credit top-up feature globally.'
],
[
'key' => 'default_org_type',
'value' => 'COOPERATIVE',
'type' => 'select',
'options' => json_encode(['COOPERATIVE', 'NGO', 'CORPORATION']),
'group' => 'general',
'label' => 'Default Organization Type',
'description' => 'Pre-selected type when creating a new organization. Options: Cooperative, NGO, Corporation/Company.',
],
];
foreach ($settings as $setting) {
$exists = SystemSetting::where('key', $setting['key'])->first();
if ($exists) {
// Preserve the operator's chosen value; only refresh schema/metadata
// (type, options, group, label, description) so re-seeding never
// clobbers configured settings.
$update = $setting;
unset($update['value']);
$exists->update($update);
} else {
SystemSetting::create($setting);
}
}
SystemSetting::clearCache();
}
}

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
use App\Models\User;
use App\Models\Market\UserInfo;
use Hyperf\Database\Seeders\Seeder;
use Hypervel\Support\Str;
class UpdateUserInfoSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Find or create the test user Rex Moran Loba
$user = User::where('email', 'rexm.loba@gmail.com')->first();
if (!$user) {
$user = User::create([
'hashkey' => Str::random(64),
'name' => 'Rex Loba',
'fullname' => 'Rex Moran Loba',
'email' => 'rexm.loba@gmail.com',
'mobile_number' => '09123456789',
'username' => 'rexl',
'password' => 'password', // Hash should be handled by model or manually if not
'acct_type' => 'user',
'active' => true,
]);
}
$userInfo = UserInfo::where('user_id', $user->id)->first();
if (!$userInfo) {
$userInfo = new UserInfo([
'user_id' => $user->id,
'hashkey' => Str::random(64),
]);
}
$userInfo->fill([
'firstname' => 'Rex Moran',
'lastname' => 'Loba',
'fullname' => 'Rex Moran Loba',
'email' => 'rexm.loba@gmail.com',
'mobile' => '09123456789',
'civil_status' => 'Single',
'education_level' => 'Bachelor\'s Degree',
'livelihood_source' => 'Software Development',
'is_active' => true,
]);
$userInfo->save();
}
}

View File

@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
use Hyperf\Database\Seeders\Seeder;
use App\Models\User;
use Hypervel\Support\Facades\Hash;
use Hypervel\Support\Str;
class UserSeeder extends Seeder
{
protected $users = [
[
'name' => 'Admin Ultima User',
'mobile_number' => '777',
'nickname' => 'admin',
'username' => 'admin',
'email' => 'admin@example.com',
'password' => 'OmegaPsilon32!',
'acct_type' => 'ult',
],
[
'name' => 'Super Op User',
'mobile_number' => '09111111111',
'nickname' => 'superop',
'username' => 'test_super_op',
'password' => 'TetraOmega21!',
'acct_type' => 'super operator',
],
[
'name' => 'Operator User',
'mobile_number' => '09222222222',
'nickname' => 'operator',
'username' => 'test_op',
'password' => 'HeliosAlpha21!',
'acct_type' => 'operator',
],
[
'name' => 'Coordinator User',
'mobile_number' => '09333333333',
'nickname' => 'coordinator',
'username' => 'test_coord',
'password' => 'ParagonSigma51!',
'acct_type' => 'coordinator',
],
[
'name' => 'Rider User',
'mobile_number' => '09444444444',
'nickname' => 'rider',
'username' => 'test_rider',
'password' => 'MilipedeAstra21!',
'acct_type' => 'rider',
],
[
'name' => 'POS Terminal User',
'mobile_number' => '09555555555',
'nickname' => 'pos',
'username' => 'test_pos',
'password' => 'MedicusGamma21!',
'acct_type' => 'pos terminal',
],
[
'name' => 'Standard User',
'mobile_number' => '09666666666',
'nickname' => 'user',
'username' => 'test_user',
'password' => 'OrionDraconis21!',
'acct_type' => 'user',
],
];
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
foreach ($this->users as $data) {
User::firstOrCreate(['mobile_number' => $data['mobile_number']], [
'name' => $data['name'],
// 'hashkey' => $data['hashkey'],
'nickname' => $data['nickname'] ?? null,
'username' => $data['username'] ?? null,
'email' => $data['email'] ?? null,
'email_verified_at' => now(),
'mobile_verified_at' => now(),
'password' => Hash::make($data['password']),
'acct_type' => $data['acct_type'],
'total_balance' => 0,
'total_credit' => 0,
'created_by' => null,
'updated_by' => null,
'active' => true,
'parentuid' => null,
'targetuids' => null,
'notes' => null,
'exec_command' => null,
'settings' => null,
'multiple_logins' => false,
'referralcode' => null,
'photourl' => null,
'logs' => null,
'cart' => null,
]);
}
}
}