Giant Update

This commit is contained in:
Wian Drs
2026-07-31 13:57:11 +07:00
parent f68d967c8b
commit b0d08211ec
112 changed files with 6674 additions and 3 deletions
+3
View File
@@ -17,6 +17,9 @@ class DatabaseSeeder extends Seeder
$this->call([
TicketTypeSeeder::class,
MenuListSeeder::class,
TopologySeeder::class,
NotificationSeeder::class,
PaymentProviderSeeder::class,
]);
User::query()->updateOrCreate(
+158
View File
@@ -188,6 +188,28 @@ class MenuListSeeder extends Seeder
);
}
$paymentGateway = MenuList::updateOrCreate(
['slug' => 'payment-gateway'],
[
'parent_id' => null, 'name' => 'Payment Gateway', 'url' => null,
'icon' => 'cil-credit-card', 'component' => null, 'sort_order' => 80,
]
);
foreach ([
['slug' => 'payment-gateway-settings', 'name' => 'Setting', 'url' => '/payment-gateway/settings', 'sort_order' => 1],
['slug' => 'payment-gateway-logs', 'name' => 'Log Pembayaran', 'url' => '/payment-gateway/logs', 'sort_order' => 2],
] as $item) {
MenuList::updateOrCreate(['slug' => $item['slug']], [
'parent_id' => $paymentGateway->id, 'name' => $item['name'], 'url' => $item['url'],
'icon' => 'cil-credit-card', 'component' => null, 'sort_order' => $item['sort_order'],
]);
}
MenuList::updateOrCreate(['slug' => 'wallet'], [
'parent_id' => null, 'name' => 'Dompet', 'url' => '/wallet',
'icon' => 'cil-wallet', 'component' => null, 'sort_order' => 81,
]);
$nas = MenuList::updateOrCreate(
['slug' => 'nas'],
[
@@ -220,5 +242,141 @@ class MenuListSeeder extends Seeder
]
);
}
$customers = MenuList::updateOrCreate(
['slug' => 'customers'],
[
'parent_id' => null,
'name' => 'Customer',
'url' => null,
'icon' => 'cil-people',
'component' => null,
'sort_order' => 6,
'is_active' => true,
]
);
foreach ([
['slug' => 'customers-orders', 'name' => 'List Order', 'url' => '/customers/orders', 'sort_order' => 1],
['slug' => 'customers-active', 'name' => 'Aktif', 'url' => '/customers/active', 'sort_order' => 2],
['slug' => 'customers-inactive', 'name' => 'Tidak Aktif', 'url' => '/customers/inactive', 'sort_order' => 3],
['slug' => 'customers-unmanaged', 'name' => 'Unmanage', 'url' => '/customers/unmanaged', 'sort_order' => 4],
['slug' => 'customers-trash', 'name' => 'Sampah', 'url' => '/customers/trash', 'sort_order' => 5],
] as $item) {
MenuList::updateOrCreate(
['slug' => $item['slug']],
[
'parent_id' => $customers->id,
'name' => $item['name'],
'url' => $item['url'],
'icon' => 'cil-user',
'component' => null,
'sort_order' => $item['sort_order'],
'is_active' => true,
]
);
}
$billing = MenuList::updateOrCreate(
['slug' => 'billing'],
[
'parent_id' => null,
'name' => 'Tagihan',
'url' => null,
'icon' => 'cil-description',
'component' => null,
'sort_order' => 7,
'is_active' => true,
]
);
foreach ([
['slug' => 'billing-profiles', 'name' => 'Profile Tagihan', 'url' => '/billing/profiles', 'sort_order' => 1],
['slug' => 'billing-running', 'name' => 'Tagihan Berjalan', 'url' => '/billing/running', 'sort_order' => 2],
['slug' => 'billing-overdue', 'name' => 'Tunggakan', 'url' => '/billing/overdue', 'sort_order' => 3],
['slug' => 'billing-paid', 'name' => 'Lunas', 'url' => '/billing/paid', 'sort_order' => 4],
] as $item) {
MenuList::updateOrCreate(
['slug' => $item['slug']],
[
'parent_id' => $billing->id,
'name' => $item['name'],
'url' => $item['url'],
'icon' => 'cil-dollar',
'component' => null,
'sort_order' => $item['sort_order'],
'is_active' => true,
]
);
}
$topology = MenuList::updateOrCreate(
['slug' => 'topology'],
[
'parent_id' => null,
'name' => 'Topologi',
'url' => null,
'icon' => 'cil-layers',
'component' => null,
'sort_order' => 8,
'is_active' => true,
]
);
foreach ([
['slug' => 'topology-map', 'name' => 'Peta Jaringan', 'url' => '/topology/map', 'icon' => 'cil-location-pin', 'sort_order' => 1],
['slug' => 'topology-devices', 'name' => 'Perangkat', 'url' => '/topology/devices', 'icon' => 'cil-settings', 'sort_order' => 2],
['slug' => 'topology-links', 'name' => 'Jalur Kabel', 'url' => '/topology/links', 'icon' => 'cil-layers', 'sort_order' => 3],
['slug' => 'topology-network', 'name' => 'Topologi Jaringan', 'url' => '/topology/network', 'icon' => 'cil-grid', 'sort_order' => 4],
['slug' => 'topology-device-types', 'name' => 'Kategori Perangkat', 'url' => '/topology/device-types', 'icon' => 'cil-list', 'sort_order' => 5],
] as $item) {
MenuList::updateOrCreate(
['slug' => $item['slug']],
[
'parent_id' => $topology->id,
'name' => $item['name'],
'url' => $item['url'],
'icon' => $item['icon'],
'component' => null,
'sort_order' => $item['sort_order'],
'is_active' => true,
]
);
}
$notifications = MenuList::updateOrCreate(
['slug' => 'notifications-service'],
[
'parent_id' => null,
'name' => 'Notifikasi',
'url' => null,
'icon' => 'cil-bell',
'component' => null,
'sort_order' => 9,
'is_active' => true,
]
);
foreach ([
['slug' => 'notifications-broadcasts', 'name' => 'Pesan Siaran', 'url' => '/notifications-service/broadcasts', 'icon' => 'cil-speech', 'sort_order' => 1],
['slug' => 'notifications-system', 'name' => 'Notifikasi Aplikasi', 'url' => '/notifications-service/system', 'icon' => 'cil-bell', 'sort_order' => 2],
['slug' => 'notifications-wa-official', 'name' => 'WhatsApp Official', 'url' => '/notifications-service/whatsapp-official', 'icon' => 'cil-comment-square', 'sort_order' => 3],
['slug' => 'notifications-wa-unofficial', 'name' => 'WhatsApp Unofficial', 'url' => '/notifications-service/whatsapp-unofficial', 'icon' => 'cil-comment-square', 'sort_order' => 4],
['slug' => 'notifications-email', 'name' => 'Email', 'url' => '/notifications-service/email', 'icon' => 'cil-envelope-open', 'sort_order' => 5],
['slug' => 'notifications-telegram', 'name' => 'Telegram', 'url' => '/notifications-service/telegram', 'icon' => 'cil-arrow-right', 'sort_order' => 6],
] as $item) {
MenuList::updateOrCreate(
['slug' => $item['slug']],
[
'parent_id' => $notifications->id,
'name' => $item['name'],
'url' => $item['url'],
'icon' => $item['icon'],
'component' => null,
'sort_order' => $item['sort_order'],
'is_active' => true,
]
);
}
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
namespace Database\Seeders;
use App\Models\NotificationEvent;
use App\Models\NotificationTemplate;
use Illuminate\Database\Seeder;
class NotificationSeeder extends Seeder
{
public function run(): void
{
$events = [
'customer.registration' => ['Registrasi Customer', 'customer', 'Halo {{customer.name}}, registrasi Anda di {{tenant.name}} berhasil diterima.'],
'customer.activation' => ['Aktivasi Customer', 'customer', 'Halo {{customer.name}}, layanan Anda telah aktif. ID pelanggan: {{customer.customer_code}}.'],
'billing.invoice_sent' => ['Kirim Tagihan', 'billing', 'Tagihan {{invoice.invoice_number}} sebesar {{invoice.total}} telah diterbitkan. Batas isolir: {{invoice.isolation_date}}.'],
'billing.warning' => ['Peringatan Tagihan', 'billing', 'Pengingat: tagihan {{invoice.invoice_number}} sebesar {{invoice.balance}} belum dibayar.'],
'billing.isolated' => ['Isolir Pelanggan', 'billing', 'Layanan {{customer.customer_code}} memasuki masa isolir karena tagihan belum dibayar.'],
'voucher_agent.registration' => ['Registrasi Agen Voucher', 'voucher', 'Registrasi agen voucher {{agent.name}} berhasil.'],
'voucher_agent.balance_added' => ['Tambah Saldo Agen Voucher', 'voucher', 'Saldo agen {{agent.name}} bertambah {{balance.amount}}. Saldo saat ini {{balance.current}}.'],
];
$channels = ['system', 'whatsapp_official', 'whatsapp_unofficial', 'email', 'telegram'];
foreach ($events as $code => [$name, $category, $body]) {
$event = NotificationEvent::updateOrCreate(
['code' => $code],
[
'name' => $name,
'category' => $category,
'description' => "Pesan otomatis untuk {$name}",
'available_channels' => $channels,
'variables' => $this->variables($body),
'is_system' => true,
'enabled' => true,
],
);
foreach ($channels as $channel) {
NotificationTemplate::updateOrCreate(
[
'tenant_id' => null,
'notification_event_id' => $event->id,
'channel' => $channel,
'language' => 'id',
'version' => 1,
],
[
'name' => "{$name} - {$this->channelName($channel)}",
'subject' => $channel === 'email' || $channel === 'system' ? $name : null,
'body' => $body,
'approval_status' => $channel === 'whatsapp_official' ? 'pending' : 'not_required',
'enabled' => true,
'variables' => $this->variables($body),
],
);
}
}
}
private function variables(string $body): array
{
preg_match_all('/{{\s*([a-zA-Z0-9_.]+)\s*}}/', $body, $matches);
return array_values(array_unique($matches[1]));
}
private function channelName(string $channel): string
{
return match ($channel) {
'system' => 'Aplikasi',
'whatsapp_official' => 'WhatsApp Official',
'whatsapp_unofficial' => 'WhatsApp Unofficial',
'email' => 'Email',
'telegram' => 'Telegram',
};
}
}
@@ -0,0 +1,27 @@
<?php
namespace Database\Seeders;
use App\Models\PaymentProvider;
use Illuminate\Database\Seeder;
class PaymentProviderSeeder extends Seeder
{
public function run(): void
{
foreach ([
['paydisini', 'Paydisini', 'tenant', ['api_key']],
['winpay', 'Winpay', 'tenant', ['merchant_id', 'api_key', 'private_key']],
['doku', 'DOKU', 'both', ['client_id', 'secret_key']],
['flip_business', 'Flip Business', 'tenant', ['token', 'validation_token']],
['duitku', 'Duitku', 'both', ['merchant_code', 'api_key']],
['midtrans', 'Midtrans', 'platform', ['merchant_id', 'client_key', 'server_key']],
] as [$code, $name, $scope, $credentials]) {
PaymentProvider::updateOrCreate(['code' => $code], [
'name' => $name, 'scope' => $scope, 'enabled' => true,
'capabilities' => ['payment' => true, 'inquiry' => true, 'webhook' => true, 'refund' => in_array($code, ['doku', 'midtrans', 'duitku'])],
'credential_schema' => collect($credentials)->map(fn ($key) => ['key' => $key, 'label' => str($key)->replace('_', ' ')->title(), 'secret' => ! str_contains($key, 'merchant_id') && ! str_contains($key, 'client_id')])->values(),
]);
}
}
}
+54
View File
@@ -0,0 +1,54 @@
<?php
namespace Database\Seeders;
use App\Models\TopologyConnectionRule;
use App\Models\TopologyDeviceType;
use Illuminate\Database\Seeder;
class TopologySeeder extends Seeder
{
public function run(): void
{
$definitions = [
['code' => 'POP', 'name' => 'Point of Presence', 'category' => 'site', 'color' => '#dc3545'],
['code' => 'OTB', 'name' => 'Optical Termination Box', 'category' => 'termination', 'color' => '#fd7e14'],
['code' => 'JB', 'name' => 'Joint Box', 'category' => 'closure', 'color' => '#6f42c1'],
['code' => 'ODC', 'name' => 'Optical Distribution Cabinet', 'category' => 'distribution', 'color' => '#0d6efd'],
['code' => 'ODP', 'name' => 'Optical Distribution Point', 'category' => 'distribution', 'color' => '#198754'],
['code' => 'SPLITTER', 'name' => 'Splitter / Ratio', 'category' => 'splitter', 'color' => '#20c997', 'can_have_splitters' => true],
];
$types = collect($definitions)->mapWithKeys(function ($definition) {
$type = TopologyDeviceType::updateOrCreate(
['tenant_id' => null, 'code' => $definition['code']],
[
...$definition,
'tenant_id' => null,
'can_have_ports' => true,
'can_have_splitters' => $definition['can_have_splitters'] ?? false,
'is_system' => true,
'icon' => 'cil-location-pin',
'status' => 'active',
],
);
return [$type->code => $type];
});
foreach ([
['POP', 'POP'], ['POP', 'OTB'], ['OTB', 'JB'], ['OTB', 'ODC'],
['OTB', 'SPLITTER'], ['JB', 'ODC'], ['JB', 'ODP'], ['ODC', 'ODP'],
['ODC', 'SPLITTER'], ['SPLITTER', 'ODP'],
] as [$source, $target]) {
TopologyConnectionRule::updateOrCreate(
[
'tenant_id' => null,
'source_device_type_id' => $types[$source]->id,
'target_device_type_id' => $types[$target]->id,
],
['allowed' => true],
);
}
}
}