363 lines
12 KiB
PHP
363 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Work;
|
|
use App\Models\Dealer;
|
|
use App\Models\WorkDealerPrice;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Yajra\DataTables\DataTables;
|
|
|
|
class WorkDealerPriceController extends Controller
|
|
{
|
|
/**
|
|
* Display a listing of work prices for a specific work
|
|
*/
|
|
public function index(Request $request, Work $work)
|
|
{
|
|
if ($request->ajax()) {
|
|
$data = WorkDealerPrice::with(['dealer'])
|
|
->where('work_id', $work->id)
|
|
->select('work_dealer_prices.*');
|
|
|
|
return DataTables::of($data)
|
|
->addIndexColumn()
|
|
->addColumn('dealer_name', function($row) {
|
|
return $row->dealer->name;
|
|
})
|
|
->addColumn('formatted_price', function($row) {
|
|
return $row->formatted_price;
|
|
})
|
|
->addColumn('action', function($row) {
|
|
$btn = '<div class="d-flex flex-row gap-1">';
|
|
$btn .= '<button class="btn btn-warning btn-sm" onclick="editPrice(' . $row->id . ')" title="Edit Harga">
|
|
<i class="fa fa-edit"></i>
|
|
</button>';
|
|
$btn .= '<button class="btn btn-danger btn-sm" onclick="deletePrice(' . $row->id . ')" title="Hapus Harga">
|
|
<i class="fa fa-trash"></i>
|
|
</button>';
|
|
$btn .= '</div>';
|
|
return $btn;
|
|
})
|
|
->rawColumns(['action'])
|
|
->make(true);
|
|
}
|
|
|
|
$dealers = Dealer::all();
|
|
return view('back.master.work_prices', compact('work', 'dealers'));
|
|
}
|
|
|
|
/**
|
|
* Store a newly created price
|
|
*/
|
|
public function store(Request $request)
|
|
{
|
|
try {
|
|
$request->validate([
|
|
'work_id' => 'required|exists:works,id',
|
|
'dealer_id' => 'required|exists:dealers,id',
|
|
'price' => 'required|numeric|min:0',
|
|
'currency' => 'required|string|max:3',
|
|
'is_active' => 'nullable|in:0,1',
|
|
], [
|
|
'work_id.required' => 'ID pekerjaan harus diisi',
|
|
'work_id.exists' => 'Pekerjaan tidak ditemukan',
|
|
'dealer_id.required' => 'ID dealer harus diisi',
|
|
'dealer_id.exists' => 'Dealer tidak ditemukan',
|
|
'price.required' => 'Harga harus diisi',
|
|
'price.numeric' => 'Harga harus berupa angka',
|
|
'price.min' => 'Harga minimal 0',
|
|
'currency.required' => 'Mata uang harus diisi',
|
|
'currency.max' => 'Mata uang maksimal 3 karakter',
|
|
'is_active.in' => 'Status aktif harus 0 atau 1',
|
|
]);
|
|
|
|
// Check if price already exists for this work-dealer combination (including soft deleted)
|
|
$existingPrice = WorkDealerPrice::withTrashed()
|
|
->where('work_id', $request->work_id)
|
|
->where('dealer_id', $request->dealer_id)
|
|
->first();
|
|
|
|
// Also check for active records to prevent duplicates
|
|
$activePrice = WorkDealerPrice::where('work_id', $request->work_id)
|
|
->where('dealer_id', $request->dealer_id)
|
|
->where('id', '!=', $existingPrice ? $existingPrice->id : 0)
|
|
->first();
|
|
|
|
if ($activePrice) {
|
|
return response()->json([
|
|
'status' => 422,
|
|
'message' => 'Harga untuk dealer ini sudah ada. Silakan edit harga yang sudah ada.'
|
|
], 422);
|
|
}
|
|
|
|
// Use database transaction to prevent race conditions
|
|
DB::beginTransaction();
|
|
try {
|
|
|
|
if ($existingPrice) {
|
|
if ($existingPrice->trashed()) {
|
|
// Restore soft deleted record and update
|
|
$existingPrice->restore();
|
|
}
|
|
|
|
// Update existing price
|
|
$existingPrice->update([
|
|
'price' => $request->price,
|
|
'currency' => $request->currency,
|
|
'is_active' => $request->has('is_active') ? (bool)$request->is_active : true,
|
|
]);
|
|
$price = $existingPrice;
|
|
|
|
$message = 'Harga berhasil diperbarui';
|
|
} else {
|
|
// Create new price
|
|
$price = WorkDealerPrice::create([
|
|
'work_id' => $request->work_id,
|
|
'dealer_id' => $request->dealer_id,
|
|
'price' => $request->price,
|
|
'currency' => $request->currency,
|
|
'is_active' => $request->has('is_active') ? (bool)$request->is_active : true,
|
|
]);
|
|
|
|
$message = 'Harga berhasil disimpan';
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
return response()->json([
|
|
'status' => 200,
|
|
'data' => $price,
|
|
'message' => $message
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
DB::rollback();
|
|
throw $e;
|
|
}
|
|
|
|
} catch (\Illuminate\Validation\ValidationException $e) {
|
|
return response()->json([
|
|
'status' => 422,
|
|
'message' => 'Validasi gagal',
|
|
'errors' => $e->errors()
|
|
], 422);
|
|
} catch (\Illuminate\Database\QueryException $e) {
|
|
// Handle unique constraint violation
|
|
if ($e->getCode() == 23000) {
|
|
return response()->json([
|
|
'status' => 422,
|
|
'message' => 'Harga untuk dealer ini sudah ada. Silakan edit harga yang sudah ada.'
|
|
], 422);
|
|
}
|
|
return response()->json([
|
|
'status' => 500,
|
|
'message' => 'Terjadi kesalahan database: ' . $e->getMessage()
|
|
], 500);
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'status' => 500,
|
|
'message' => 'Terjadi kesalahan: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show the form for editing the specified price
|
|
*/
|
|
public function edit($id)
|
|
{
|
|
$price = WorkDealerPrice::with(['work', 'dealer'])->findOrFail($id);
|
|
|
|
return response()->json([
|
|
'status' => 200,
|
|
'data' => $price,
|
|
'message' => 'Data harga berhasil diambil'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Update the specified price
|
|
*/
|
|
public function update(Request $request, $id)
|
|
{
|
|
$request->validate([
|
|
'price' => 'required|numeric|min:0',
|
|
'currency' => 'required|string|max:3',
|
|
'is_active' => 'boolean',
|
|
]);
|
|
|
|
$price = WorkDealerPrice::findOrFail($id);
|
|
$price->update($request->all());
|
|
|
|
return response()->json([
|
|
'status' => 200,
|
|
'message' => 'Harga berhasil diperbarui'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Remove the specified price
|
|
*/
|
|
public function destroy($id)
|
|
{
|
|
try {
|
|
$price = WorkDealerPrice::findOrFail($id);
|
|
$price->delete(); // Soft delete
|
|
|
|
return response()->json([
|
|
'status' => 200,
|
|
'message' => 'Harga berhasil dihapus'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'status' => 500,
|
|
'message' => 'Terjadi kesalahan saat menghapus harga: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get price for specific work and dealer
|
|
*/
|
|
public function getPrice(Request $request)
|
|
{
|
|
$request->validate([
|
|
'work_id' => 'required|exists:works,id',
|
|
'dealer_id' => 'required|exists:dealers,id',
|
|
]);
|
|
|
|
$price = WorkDealerPrice::getPriceForWorkAndDealer(
|
|
$request->work_id,
|
|
$request->dealer_id
|
|
);
|
|
|
|
return response()->json([
|
|
'status' => 200,
|
|
'data' => $price,
|
|
'message' => $price ? 'Harga ditemukan' : 'Harga tidak ditemukan'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Toggle status of a price
|
|
*/
|
|
public function toggleStatus(Request $request, Work $work)
|
|
{
|
|
try {
|
|
$request->validate([
|
|
'dealer_id' => 'required|exists:dealers,id',
|
|
'is_active' => 'required|in:0,1,true,false',
|
|
], [
|
|
'dealer_id.required' => 'ID dealer harus diisi',
|
|
'dealer_id.exists' => 'Dealer tidak ditemukan',
|
|
'is_active.required' => 'Status aktif harus diisi',
|
|
'is_active.in' => 'Status aktif harus 0, 1, true, atau false',
|
|
]);
|
|
|
|
// Convert string values to boolean
|
|
$isActive = filter_var($request->is_active, FILTER_VALIDATE_BOOLEAN);
|
|
|
|
// Find existing price (including soft deleted)
|
|
$existingPrice = WorkDealerPrice::withTrashed()
|
|
->where('work_id', $work->id)
|
|
->where('dealer_id', $request->dealer_id)
|
|
->first();
|
|
|
|
if (!$existingPrice) {
|
|
// Create new record with default price 0 if no record exists
|
|
$existingPrice = WorkDealerPrice::create([
|
|
'work_id' => $work->id,
|
|
'dealer_id' => $request->dealer_id,
|
|
'price' => 0,
|
|
'currency' => 'IDR',
|
|
'is_active' => $isActive,
|
|
]);
|
|
} else {
|
|
// Restore if soft deleted
|
|
if ($existingPrice->trashed()) {
|
|
$existingPrice->restore();
|
|
}
|
|
|
|
// Update status
|
|
$existingPrice->update([
|
|
'is_active' => $isActive
|
|
]);
|
|
}
|
|
|
|
return response()->json([
|
|
'status' => 200,
|
|
'data' => $existingPrice,
|
|
'message' => 'Status berhasil diubah menjadi ' . ($isActive ? 'Aktif' : 'Nonaktif')
|
|
]);
|
|
|
|
} catch (\Illuminate\Validation\ValidationException $e) {
|
|
return response()->json([
|
|
'status' => 422,
|
|
'message' => 'Validasi gagal',
|
|
'errors' => $e->errors()
|
|
], 422);
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'status' => 500,
|
|
'message' => 'Terjadi kesalahan: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Bulk create prices for a work
|
|
*/
|
|
public function bulkCreate(Request $request, Work $work)
|
|
{
|
|
$request->validate([
|
|
'prices' => 'required|array',
|
|
'prices.*.dealer_id' => 'required|exists:dealers,id',
|
|
'prices.*.price' => 'required|numeric|min:0',
|
|
'prices.*.currency' => 'required|string|max:3',
|
|
]);
|
|
|
|
DB::beginTransaction();
|
|
try {
|
|
foreach ($request->prices as $priceData) {
|
|
// Check if price already exists
|
|
$existingPrice = WorkDealerPrice::where('work_id', $work->id)
|
|
->where('dealer_id', $priceData['dealer_id'])
|
|
->first();
|
|
|
|
if ($existingPrice) {
|
|
// Update existing price
|
|
$existingPrice->update([
|
|
'price' => $priceData['price'],
|
|
'currency' => $priceData['currency'],
|
|
'is_active' => true,
|
|
]);
|
|
} else {
|
|
// Create new price
|
|
WorkDealerPrice::create([
|
|
'work_id' => $work->id,
|
|
'dealer_id' => $priceData['dealer_id'],
|
|
'price' => $priceData['price'],
|
|
'currency' => $priceData['currency'],
|
|
'is_active' => true,
|
|
]);
|
|
}
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
return response()->json([
|
|
'status' => 200,
|
|
'message' => 'Harga berhasil disimpan'
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
DB::rollback();
|
|
return response()->json([
|
|
'status' => 500,
|
|
'message' => 'Terjadi kesalahan: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
}
|