336 lines
11 KiB
PHP
336 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\StaffNotification;
|
|
use App\User;
|
|
|
|
class NotificationService
|
|
{
|
|
const TYPE_PEMBIAYAAN_PENDING_PC = 'pembiayaan_online.pending_pc';
|
|
const TYPE_MODAL_PENDING_OPERASI = 'modal_online.pending_operasi';
|
|
const TYPE_PEMBIAYAAN_BATCH_OPERASI = 'pembiayaan_online.batch_operasi';
|
|
const TYPE_PEMBIAYAAN_REJECTED_PC = 'pembiayaan_online.rejected_pc';
|
|
const TYPE_PEMBIAYAAN_PAID_PC = 'pembiayaan_online.paid_pc';
|
|
|
|
/**
|
|
* Create one inbox row per staff matching role + branch.
|
|
*
|
|
* @param string $role
|
|
* @param string $kodcaw
|
|
* @param array $payload
|
|
* @return \Illuminate\Support\Collection
|
|
*/
|
|
public function notifyRoleAtCawangan($role, $kodcaw, array $payload)
|
|
{
|
|
$users = User::query()
|
|
->where('roles', $role)
|
|
->where('cawangan', $kodcaw)
|
|
->get();
|
|
|
|
$created = collect();
|
|
foreach ($users as $user) {
|
|
$created->push($this->notifyUser($user, $kodcaw, $role, $payload));
|
|
}
|
|
|
|
return $created;
|
|
}
|
|
|
|
/**
|
|
* Create one inbox row per staff matching role (any branch). For HQ like operasi.
|
|
*
|
|
* @param string $role
|
|
* @param array $payload
|
|
* @return \Illuminate\Support\Collection
|
|
*/
|
|
public function notifyRole($role, array $payload)
|
|
{
|
|
$kodcaw = isset($payload['cawangan']) ? $payload['cawangan'] : null;
|
|
$users = User::query()->where('roles', $role)->get();
|
|
|
|
$created = collect();
|
|
foreach ($users as $user) {
|
|
$created->push($this->notifyUser($user, $kodcaw, $role, $payload));
|
|
}
|
|
|
|
return $created;
|
|
}
|
|
|
|
/**
|
|
* Entry point for api_arrahn (and local callers). Builds title/url from type when omitted.
|
|
*
|
|
* @param array $input
|
|
* @return \Illuminate\Support\Collection
|
|
*/
|
|
public function dispatch(array $input)
|
|
{
|
|
$type = isset($input['type']) ? $input['type'] : '';
|
|
$kodcaw = isset($input['cawangan']) ? $input['cawangan'] : null;
|
|
$audience = isset($input['audience']) && is_array($input['audience']) ? $input['audience'] : [];
|
|
$role = isset($audience['role']) ? $audience['role'] : null;
|
|
$data = isset($input['data']) && is_array($input['data']) ? $input['data'] : [];
|
|
|
|
$payload = $this->payloadForType($type, $kodcaw, $data);
|
|
|
|
if (!empty($input['title'])) {
|
|
$payload['title'] = $input['title'];
|
|
}
|
|
if (array_key_exists('body', $input) && $input['body'] !== null && $input['body'] !== '') {
|
|
$payload['body'] = $input['body'];
|
|
}
|
|
if (!empty($input['url'])) {
|
|
$payload['url'] = $input['url'];
|
|
}
|
|
|
|
if ($role === 'operasi') {
|
|
return $this->notifyRole('operasi', $payload);
|
|
}
|
|
|
|
if ($role && $kodcaw) {
|
|
return $this->notifyRoleAtCawangan($role, $kodcaw, $payload);
|
|
}
|
|
|
|
return collect();
|
|
}
|
|
|
|
/**
|
|
* @param string $type
|
|
* @param string|null $kodcaw
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
protected function payloadForType($type, $kodcaw, array $data)
|
|
{
|
|
if ($type === self::TYPE_MODAL_PENDING_OPERASI) {
|
|
$jenis = isset($data['jenis']) ? strtoupper((string) $data['jenis']) : 'HAD';
|
|
$label = $jenis === 'TOPUP' ? 'tambah modal' : 'had modal';
|
|
$nama = !empty($data['cawangan_nama']) ? $data['cawangan_nama'] : $kodcaw;
|
|
$amaun = number_format(isset($data['amaun']) ? (float) $data['amaun'] : 0, 2);
|
|
$oleh = isset($data['dimohon_oleh']) ? trim((string) $data['dimohon_oleh']) : '';
|
|
|
|
return [
|
|
'type' => $type,
|
|
'cawangan' => $kodcaw,
|
|
'title' => 'Permohonan modal online',
|
|
'body' => sprintf(
|
|
'%s mohon %s RM %s%s',
|
|
$nama,
|
|
$label,
|
|
$amaun,
|
|
$oleh !== '' ? ' — '.$oleh : ''
|
|
),
|
|
'url' => '/pembiayaan-online/operasi/topup',
|
|
'data' => $data,
|
|
];
|
|
}
|
|
|
|
if ($type === self::TYPE_PEMBIAYAAN_BATCH_OPERASI) {
|
|
$nama = !empty($data['cawangan_nama']) ? $data['cawangan_nama'] : $kodcaw;
|
|
$batchNo = !empty($data['batch_no']) ? $data['batch_no'] : 'batch';
|
|
$batchId = isset($data['batch_id']) ? $data['batch_id'] : null;
|
|
$submitted = isset($data['submitted_count']) ? (int) $data['submitted_count'] : 0;
|
|
$jumlah = number_format(isset($data['jumlah_keseluruhan']) ? (float) $data['jumlah_keseluruhan'] : 0, 2);
|
|
$oleh = isset($data['pc_submitted_by']) ? trim((string) $data['pc_submitted_by']) : '';
|
|
$appended = !empty($data['appended']);
|
|
|
|
if ($appended) {
|
|
$body = sprintf(
|
|
'%s tambah %d rekod ke %s (RM %s)%s',
|
|
$nama,
|
|
$submitted,
|
|
$batchNo,
|
|
$jumlah,
|
|
$oleh !== '' ? ' — '.$oleh : ''
|
|
);
|
|
} else {
|
|
$body = sprintf(
|
|
'%s hantar %s — %d rekod (RM %s)%s',
|
|
$nama,
|
|
$batchNo,
|
|
$submitted,
|
|
$jumlah,
|
|
$oleh !== '' ? ' — '.$oleh : ''
|
|
);
|
|
}
|
|
|
|
return [
|
|
'type' => $type,
|
|
'cawangan' => $kodcaw,
|
|
'title' => 'Batch pembiayaan online',
|
|
'body' => $body,
|
|
'url' => ($kodcaw && $batchId)
|
|
? '/pembiayaan-online/operasi/'.$kodcaw.'/batches/'.$batchId
|
|
: '/pembiayaan-online/operasi',
|
|
'data' => $data,
|
|
];
|
|
}
|
|
|
|
if ($type === self::TYPE_PEMBIAYAAN_REJECTED_PC) {
|
|
$norujukan = !empty($data['norujukan']) ? $data['norujukan'] : 'rekod';
|
|
$reason = isset($data['reject_reason']) ? trim((string) $data['reject_reason']) : '';
|
|
$amaun = number_format(isset($data['pinjaman']) ? (float) $data['pinjaman'] : 0, 2);
|
|
|
|
return [
|
|
'type' => $type,
|
|
'cawangan' => $kodcaw,
|
|
'title' => 'Pembiayaan online ditolak',
|
|
'body' => sprintf(
|
|
'%s (RM %s) ditolak%s',
|
|
$norujukan,
|
|
$amaun,
|
|
$reason !== '' ? ' — '.$reason : ''
|
|
),
|
|
'url' => '/pembiayaan-online/pc',
|
|
'data' => $data,
|
|
];
|
|
}
|
|
|
|
if ($type === self::TYPE_PEMBIAYAAN_PAID_PC) {
|
|
$paidCount = isset($data['paid_count']) ? (int) $data['paid_count'] : 1;
|
|
$batchNo = !empty($data['batch_no']) ? $data['batch_no'] : '';
|
|
$norujukan = !empty($data['norujukan']) ? $data['norujukan'] : '';
|
|
$nama = isset($data['nama_pelanggan']) ? trim((string) $data['nama_pelanggan']) : '';
|
|
$amaun = number_format(
|
|
isset($data['pinjaman'])
|
|
? (float) $data['pinjaman']
|
|
: (isset($data['jumlah_keseluruhan']) ? (float) $data['jumlah_keseluruhan'] : 0),
|
|
2
|
|
);
|
|
|
|
if ($paidCount > 1 || ($batchNo !== '' && $norujukan === '')) {
|
|
$body = sprintf(
|
|
'%d rekod telah dibayar%s (RM %s)',
|
|
$paidCount > 0 ? $paidCount : 0,
|
|
$batchNo !== '' ? ' dalam '.$batchNo : '',
|
|
$amaun
|
|
);
|
|
} else {
|
|
$body = sprintf(
|
|
'%s telah dibayar (RM %s)%s',
|
|
$norujukan !== '' ? $norujukan : 'Rekod',
|
|
$amaun,
|
|
$nama !== '' ? ' — '.$nama : ''
|
|
);
|
|
}
|
|
|
|
return [
|
|
'type' => $type,
|
|
'cawangan' => $kodcaw,
|
|
'title' => 'Pembiayaan online telah dibayar',
|
|
'body' => $body,
|
|
'url' => '/pembiayaan-online/pc/paid',
|
|
'data' => $data,
|
|
];
|
|
}
|
|
|
|
return [
|
|
'type' => $type,
|
|
'cawangan' => $kodcaw,
|
|
'title' => isset($data['title']) ? $data['title'] : $type,
|
|
'body' => isset($data['body']) ? $data['body'] : null,
|
|
'url' => isset($data['url']) ? $data['url'] : null,
|
|
'data' => $data,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Create one inbox row for a specific user.
|
|
*
|
|
* @param \App\User $user
|
|
* @param string|null $kodcaw
|
|
* @param string|null $role
|
|
* @param array $payload
|
|
* @return \App\StaffNotification
|
|
*/
|
|
public function notifyUser(User $user, $kodcaw, $role, array $payload)
|
|
{
|
|
return StaffNotification::create([
|
|
'user_id' => $user->id,
|
|
'cawangan' => $kodcaw,
|
|
'role' => $role ?: $user->roles,
|
|
'type' => $payload['type'],
|
|
'title' => $payload['title'],
|
|
'body' => isset($payload['body']) ? $payload['body'] : null,
|
|
'url' => isset($payload['url']) ? $payload['url'] : null,
|
|
'data' => isset($payload['data']) ? $payload['data'] : null,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @param \App\User $user
|
|
* @param int $limit
|
|
* @return \Illuminate\Support\Collection
|
|
*/
|
|
public function inboxFor(User $user, $limit = 20)
|
|
{
|
|
return StaffNotification::query()
|
|
->where('user_id', $user->id)
|
|
->orderByDesc('id')
|
|
->limit($limit)
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* @param \App\User $user
|
|
* @return int
|
|
*/
|
|
public function unreadCount(User $user)
|
|
{
|
|
return StaffNotification::query()
|
|
->where('user_id', $user->id)
|
|
->unread()
|
|
->count();
|
|
}
|
|
|
|
/**
|
|
* @param \App\User $user
|
|
* @param int $id
|
|
* @return \App\StaffNotification|null
|
|
*/
|
|
public function markAsRead(User $user, $id)
|
|
{
|
|
$notification = StaffNotification::query()
|
|
->where('user_id', $user->id)
|
|
->where('id', $id)
|
|
->first();
|
|
|
|
if (!$notification) {
|
|
return null;
|
|
}
|
|
|
|
if ($notification->read_at === null) {
|
|
$notification->read_at = now();
|
|
$notification->save();
|
|
}
|
|
|
|
return $notification;
|
|
}
|
|
|
|
/**
|
|
* @param \App\User $user
|
|
* @return int
|
|
*/
|
|
public function markAllAsRead(User $user)
|
|
{
|
|
return StaffNotification::query()
|
|
->where('user_id', $user->id)
|
|
->unread()
|
|
->update(['read_at' => now()]);
|
|
}
|
|
|
|
/**
|
|
* @param \App\User $user
|
|
* @param int $limit
|
|
* @return array
|
|
*/
|
|
public function inboxPayload(User $user, $limit = 20)
|
|
{
|
|
return [
|
|
'unread_count' => $this->unreadCount($user),
|
|
'notifications' => $this->inboxFor($user, $limit)->map(function (StaffNotification $notification) {
|
|
return $notification->toInboxArray();
|
|
})->values(),
|
|
];
|
|
}
|
|
}
|