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\Enums\RawMaterialUnit;
|
||||||
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
use App\Http\Controllers\Concerns\FlashesEntityMessage;
|
||||||
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
||||||
|
use App\Enums\CuttingStatus;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\Master\RawMaterialRequest;
|
use App\Http\Requests\Admin\Master\RawMaterialRequest;
|
||||||
use App\Http\Requests\Admin\ToggleStatusRequest;
|
use App\Http\Requests\Admin\ToggleStatusRequest;
|
||||||
|
use App\Models\CuttingMaterial;
|
||||||
use App\Models\RawMaterial;
|
use App\Models\RawMaterial;
|
||||||
use App\Services\Master\RawMaterialService;
|
use App\Services\Master\RawMaterialService;
|
||||||
use App\Support\Media\MediaPresenter;
|
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');
|
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
|
public function toggleStatus(ToggleStatusRequest $request, RawMaterial $rawMaterial): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->rawMaterialService->toggleStatus($rawMaterial, $request->validated(), $request->user());
|
$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
|
public function applyToggleStatus(OwnerVerificationRequest $verificationRequest): void
|
||||||
{
|
{
|
||||||
$rawMaterial = $verificationRequest->subject;
|
$rawMaterial = $verificationRequest->subject;
|
||||||
@ -353,6 +374,15 @@ private function applyPayloadToRawMaterial(
|
|||||||
->map(fn ($id) => (int) $id)
|
->map(fn ($id) => (int) $id)
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
|
$deletingPriceIds = $rawMaterial->prices()
|
||||||
|
->whereNotIn('id', $submittedPriceIds)
|
||||||
|
->pluck('id')
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
if ($deletingPriceIds !== []) {
|
||||||
|
$this->ensurePricesNotUsedInActiveCutting($deletingPriceIds);
|
||||||
|
}
|
||||||
|
|
||||||
$rawMaterial->prices()
|
$rawMaterial->prices()
|
||||||
->whereNotIn('id', $submittedPriceIds)
|
->whereNotIn('id', $submittedPriceIds)
|
||||||
->get()
|
->get()
|
||||||
|
|||||||
@ -94,7 +94,23 @@ const useSamePrice = ref(prices.value.length <= 1 || allPricesHaveSameValue());
|
|||||||
const showDeleteConfirm = ref(false);
|
const showDeleteConfirm = ref(false);
|
||||||
const priceToDelete = ref<string | null>(null);
|
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;
|
priceToDelete.value = clientId;
|
||||||
showDeleteConfirm.value = true;
|
showDeleteConfirm.value = true;
|
||||||
}
|
}
|
||||||
@ -223,6 +239,9 @@ function submit() {
|
|||||||
if (errors.system) {
|
if (errors.system) {
|
||||||
toast.error(errors.system);
|
toast.error(errors.system);
|
||||||
}
|
}
|
||||||
|
if (errors.prices) {
|
||||||
|
toast.error(errors.prices);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -146,6 +146,9 @@
|
|||||||
Route::prefix('raw-materials')->name('raw_materials.')
|
Route::prefix('raw-materials')->name('raw_materials.')
|
||||||
->middleware('permission:'.Permission::RAW_MATERIALS_VIEW->value)
|
->middleware('permission:'.Permission::RAW_MATERIALS_VIEW->value)
|
||||||
->group(function () {
|
->group(function () {
|
||||||
|
Route::get('check-variant-usage', [RawMaterialController::class, 'checkVariantUsage'])
|
||||||
|
->name('check_variant_usage');
|
||||||
|
|
||||||
Route::get('create', [RawMaterialController::class, 'create'])
|
Route::get('create', [RawMaterialController::class, 'create'])
|
||||||
->middleware('permission:'.Permission::RAW_MATERIALS_CREATE->value)
|
->middleware('permission:'.Permission::RAW_MATERIALS_CREATE->value)
|
||||||
->name('create');
|
->name('create');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user