refactor: streamline RetailStockService and OwnerVerificationService by removing unused verification logic and updating notification messages for stock changes
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-05 17:35:47 +07:00
parent c815db0042
commit 0b3bf891cc
4 changed files with 13 additions and 91 deletions

View File

@ -283,7 +283,6 @@ private function rejectVerificationRequest(OwnerVerificationRequest $request): v
RawMaterial::class => $this->rawMaterialService->rejectVerificationRequest($request),
Purchase::class => $this->purchaseService->rejectVerificationRequest($request),
MarketplaceSettings::class => null,
ProductVariant::class => $this->retailStockService->rejectRetailStockTransfer($request),
default => throw ValidationException::withMessages([
'subject_type' => 'Tipe data verifikasi tidak didukung.',
]),
@ -297,7 +296,6 @@ private function applyVerificationRequest(OwnerVerificationRequest $request): vo
RawMaterial::class => $this->rawMaterialService->applyVerificationRequest($request),
Purchase::class => $this->purchaseService->applyVerificationRequest($request),
MarketplaceSettings::class => $this->marketplaceService->applyVerificationRequest($request),
ProductVariant::class => $this->retailStockService->applyRetailStockTransfer($request),
default => throw ValidationException::withMessages([
'subject_type' => 'Tipe data verifikasi tidak didukung.',
]),

View File

@ -2,16 +2,11 @@
namespace App\Services\Manage;
use App\Enums\OwnerVerificationAction;
use App\Enums\OwnerVerificationStatus;
use App\Enums\Permission;
use App\Models\OwnerVerificationRequest;
use App\Models\ProductVariant;
use App\Models\RetailStockHistory;
use App\Models\User;
use App\Services\System\PushNotificationService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
class RetailStockService
@ -20,7 +15,7 @@ public function __construct(
private readonly PushNotificationService $pushNotificationService,
) {}
public function transfer(int $variantId, int $quantity, User $user, ?string $notes = null): ?OwnerVerificationRequest
public function transfer(int $variantId, int $quantity, User $user, ?string $notes = null): void
{
if ($quantity <= 0) {
throw ValidationException::withMessages([
@ -36,78 +31,16 @@ public function transfer(int $variantId, int $quantity, User $user, ?string $not
]);
}
$isOwner = $user->can(Permission::OWNER_VERIFICATIONS_VERIFY->value);
$this->executeTransfer($variant, $quantity, $user, $notes);
if ($isOwner) {
$this->executeTransfer($variant, $quantity, $user, $notes);
$productName = $variant->product?->name ?? $variant->name;
return null;
}
$existingPending = OwnerVerificationRequest::query()
->where('subject_type', ProductVariant::class)
->where('subject_id', $variant->id)
->where('action', OwnerVerificationAction::RETAIL_STOCK_TRANSFER)
->where('status', OwnerVerificationStatus::PENDING)
->exists();
if ($existingPending) {
throw ValidationException::withMessages([
'quantity' => 'Masih ada pengajuan transfer stok ecer yang menunggu verifikasi untuk varian ini.',
]);
}
try {
$request = OwnerVerificationRequest::create([
'action' => OwnerVerificationAction::RETAIL_STOCK_TRANSFER,
'status' => OwnerVerificationStatus::PENDING,
'subject_type' => ProductVariant::class,
'subject_id' => $variant->id,
'submitted_by_id' => $user->id,
'payload' => [
'old' => [
'stock' => $variant->stock,
'retail_stock' => $variant->retail_stock,
],
'new' => [
'quantity' => $quantity,
'stock' => $variant->stock - $quantity,
'retail_stock' => $variant->retail_stock + $quantity,
'notes' => $notes,
'variant_name' => $variant->name,
'product_name' => $variant->product?->name ?? '-',
],
],
]);
$productName = $variant->product?->name ?? $variant->name;
$this->pushNotificationService->sendToRoles(
'📦 Transfer Stok Ecer Menunggu Persetujuan Owner',
"Pengajuan transfer {$quantity} pcs stok ecer untuk varian '{$variant->name}' menunggu verifikasi owner.",
['owner', 'developer', 'direktur'],
route('admin.master.products.index', ['search' => $productName]),
);
$this->pushNotificationService->sendToUser(
'📤 Pengajuan Transfer Terkirim',
"Pengajuan transfer {$quantity} pcs stok ecer untuk varian '{$variant->name}' telah dikirim dan menunggu verifikasi owner.",
$user->id,
route('admin.master.products.index', ['search' => $productName]),
);
return $request;
} catch (ValidationException $e) {
throw $e;
} catch (\Throwable $e) {
Log::error('Gagal mengajukan transfer stok ecer: '.$e->getMessage(), [
'trace' => $e->getTraceAsString(),
]);
throw ValidationException::withMessages([
'system' => 'Terjadi kesalahan pada server. Silakan laporkan masalah ini ke pihak terkait.',
]);
}
$this->pushNotificationService->sendToRoles(
'📦 Perubahan Stok Ecer',
"Perubahan {$quantity} pcs stok ecer untuk varian '{$variant->name}' telah diterapkan.",
['owner', 'developer', 'direktur'],
route('admin.master.products.index', ['search' => $productName]),
);
}
public function applyRetailStockTransfer(OwnerVerificationRequest $request): void
@ -156,9 +89,4 @@ private function executeTransfer(ProductVariant $variant, int $quantity, User $u
]);
});
}
public function rejectRetailStockTransfer(OwnerVerificationRequest $request): void
{
// No-op: nothing was changed yet, so nothing to rollback.
}
}

View File

@ -115,7 +115,7 @@ async function submit() {
emit('submitted');
open.value = false;
toast.success('Pengajuan perubahan stok ecer berhasil dikirim. Menunggu verifikasi owner.');
toast.success('Perubahan stok ecer berhasil diterapkan.');
} catch (error) {
const message =
error instanceof Error ? error.message : 'Gagal menyimpan data.';
@ -186,11 +186,6 @@ function formatNumber(value: number): string {
<span class="font-medium tabular-nums text-blue-600">{{ formatNumber(displayRetailStock) }}</span>
</div>
</div>
<p class="text-xs text-amber-600 bg-amber-50 border border-amber-200 rounded-md px-3 py-2">
Perubahan stok ecer memerlukan persetujuan owner. Stok akan berubah setelah disetujui.
</p>
<form @submit.prevent="submit">
<FieldGroup>
<FieldSet class="grid gap-4">
@ -231,7 +226,7 @@ function formatNumber(value: number): string {
</Button>
<Button type="submit" :disabled="processing || !form.quantity || Number(form.quantity) < 1 || (hasMultipleVariants && !selectedVariantId)">
<Save class="size-4" />
{{ processing ? 'Mengirim...' : 'Ajukan Perubahan' }}
{{ processing ? 'Mengirim...' : 'Simpan' }}
</Button>
</DialogFooter>
</form>

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { ref } from 'vue';
import { RowDeleteAction, RowEditAction, RowTransferAction } from '@/components/button';
import RetailStockTransferModal from '@/components/modal/RetailStockTransferModal.vue';
@ -72,6 +73,6 @@ function handleTransferClick() {
:good-stock="transferGoodStock"
:retail-stock="transferRetailStock"
:variants="(product.variants ?? []).map(v => ({ id: v.id, name: v.name, stock: v.stock, retail_stock: v.retail_stock }))"
@submitted="() => {}"
@submitted="router.reload({ only: ['products'] })"
/>
</template>