DONE: add notification table on kaunter, notifies pc and operasi for pembiayaan online; WIP: notification for gadaian above 10000
This commit is contained in:
@@ -64,5 +64,8 @@ DB_PASSWORD_7=root
|
||||
TENNANT_MASTER_DB=master_erahn
|
||||
TENNANT_KAUNTER_DB=kaunter_erahn
|
||||
|
||||
KAUNTER_URL=http://host.docker.internal:8081
|
||||
INTERNAL_NOTIFICATION_SECRET=erahn-local-notification-secret
|
||||
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
@@ -262,3 +262,7 @@ ONEWAYSMS_AUTH_PASS=APIUK330HDAFOUK330
|
||||
|
||||
ADMIN_PHONE_NUMBER=60193450165
|
||||
ACTIVE_JOB_SERVER=false
|
||||
|
||||
# Kaunter inbox (PC modal request → operasi bell). Same secret as kaunter INTERNAL_NOTIFICATION_SECRET.
|
||||
KAUNTER_URL=http://host.docker.internal:8081
|
||||
INTERNAL_NOTIFICATION_SECRET=
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Cawangan;
|
||||
use App\Feature;
|
||||
use App\ModalOnline;
|
||||
use App\RequestModalOnline;
|
||||
use App\Services\StaffNotificationClient;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -362,6 +363,8 @@ class ModalOnlineService
|
||||
'nota' => $nota,
|
||||
]);
|
||||
|
||||
$this->notifyOperasiModalRequest($kodcaw, $request, $jenis);
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'status' => 201,
|
||||
@@ -373,6 +376,54 @@ class ModalOnlineService
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Inbox for all operasi staff. Failures must not block the request.
|
||||
*
|
||||
* @param string $kodcaw
|
||||
* @param \App\RequestModalOnline $request
|
||||
* @param string $jenis
|
||||
* @return void
|
||||
*/
|
||||
protected function notifyOperasiModalRequest($kodcaw, $request, $jenis)
|
||||
{
|
||||
try {
|
||||
app(StaffNotificationClient::class)->notify([
|
||||
'type' => 'modal_online.pending_operasi',
|
||||
'cawangan' => $kodcaw,
|
||||
'audience' => ['role' => 'operasi'],
|
||||
'data' => [
|
||||
'request_id' => $request->id,
|
||||
'amaun' => (float) $request->amaun,
|
||||
'dimohon_oleh' => $request->dimohon_oleh,
|
||||
'jenis' => $jenis,
|
||||
'nota' => $request->nota,
|
||||
'cawangan_nama' => $this->cawanganNama($kodcaw),
|
||||
],
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Operasi modal-online notification failed: '.$e->getMessage(), [
|
||||
'kodcaw' => $kodcaw,
|
||||
'request_id' => $request->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $kodcaw
|
||||
* @return string
|
||||
*/
|
||||
protected function cawanganNama($kodcaw)
|
||||
{
|
||||
$cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $kodcaw)->first();
|
||||
if (!$cawangan) {
|
||||
return $kodcaw;
|
||||
}
|
||||
|
||||
$nama = trim((string) $cawangan->nama_cawangan);
|
||||
|
||||
return $nama !== '' ? $nama : $kodcaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* List top-up requests.
|
||||
* For PC: pass kodcaw. For Operasi: omit kodcaw (all branches).
|
||||
|
||||
@@ -11,6 +11,7 @@ use App\Feature;
|
||||
use App\Gadai;
|
||||
use App\Jobs\WhatsappPembiayaanOnlinePaid;
|
||||
use App\PembiayaanOnline;
|
||||
use App\Services\StaffNotificationClient;
|
||||
use App\Services\Whatsapp\WhatsappCloudClient;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -749,7 +750,7 @@ class PembiayaanOnlineService
|
||||
$tarikh = $now->toDateString();
|
||||
|
||||
try {
|
||||
return DB::connection($mysql)->transaction(function () use (
|
||||
$result = DB::connection($mysql)->transaction(function () use (
|
||||
$mysql,
|
||||
$kodcaw,
|
||||
$ids,
|
||||
@@ -857,6 +858,127 @@ class PembiayaanOnlineService
|
||||
'payload' => ['message' => 'Gagal hantar batch pembiayaan online'],
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($result['ok'])) {
|
||||
$this->notifyOperasiBatchSubmitted($kodcaw, $ids, $pcBy, $result['payload']);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inbox for all operasi staff after PC submit. Failures must not block the batch.
|
||||
*
|
||||
* @param string $kodcaw
|
||||
* @param array $ids
|
||||
* @param string $pcBy
|
||||
* @param array $payload
|
||||
* @return void
|
||||
*/
|
||||
protected function notifyOperasiBatchSubmitted($kodcaw, array $ids, $pcBy, array $payload)
|
||||
{
|
||||
$batch = isset($payload['batch']) ? $payload['batch'] : null;
|
||||
if (!$batch) {
|
||||
return;
|
||||
}
|
||||
|
||||
$batchId = is_array($batch) ? ($batch['id'] ?? null) : $batch->id;
|
||||
$batchNo = is_array($batch) ? ($batch['batch_no'] ?? '') : $batch->batch_no;
|
||||
$slot = is_array($batch) ? ($batch['slot'] ?? '') : $batch->slot;
|
||||
$bilangan = is_array($batch) ? ($batch['bilangan'] ?? 0) : $batch->bilangan;
|
||||
$jumlah = is_array($batch) ? ($batch['jumlah_keseluruhan'] ?? 0) : $batch->jumlah_keseluruhan;
|
||||
|
||||
if (!$batchId) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
app(StaffNotificationClient::class)->notify([
|
||||
'type' => 'pembiayaan_online.batch_operasi',
|
||||
'cawangan' => $kodcaw,
|
||||
'audience' => ['role' => 'operasi'],
|
||||
'data' => [
|
||||
'batch_id' => $batchId,
|
||||
'batch_no' => $batchNo,
|
||||
'slot' => $slot,
|
||||
'appended' => !empty($payload['appended']),
|
||||
'submitted_count' => count($ids),
|
||||
'bilangan' => $bilangan,
|
||||
'jumlah_keseluruhan' => (float) $jumlah,
|
||||
'pc_submitted_by' => $pcBy,
|
||||
'cawangan_nama' => $this->cawanganNama($kodcaw),
|
||||
],
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Operasi batch notification failed: '.$e->getMessage(), [
|
||||
'kodcaw' => $kodcaw,
|
||||
'batch_id' => $batchId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $kodcaw
|
||||
* @return string
|
||||
*/
|
||||
protected function cawanganNama($kodcaw)
|
||||
{
|
||||
$cawangan = Cawangan::on('mysql7')->where('kodcaw', '=', $kodcaw)->first();
|
||||
if (!$cawangan) {
|
||||
return $kodcaw;
|
||||
}
|
||||
|
||||
$nama = trim((string) $cawangan->nama_cawangan);
|
||||
|
||||
return $nama !== '' ? $nama : $kodcaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inbox for PC at this branch. Failures must not block the operasi action.
|
||||
*
|
||||
* @param string $kodcaw
|
||||
* @param string $type
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
protected function notifyPcPembiayaanOnline($kodcaw, $type, array $data)
|
||||
{
|
||||
try {
|
||||
app(StaffNotificationClient::class)->notify([
|
||||
'type' => $type,
|
||||
'cawangan' => $kodcaw,
|
||||
'audience' => ['role' => 'pc'],
|
||||
'data' => array_merge($data, [
|
||||
'cawangan_nama' => $this->cawanganNama($kodcaw),
|
||||
]),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('PC pembiayaan-online notification failed: '.$e->getMessage(), [
|
||||
'kodcaw' => $kodcaw,
|
||||
'type' => $type,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $line
|
||||
* @return array
|
||||
*/
|
||||
protected function lineNotifyFields($line)
|
||||
{
|
||||
if (!$line) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$isArr = is_array($line);
|
||||
|
||||
return [
|
||||
'norujukan' => $isArr ? ($line['norujukan'] ?? '') : $line->norujukan,
|
||||
'nama_pelanggan' => $isArr ? ($line['nama_pelanggan'] ?? '') : $line->nama_pelanggan,
|
||||
'pinjaman' => $isArr ? ($line['pinjaman'] ?? 0) : $line->pinjaman,
|
||||
'ops_by' => $isArr ? ($line['ops_by'] ?? '') : $line->ops_by,
|
||||
'reject_reason' => $isArr ? ($line['reject_reason'] ?? '') : $line->reject_reason,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1031,7 +1153,7 @@ class PembiayaanOnlineService
|
||||
$now = Carbon::now();
|
||||
|
||||
try {
|
||||
return DB::connection($mysql)->transaction(function () use ($mysql, $kodcaw, $id, $opsBy, $reason, $now) {
|
||||
$result = DB::connection($mysql)->transaction(function () use ($mysql, $kodcaw, $id, $opsBy, $reason, $now) {
|
||||
$line = PembiayaanOnline::on($mysql)
|
||||
->where('kodcaw', $kodcaw)
|
||||
->where('id', $id)
|
||||
@@ -1102,6 +1224,18 @@ class PembiayaanOnlineService
|
||||
'payload' => ['message' => 'Gagal tolak pembiayaan online'],
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($result['ok'])) {
|
||||
$this->notifyPcPembiayaanOnline($kodcaw, 'pembiayaan_online.rejected_pc', array_merge(
|
||||
$this->lineNotifyFields(isset($result['payload']['pembiayaan_online']) ? $result['payload']['pembiayaan_online'] : null),
|
||||
[
|
||||
'ops_by' => $opsBy,
|
||||
'reject_reason' => $reason,
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1222,7 +1356,7 @@ class PembiayaanOnlineService
|
||||
}
|
||||
|
||||
try {
|
||||
return DB::connection($mysql)->transaction(function () use (
|
||||
$result = DB::connection($mysql)->transaction(function () use (
|
||||
$mysql,
|
||||
$kodcaw,
|
||||
$id,
|
||||
@@ -1321,6 +1455,18 @@ class PembiayaanOnlineService
|
||||
'payload' => ['message' => 'Gagal tanda PAID / muat naik bukti'],
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($result['ok'])) {
|
||||
$this->notifyPcPembiayaanOnline($kodcaw, 'pembiayaan_online.paid_pc', array_merge(
|
||||
$this->lineNotifyFields(isset($result['payload']['pembiayaan_online']) ? $result['payload']['pembiayaan_online'] : null),
|
||||
[
|
||||
'paid_count' => 1,
|
||||
'ops_by' => $opsBy,
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1366,7 +1512,7 @@ class PembiayaanOnlineService
|
||||
}
|
||||
|
||||
try {
|
||||
return DB::connection($mysql)->transaction(function () use (
|
||||
$result = DB::connection($mysql)->transaction(function () use (
|
||||
$mysql,
|
||||
$kodcaw,
|
||||
$batchId,
|
||||
@@ -1458,6 +1604,19 @@ class PembiayaanOnlineService
|
||||
'payload' => ['message' => 'Gagal tanda PAID batch'],
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($result['ok'])) {
|
||||
$batch = isset($result['payload']['batch']) ? $result['payload']['batch'] : null;
|
||||
$this->notifyPcPembiayaanOnline($kodcaw, 'pembiayaan_online.paid_pc', [
|
||||
'paid_count' => isset($result['payload']['dibayar']) ? (int) $result['payload']['dibayar'] : 0,
|
||||
'batch_id' => $batch ? (is_array($batch) ? ($batch['id'] ?? null) : $batch->id) : $batchId,
|
||||
'batch_no' => $batch ? (is_array($batch) ? ($batch['batch_no'] ?? '') : $batch->batch_no) : '',
|
||||
'jumlah_keseluruhan' => $batch ? (is_array($batch) ? ($batch['jumlah_keseluruhan'] ?? 0) : $batch->jumlah_keseluruhan) : 0,
|
||||
'ops_by' => $opsBy,
|
||||
]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class StaffNotificationClient
|
||||
{
|
||||
/**
|
||||
* Ask kaunter to persist a staff inbox row. Never throws.
|
||||
*
|
||||
* @param array $payload
|
||||
* @return void
|
||||
*/
|
||||
public function notify(array $payload)
|
||||
{
|
||||
$base = rtrim((string) config('kaunter.url'), '/');
|
||||
$secret = (string) config('kaunter.notification_secret');
|
||||
|
||||
if ($base === '' || $secret === '') {
|
||||
Log::info('Staff notification skipped: KAUNTER_URL or INTERNAL_NOTIFICATION_SECRET is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
$timeout = (int) config('kaunter.notification_timeout', 3);
|
||||
if ($timeout < 1) {
|
||||
$timeout = 3;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::timeout($timeout)
|
||||
->withHeaders([
|
||||
'X-Internal-Token' => $secret,
|
||||
'Accept' => 'application/json',
|
||||
])
|
||||
->asJson()
|
||||
->post($base . '/internal/notifications', $payload);
|
||||
|
||||
if (!$response->successful()) {
|
||||
Log::warning('Staff notification to kaunter failed', [
|
||||
'status' => $response->status(),
|
||||
'body' => $response->body(),
|
||||
'type' => isset($payload['type']) ? $payload['type'] : null,
|
||||
]);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Staff notification to kaunter errored: '.$e->getMessage(), [
|
||||
'type' => isset($payload['type']) ? $payload['type'] : null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,7 @@ $app->configure('report');
|
||||
$app->configure('app_parameter');
|
||||
$app->configure('parameter');
|
||||
$app->configure('whatsapp');
|
||||
$app->configure('kaunter');
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Middleware
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'url' => env('KAUNTER_URL', ''),
|
||||
'notification_secret' => env('INTERNAL_NOTIFICATION_SECRET', ''),
|
||||
'notification_timeout' => (int) env('KAUNTER_NOTIFICATION_TIMEOUT', 3),
|
||||
];
|
||||
Reference in New Issue
Block a user