feat: replace OwnerVerificationService with PushNotificationService and update notification logic in SettingController and MarketplaceService
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (8.3) (push) Waiting to run
tests / ci (8.4) (push) Waiting to run
tests / ci (8.5) (push) Waiting to run

This commit is contained in:
Yoga Pangestu 2026-07-20 23:02:28 +07:00
parent 0f5bf66320
commit ee9bff3043
4 changed files with 51 additions and 112 deletions

View File

@ -10,7 +10,7 @@
use App\Http\Requests\Admin\System\Setting\MarketplaceRequest;
use App\Http\Requests\Admin\System\Setting\SocialMediaRequest;
use App\Http\Requests\Admin\System\Setting\SystemRequest;
use App\Services\Manage\OwnerVerificationService;
use App\Services\System\PushNotificationService;
use App\Services\System\Setting\HomepageSettingService;
use App\Services\System\Setting\HrSettingService;
use App\Services\System\Setting\MarketplaceService;
@ -31,7 +31,7 @@ public function __construct(
private readonly MarketplaceService $marketplaceService,
private readonly HrSettingService $hrSettingService,
private readonly HomepageSettingService $homepageSettingService,
private readonly OwnerVerificationService $ownerVerificationService,
private readonly PushNotificationService $pushNotificationService,
) {}
public function index(Request $request): Response
@ -44,7 +44,6 @@ public function index(Request $request): Response
'marketplace' => $this->marketplaceService->marketplaceData(),
'hr' => $this->hrSettingService->hrData(),
'homepage' => $this->homepageSettingService->homepageData(),
'hasPendingMarketplaceVerification' => $this->ownerVerificationService->hasPendingMarketplaceVerification(),
'canUpdateSystem' => $user->can(Permission::SETTINGS_UPDATE_SYSTEM->value),
'canUpdateSocialMedia' => $user->can(Permission::SETTINGS_UPDATE_SOCIAL_MEDIA->value),
'canUpdateMarketplace' => $user->can(Permission::SETTINGS_UPDATE_MARKETPLACE->value),
@ -57,6 +56,8 @@ public function updateSystem(SystemRequest $request): RedirectResponse
{
$this->systemService->updateSystem($request->validated());
$this->notifyOwnerIfAdmin($request->user(), 'Sistem', 'Pengaturan sistem');
$this->flashSuccess('Pengaturan sistem berhasil disimpan.');
return redirect()->route('admin.system.settings.index');
@ -66,6 +67,8 @@ public function updateSocialMedia(SocialMediaRequest $request): RedirectResponse
{
$this->socialMediaService->updateSocialMedia($request->validated());
$this->notifyOwnerIfAdmin($request->user(), 'Media Sosial', 'Pengaturan media sosial');
$this->flashSuccess('Pengaturan media sosial berhasil disimpan.');
return redirect()->route('admin.system.settings.index');
@ -75,11 +78,7 @@ public function updateMarketplace(MarketplaceRequest $request): RedirectResponse
{
$this->marketplaceService->updateMarketplace($request->validated(), $request->user());
if ($this->ownerVerificationService->hasPendingMarketplaceVerification()) {
$this->flashSuccess('Perubahan pengaturan marketplace berhasil diajukan dan menunggu verifikasi owner.');
} else {
$this->flashSuccess('Pengaturan marketplace berhasil disimpan.');
}
$this->flashSuccess('Pengaturan marketplace berhasil disimpan.');
return redirect()->route('admin.system.settings.index');
}
@ -88,6 +87,8 @@ public function updateHr(HrSettingRequest $request): RedirectResponse
{
$this->hrSettingService->updateHr($request->validated());
$this->notifyOwnerIfAdmin($request->user(), 'HR', 'Pengaturan HR');
$this->flashSuccess('Pengaturan HR berhasil disimpan.');
return redirect()->route('admin.system.settings.index');
@ -97,8 +98,24 @@ public function updateHomepage(HomepageSettingRequest $request): RedirectRespons
{
$this->homepageSettingService->updateHomepage($request->validated());
$this->notifyOwnerIfAdmin($request->user(), 'Homepage', 'Pengaturan homepage');
$this->flashSuccess('Pengaturan homepage berhasil disimpan.');
return redirect()->route('admin.system.settings.index');
}
private function notifyOwnerIfAdmin($user, string $sectionLabel, string $settingLabel): void
{
if ($user->can(Permission::OWNER_VERIFICATIONS_VERIFY->value)) {
return;
}
$this->pushNotificationService->sendToRoles(
"⚙️ {$sectionLabel} Diubah",
"{$settingLabel} telah diubah oleh '{$user->username}'.",
['owner', 'developer'],
route('admin.system.settings.index'),
);
}
}

View File

@ -3,8 +3,6 @@
namespace App\Services\System\Setting;
use App\Enums\OrderChannel;
use App\Enums\OwnerVerificationAction;
use App\Enums\OwnerVerificationStatus;
use App\Enums\Permission;
use App\Models\OwnerVerificationRequest;
use App\Models\User;
@ -14,7 +12,6 @@
use App\Settings\MarketplaceSettings;
use App\Support\Marketplace\MarketplaceFeeCalculator;
use App\Support\Marketplace\MarketplaceFeeRule;
use Illuminate\Validation\ValidationException;
class MarketplaceService
{
@ -80,62 +77,16 @@ public function updateMarketplace(array $validated, User $user): void
{
$this->runInTransaction(
function () use ($validated, $user): void {
if ($user->can(Permission::OWNER_VERIFICATIONS_VERIFY->value)) {
$this->saveSettings($validated);
$this->saveSettings($validated);
return;
if (! $user->can(Permission::OWNER_VERIFICATIONS_VERIFY->value)) {
$this->pushNotificationService->sendToRoles(
'⚙️ Pengaturan Marketplace Diubah',
"Pengaturan marketplace telah diubah oleh '{$user->username}'.",
['owner', 'developer'],
route('admin.system.settings.index'),
);
}
$hasPending = OwnerVerificationRequest::query()
->where('subject_type', MarketplaceSettings::class)
->pending()
->exists();
if ($hasPending) {
throw ValidationException::withMessages([
'system' => 'Perubahan pengaturan marketplace sedang menunggu verifikasi owner.',
]);
}
$settings = app(MarketplaceSettings::class);
$oldPayload = [];
$newPayload = [];
foreach ($this->tiktokFeeKeys() as $key) {
$oldPayload[$key] = $this->presentFeeRule($settings->{$key});
$newPayload[$key] = $this->normalizeFeeRule($validated[$key]);
}
foreach ($this->shopeeFeeKeys() as $key) {
$oldPayload[$key] = $this->presentFeeRule($settings->{$key});
$newPayload[$key] = $this->normalizeFeeRule($validated[$key]);
}
OwnerVerificationRequest::create([
'action' => OwnerVerificationAction::UPDATE,
'status' => OwnerVerificationStatus::PENDING,
'subject_type' => MarketplaceSettings::class,
'subject_id' => null,
'submitted_by_id' => $user->id,
'payload' => [
'old' => $oldPayload,
'new' => $newPayload,
],
]);
$this->pushNotificationService->sendToRoles(
'⚙️ Pengaturan Marketplace Menunggu Persetujuan Owner',
"Pengajuan ubah pengaturan marketplace oleh '{$user->username}' menunggu verifikasi owner.",
['owner', 'developer', 'direktur'],
route('admin.system.settings.index'),
);
$this->pushNotificationService->sendToUser(
'📤 Pengajuan Terkirim',
"Pengajuan ubah pengaturan marketplace oleh {$user->profile?->full_name} menunggu verifikasi owner.",
$user->id,
route('admin.system.settings.index'),
);
},
'Gagal memperbarui pengaturan marketplace',
);

View File

@ -24,7 +24,6 @@ defineProps<{
marketplace: MarketplaceSettingsData;
hr: HrSettingsData;
homepage: HomepageSettingsData;
hasPendingMarketplaceVerification: boolean;
canUpdateSystem: boolean;
canUpdateSocialMedia: boolean;
canUpdateMarketplace: boolean;
@ -47,7 +46,7 @@ const activeSection = ref<SettingSection>(
<SystemSection v-if="activeSection === SettingSectionConst.SYSTEM" :data="system" :can-update="canUpdateSystem" />
<HomepageSection v-else-if="activeSection === SettingSectionConst.HOMEPAGE" :data="homepage" :can-update="canUpdateHomepage" />
<SocialMediaSection v-else-if="activeSection === SettingSectionConst.SOCIAL" :data="socialMedia" :can-update="canUpdateSocialMedia" />
<MarketplaceSection v-else-if="activeSection === SettingSectionConst.MARKETPLACE" :data="marketplace" :has-pending-verification="hasPendingMarketplaceVerification" :can-update="canUpdateMarketplace" />
<MarketplaceSection v-else-if="activeSection === SettingSectionConst.MARKETPLACE" :data="marketplace" :can-update="canUpdateMarketplace" />
<HrSection v-else-if="activeSection === SettingSectionConst.HR" :data="hr" :can-update="canUpdateHr" />
</SettingLayout>
</template>

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import { Save, ShoppingBag, Store, TriangleAlert } from '@lucide/vue';
import { Save, ShoppingBag, Store } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import { Button } from '@/components/ui/button';
@ -24,7 +24,6 @@ import MarketplaceFeeField from './MarketplaceFeeField.vue';
const props = defineProps<{
data: MarketplaceSettingsData;
hasPendingVerification: boolean;
canUpdate: boolean;
}>();
@ -80,18 +79,6 @@ function submit() {
<template>
<form @submit.prevent="submit">
<div v-if="props.hasPendingVerification" class="mb-6 rounded-lg border border-yellow-200 bg-yellow-50 p-4 dark:border-yellow-900/30 dark:bg-yellow-950/20">
<div class="flex gap-3">
<TriangleAlert class="size-5 text-yellow-600 dark:text-yellow-400 shrink-0 mt-0.5" />
<div>
<h5 class="font-medium text-yellow-800 dark:text-yellow-300">Menunggu Verifikasi Owner</h5>
<p class="mt-1 text-sm text-yellow-700/90 dark:text-yellow-400/90">
Perubahan pengaturan marketplace sedang menunggu verifikasi owner. Anda tidak dapat melakukan perubahan baru hingga pengajuan ini diproses.
</p>
</div>
</div>
</div>
<div class="flex flex-col gap-6 lg:flex-row">
<nav class="flex shrink-0 flex-row gap-1 overflow-x-auto lg:w-44 lg:flex-col lg:overflow-visible">
<button v-for="item in platformItems" :key="item.key" type="button" :class="cn(
@ -112,32 +99,26 @@ function submit() {
<FieldGroup class="grid gap-4 sm:grid-cols-2">
<MarketplaceFeeField id="tiktok_shop_platform_commission"
v-model="form.tiktok_shop_platform_commission" label="Biaya Komisi Platform"
:errors="feeErrors('tiktok_shop_platform_commission')"
:disabled="props.hasPendingVerification" />
:errors="feeErrors('tiktok_shop_platform_commission')" />
<MarketplaceFeeField id="tiktok_shop_logistics_service_fee"
v-model="form.tiktok_shop_logistics_service_fee" label="Biaya Layanan Logistik"
:errors="feeErrors('tiktok_shop_logistics_service_fee')"
:disabled="props.hasPendingVerification" />
:errors="feeErrors('tiktok_shop_logistics_service_fee')" />
<MarketplaceFeeField id="tiktok_shop_dynamic_commission"
v-model="form.tiktok_shop_dynamic_commission" label="Komisi Dinamis"
:errors="feeErrors('tiktok_shop_dynamic_commission')"
:disabled="props.hasPendingVerification" />
:errors="feeErrors('tiktok_shop_dynamic_commission')" />
<MarketplaceFeeField id="tiktok_shop_order_processing_fee"
v-model="form.tiktok_shop_order_processing_fee" label="Biaya Pemrosesan Pesanan"
:errors="feeErrors('tiktok_shop_order_processing_fee')"
:disabled="props.hasPendingVerification" />
:errors="feeErrors('tiktok_shop_order_processing_fee')" />
<MarketplaceFeeField id="tiktok_shop_affiliate" v-model="form.tiktok_shop_affiliate"
label="Affiliate" :errors="feeErrors('tiktok_shop_affiliate')"
:disabled="props.hasPendingVerification" />
label="Affiliate" :errors="feeErrors('tiktok_shop_affiliate')" />
<MarketplaceFeeField id="tiktok_shop_pre_order_service_fee"
v-model="form.tiktok_shop_pre_order_service_fee" label="Biaya Layanan Pre Order"
:errors="feeErrors('tiktok_shop_pre_order_service_fee')"
:disabled="props.hasPendingVerification" />
:errors="feeErrors('tiktok_shop_pre_order_service_fee')" />
</FieldGroup>
</FieldSet>
</CardContent>
@ -148,49 +129,40 @@ function submit() {
<FieldSet>
<FieldGroup class="grid gap-4 sm:grid-cols-2">
<MarketplaceFeeField id="shopee_admin_fee" v-model="form.shopee_admin_fee"
label="Biaya Administrasi" :errors="feeErrors('shopee_admin_fee')"
:disabled="props.hasPendingVerification" />
label="Biaya Administrasi" :errors="feeErrors('shopee_admin_fee')" />
<MarketplaceFeeField id="shopee_program_fee" v-model="form.shopee_program_fee"
label="Biaya Program" :errors="feeErrors('shopee_program_fee')"
:disabled="props.hasPendingVerification" />
label="Biaya Program" :errors="feeErrors('shopee_program_fee')" />
<MarketplaceFeeField id="shopee_shipping_savings" v-model="form.shopee_shipping_savings"
label="Hemat Biaya Kirim" :errors="feeErrors('shopee_shipping_savings')"
:disabled="props.hasPendingVerification" />
label="Hemat Biaya Kirim" :errors="feeErrors('shopee_shipping_savings')" />
<MarketplaceFeeField id="shopee_premium" v-model="form.shopee_premium" label="Premi"
:errors="feeErrors('shopee_premium')"
:disabled="props.hasPendingVerification" />
:errors="feeErrors('shopee_premium')" />
<MarketplaceFeeField id="shopee_service_fee" v-model="form.shopee_service_fee"
label="Biaya Layanan" :errors="feeErrors('shopee_service_fee')"
:disabled="props.hasPendingVerification" />
label="Biaya Layanan" :errors="feeErrors('shopee_service_fee')" />
<MarketplaceFeeField id="shopee_order_processing_fee"
v-model="form.shopee_order_processing_fee" label="Biaya Proses Pesanan"
:errors="feeErrors('shopee_order_processing_fee')"
:disabled="props.hasPendingVerification" />
:errors="feeErrors('shopee_order_processing_fee')" />
<MarketplaceFeeField id="shopee_ams_commission_fee"
v-model="form.shopee_ams_commission_fee" label="Biaya Komisi AMS"
:errors="feeErrors('shopee_ams_commission_fee')"
:disabled="props.hasPendingVerification" />
:errors="feeErrors('shopee_ams_commission_fee')" />
<MarketplaceFeeField id="shopee_pre_order" v-model="form.shopee_pre_order"
label="Pre Order" :errors="feeErrors('shopee_pre_order')"
:disabled="props.hasPendingVerification" />
label="Pre Order" :errors="feeErrors('shopee_pre_order')" />
<MarketplaceFeeField id="shopee_live_extra" v-model="form.shopee_live_extra"
label="Live Extra" :errors="feeErrors('shopee_live_extra')"
:disabled="props.hasPendingVerification" />
label="Live Extra" :errors="feeErrors('shopee_live_extra')" />
</FieldGroup>
</FieldSet>
</CardContent>
</Card>
<div v-if="canUpdate" class="flex justify-end">
<Button type="submit" :disabled="form.processing || props.hasPendingVerification">
<Button type="submit" :disabled="form.processing">
<Save class="size-4" />
{{ form.processing ? 'Menyimpan...' : 'Simpan' }}
</Button>