feat: add checkVariantUsage endpoint and implement price usage validation in RawMaterial management
This commit is contained in:
parent
fa52f177e2
commit
562c5721dd
@ -5,9 +5,11 @@
|
||||
use App\Enums\RawMaterialUnit;
|
||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||
use App\Enums\CuttingStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\Master\RawMaterialRequest;
|
||||
use App\Http\Requests\Admin\ToggleStatusRequest;
|
||||
use App\Models\CuttingMaterial;
|
||||
use App\Models\RawMaterial;
|
||||
use App\Services\Master\RawMaterialService;
|
||||
use App\Support\Media\MediaPresenter;
|
||||
@ -84,6 +86,27 @@ public function destroy(Request $request, RawMaterial $rawMaterial): RedirectRes
|
||||
return redirect()->route('admin.master.raw_materials.index');
|
||||
}
|
||||
|
||||
public function checkVariantUsage(Request $request): JsonResponse
|
||||
{
|
||||
$priceIds = $request->query('price_ids', []);
|
||||
|
||||
if (! is_array($priceIds) || $priceIds === []) {
|
||||
return response()->json(['in_use' => []]);
|
||||
}
|
||||
|
||||
$priceIds = array_map('intval', $priceIds);
|
||||
|
||||
$inUse = CuttingMaterial::query()
|
||||
->whereIn('raw_material_price_id', $priceIds)
|
||||
->whereHas('cutting', fn ($q) => $q->where('status', '!=', CuttingStatus::COMPLETED))
|
||||
->pluck('raw_material_price_id')
|
||||
->unique()
|
||||
->values()
|
||||
->toArray();
|
||||
|
||||
return response()->json(['in_use' => $inUse]);
|
||||
}
|
||||
|
||||
public function toggleStatus(ToggleStatusRequest $request, RawMaterial $rawMaterial): RedirectResponse
|
||||
{
|
||||
$this->rawMaterialService->toggleStatus($rawMaterial, $request->validated(), $request->user());
|
||||
|
||||
@ -313,6 +313,27 @@ private function ensureNotUsedInActiveCutting(RawMaterial $rawMaterial): void
|
||||
}
|
||||
}
|
||||
|
||||
private function ensurePricesNotUsedInActiveCutting(array $priceIds): void
|
||||
{
|
||||
$usedPriceIds = CuttingMaterial::query()
|
||||
->whereIn('raw_material_price_id', $priceIds)
|
||||
->whereHas('cutting', fn ($q) => $q->where('status', '!=', CuttingStatus::COMPLETED))
|
||||
->pluck('raw_material_price_id')
|
||||
->unique()
|
||||
->toArray();
|
||||
|
||||
if ($usedPriceIds !== []) {
|
||||
$variantNames = RawMaterialPrice::whereIn('id', $usedPriceIds)
|
||||
->pluck('variant')
|
||||
->unique()
|
||||
->implode(', ');
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'prices' => "Variant '{$variantNames}' tidak dapat dihapus karena masih digunakan dalam proses cutting yang belum selesai.",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function applyToggleStatus(OwnerVerificationRequest $verificationRequest): void
|
||||
{
|
||||
$rawMaterial = $verificationRequest->subject;
|
||||
@ -353,6 +374,15 @@ private function applyPayloadToRawMaterial(
|
||||
->map(fn ($id) => (int) $id)
|
||||
->all();
|
||||
|
||||
$deletingPriceIds = $rawMaterial->prices()
|
||||
->whereNotIn('id', $submittedPriceIds)
|
||||
->pluck('id')
|
||||
->toArray();
|
||||
|
||||
if ($deletingPriceIds !== []) {
|
||||
$this->ensurePricesNotUsedInActiveCutting($deletingPriceIds);
|
||||
}
|
||||
|
||||
$rawMaterial->prices()
|
||||
->whereNotIn('id', $submittedPriceIds)
|
||||
->get()
|
||||
|
||||
@ -94,7 +94,23 @@ const useSamePrice = ref(prices.value.length <= 1 || allPricesHaveSameValue());
|
||||
const showDeleteConfirm = ref(false);
|
||||
const priceToDelete = ref<string | null>(null);
|
||||
|
||||
function confirmRemovePrice(clientId: string) {
|
||||
async function confirmRemovePrice(clientId: string) {
|
||||
const price = prices.value.find((p) => p.client_id === clientId);
|
||||
|
||||
if (price?.id) {
|
||||
try {
|
||||
const res = await fetch(`/admin/master/raw-materials/check-variant-usage?price_ids[]=${price.id}`);
|
||||
const data: { in_use: number[] } = await res.json();
|
||||
|
||||
if (data.in_use?.includes(price.id)) {
|
||||
toast.error(`Varian "${price.variant}" tidak dapat dihapus karena masih digunakan dalam proses cutting yang belum selesai.`);
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// proceed to confirm dialog if check fails
|
||||
}
|
||||
}
|
||||
|
||||
priceToDelete.value = clientId;
|
||||
showDeleteConfirm.value = true;
|
||||
}
|
||||
@ -223,6 +239,9 @@ function submit() {
|
||||
if (errors.system) {
|
||||
toast.error(errors.system);
|
||||
}
|
||||
if (errors.prices) {
|
||||
toast.error(errors.prices);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -146,6 +146,9 @@
|
||||
Route::prefix('raw-materials')->name('raw_materials.')
|
||||
->middleware('permission:'.Permission::RAW_MATERIALS_VIEW->value)
|
||||
->group(function () {
|
||||
Route::get('check-variant-usage', [RawMaterialController::class, 'checkVariantUsage'])
|
||||
->name('check_variant_usage');
|
||||
|
||||
Route::get('create', [RawMaterialController::class, 'create'])
|
||||
->middleware('permission:'.Permission::RAW_MATERIALS_CREATE->value)
|
||||
->name('create');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user