fix form create update postcheck and precheck
This commit is contained in:
@@ -55,7 +55,6 @@ class AdminController extends Controller
|
||||
}
|
||||
|
||||
$ajax_url = route('dashboard_data').'?month='.$month.'&year='.$year.'&dealer='.$dealer;
|
||||
// dd($ajax_url);
|
||||
return view('dashboard', compact('month','year', 'ajax_url', 'dealer', 'dealer_datas'));
|
||||
}
|
||||
|
||||
@@ -134,7 +133,6 @@ class AdminController extends Controller
|
||||
$dealer_work_trx = DB::statement("PREPARE stmt FROM @sql");
|
||||
$dealer_work_trx = DB::select(DB::raw("EXECUTE stmt"));
|
||||
DB::statement('DEALLOCATE PREPARE stmt');
|
||||
// DD($dealer_work_trx);
|
||||
$theads = ['DEALER'];
|
||||
$dealer_names = [];
|
||||
$dealer_trx = [];
|
||||
@@ -165,7 +163,6 @@ class AdminController extends Controller
|
||||
|
||||
$dealer_names[] = $dealer_work->DEALER;
|
||||
}
|
||||
// dd($dealer_trx);
|
||||
$dealer_trx = array_values($dealer_trx);
|
||||
$dealer = $request->dealer;
|
||||
$month = $request->month;
|
||||
@@ -319,7 +316,6 @@ class AdminController extends Controller
|
||||
$prev_mth_end = $prev_mth[0].'-'.$prev_mth[1].'-'.date('t', strtotime($prev_mth_start));
|
||||
}
|
||||
|
||||
// dd($prev_mth_end);
|
||||
$yesterday_month_trx = Transaction::where('work_id', $work1->id)->where('dealer_id', $dealer->id)->whereDate('date', '>=', $prev_mth_start)->whereDate('date', '<=', $prev_mth_end)->sum('qty');
|
||||
|
||||
if(array_key_exists($work1->id, $prev_month_trxs_total)) {
|
||||
@@ -528,16 +524,12 @@ class AdminController extends Controller
|
||||
|
||||
// $month_trxs_total = array_values($month_trxs_total);
|
||||
// $yesterday_month_trxs_total = array_values($yesterday_month_trxs_total);
|
||||
// dd(["month_trxs_total" => $month_trxs_total, "yesterday_month_trxs_total" => $yesterday_month_trxs_total, "works" => $works->toArray()]);
|
||||
// dd($month_trxs_total);
|
||||
// dd($yesterday_month_trxs_total);
|
||||
$final_month_trxs_total = [];
|
||||
$final_yesterday_month_trxs_total = [];
|
||||
foreach($works as $work1) {
|
||||
$final_month_trxs_total[$work1->id] = array_key_exists($work1->id, $month_trxs_total) ? $month_trxs_total[$work1->id] : 0;
|
||||
$final_yesterday_month_trxs_total[$work1->id] = $yesterday_month_trxs_total[$work1->id];
|
||||
}
|
||||
// dd([$final_month_trxs_total, $final_yesterday_month_trxs_total]);
|
||||
$month_trxs_total = array_values($final_month_trxs_total);
|
||||
$yesterday_month_trxs_total = array_values($final_yesterday_month_trxs_total);
|
||||
$totals = [];
|
||||
|
||||
@@ -93,7 +93,6 @@ class ApiController extends Controller
|
||||
$prev_mth_end = $prev_mth[0].'-'.$prev_mth[1].'-'.date('t');
|
||||
}
|
||||
|
||||
// dd($prev_mth_end);
|
||||
$yesterday_month_trx = Transaction::where('work_id', $work1->id)->where('dealer_id', $id)->whereDate('date', '>=', $prev_mth_start)->whereDate('date', '<=', $prev_mth_end)->sum('qty');
|
||||
|
||||
if(array_key_exists($work1->id, $yesterday_month_trxs_total)) {
|
||||
@@ -153,7 +152,6 @@ class ApiController extends Controller
|
||||
$final_month_trxs_total[$work1->id] = $month_trxs_total[$work1->id];
|
||||
$final_yesterday_month_trxs_total[$work1->id] = $yesterday_month_trxs_total[$work1->id];
|
||||
}
|
||||
// dd([$final_month_trxs_total, $final_yesterday_month_trxs_total]);
|
||||
$month_trxs_total = array_values($final_month_trxs_total);
|
||||
$yesterday_month_trxs_total = array_values($final_yesterday_month_trxs_total);
|
||||
|
||||
|
||||
@@ -472,7 +472,6 @@ class ReportController extends Controller
|
||||
|
||||
$sa_names = json_encode($sa_names);
|
||||
$trx_data = json_encode(array_values($trx_data));
|
||||
// dd($trx_data);
|
||||
$work_count = count($works);
|
||||
$month = $request->month;
|
||||
$dealer_id = $request->dealer;
|
||||
@@ -703,11 +702,28 @@ class ReportController extends Controller
|
||||
}
|
||||
|
||||
$data = Transaction::leftJoin('users', 'users.id', '=', 'transactions.user_id')
|
||||
->leftJoin('users as sa', 'sa.id', '=', 'transactions.user_sa_id')
|
||||
->leftJoin('works as w', 'w.id', '=', 'transactions.work_id')
|
||||
->leftJoin('categories as cat', 'cat.id', '=', 'w.category_id')
|
||||
->leftJoin('dealers as d', 'd.id', '=', 'transactions.dealer_id')
|
||||
->select('transactions.id', 'transactions.status', 'transactions.user_id as user_id', 'transactions.user_sa_id as user_sa_id', 'users.name as username', 'sa.name as sa_name', 'cat.name as category_name', 'w.name as workname', 'transactions.qty as qty', 'transactions.date as date', 'transactions.police_number as police_number', 'transactions.warranty as warranty', 'transactions.spk as spk', 'transactions.dealer_id', 'd.name as dealer_name');
|
||||
->leftJoin('users as sa', 'sa.id', '=', 'transactions.user_sa_id')
|
||||
->leftJoin('works as w', 'w.id', '=', 'transactions.work_id')
|
||||
->leftJoin('categories as cat', 'cat.id', '=', 'w.category_id')
|
||||
->leftJoin('dealers as d', 'd.id', '=', 'transactions.dealer_id')
|
||||
->leftJoin('prechecks as pre', 'pre.transaction_id', '=', 'transactions.id')
|
||||
->leftJoin('postchecks as post', 'post.transaction_id', '=', 'transactions.id')
|
||||
->select(
|
||||
'transactions.id',
|
||||
'transactions.status',
|
||||
'users.name as username',
|
||||
'sa.name as sa_name',
|
||||
'cat.name as category_name',
|
||||
'w.name as workname',
|
||||
'transactions.qty as qty',
|
||||
'transactions.date as date',
|
||||
'transactions.police_number as police_number',
|
||||
'transactions.warranty as warranty',
|
||||
'transactions.spk as spk',
|
||||
'd.name as dealer_name',
|
||||
DB::raw('pre.id as precheck_id'),
|
||||
DB::raw('post.id as postcheck_id')
|
||||
);
|
||||
|
||||
// Filter by allowed dealers based on user role
|
||||
if($allowedDealers->count() > 0) {
|
||||
@@ -747,24 +763,70 @@ class ReportController extends Controller
|
||||
$data->orderBy('date', 'DESC');
|
||||
return DataTables::of($data)->addIndexColumn()
|
||||
->addColumn('action', function($row) use ($menu) {
|
||||
$btn = '<div class="d-flex justify-content-center">';
|
||||
$btn = '<div class="d-flex justify-content-center align-items-center flex-wrap">';
|
||||
|
||||
if($row->status == 1) {
|
||||
if(Gate::allows('delete', $menu)) {
|
||||
$btn .= ' <button class="btn btn-danger btn-sm btn-bold mr-2" data-action="'. route('report.transaction.destroy', $row->id) .'" id="destroyTransaction'. $row->id .'" onclick="destroyTransaction('. $row->id .')"> Hapus </button>';
|
||||
// Jika status closed
|
||||
if ($row->status == 1) {
|
||||
if (Gate::allows('delete', $menu)) {
|
||||
$btn .= '<button class="btn btn-danger btn-sm font-weight-bold mr-2 mt-2"
|
||||
data-action="'. route('report.transaction.destroy', $row->id) .'"
|
||||
id="destroyTransaction'. $row->id .'"
|
||||
onclick="destroyTransaction('. $row->id .')">
|
||||
Hapus
|
||||
</button>';
|
||||
}
|
||||
$btn .= '<span class="badge badge-success">Closed</span>';
|
||||
}else{
|
||||
if(Gate::allows('delete', $menu)) {
|
||||
$btn .= '<button class="btn btn-danger btn-sm btn-bold mr-2" data-action="'. route('report.transaction.destroy', $row->id) .'" id="destroyTransaction'. $row->id .'" onclick="destroyTransaction('. $row->id .')"> Hapus </button>';
|
||||
|
||||
// Badge Closed rapi
|
||||
$btn .= '<span class="btn btn-success btn-sm font-weight-bold px-3 py-2 mr-2 mt-2 disabled"
|
||||
style="pointer-events: none; cursor: default;">
|
||||
Closed
|
||||
</span>';
|
||||
} else {
|
||||
if (Gate::allows('delete', $menu)) {
|
||||
$btn .= '<button class="btn btn-danger btn-sm font-weight-bold mr-2 mt-2"
|
||||
data-action="'. route('report.transaction.destroy', $row->id) .'"
|
||||
id="destroyTransaction'. $row->id .'"
|
||||
onclick="destroyTransaction('. $row->id .')">
|
||||
Hapus
|
||||
</button>';
|
||||
}
|
||||
|
||||
if(Gate::allows('update', $menu)) {
|
||||
$btn .= '<button class="btn btn-info btn-sm btn-bold mr-2" data-url="'. route('report.transaction.edit', $row->id) .'" data-action="'. route('report.transaction.update', $row->id) .'" onclick="editTransaction('. $row->id .')" id="editTransaction'. $row->id .'"> Edit </button>
|
||||
<button class="btn btn-warning btn-sm btn-bold" id="closeTransaction'. $row->id .'" data-url="'. route('report.transaction.close', $row->id) .'" onclick="closeTransaction('. $row->id .')"> Close </button>';
|
||||
|
||||
if (Gate::allows('update', $menu)) {
|
||||
$btn .= '<button class="btn btn-info btn-sm font-weight-bold mr-2 mt-2"
|
||||
data-url="'. route('report.transaction.edit', $row->id) .'"
|
||||
data-action="'. route('report.transaction.update', $row->id) .'"
|
||||
onclick="editTransaction('. $row->id .')"
|
||||
id="editTransaction'. $row->id .'">
|
||||
Edit
|
||||
</button>';
|
||||
|
||||
$btn .= '<button class="btn btn-warning btn-sm font-weight-bold mr-2 mt-2"
|
||||
id="closeTransaction'. $row->id .'"
|
||||
data-url="'. route('report.transaction.close', $row->id) .'"
|
||||
onclick="closeTransaction('. $row->id .')">
|
||||
Close
|
||||
</button>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($row->precheck_id) {
|
||||
$btn .= '<button class="btn btn-primary btn-sm font-weight-bold action-print mr-2 mt-2"
|
||||
data-type="precheck"
|
||||
data-id="'. $row->id .'"
|
||||
data-url="'. route('report.transaction.precheck.print', $row->id) .'">
|
||||
Pre Check
|
||||
</button>';
|
||||
}
|
||||
|
||||
if ($row->postcheck_id) {
|
||||
$btn .= '<button class="btn btn-success btn-sm font-weight-bold action-print mr-2 mt-2"
|
||||
data-type="postcheck"
|
||||
data-id="'. $row->id .'"
|
||||
data-url="'. route('report.transaction.postcheck.print', $row->id) .'">
|
||||
Post Check
|
||||
</button>';
|
||||
}
|
||||
|
||||
$btn .= '</div>';
|
||||
|
||||
return $btn;
|
||||
|
||||
@@ -15,6 +15,9 @@ use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Models\Precheck;
|
||||
use App\Models\Postcheck;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Exception;
|
||||
|
||||
class TransactionController extends Controller
|
||||
@@ -519,7 +522,6 @@ class TransactionController extends Controller
|
||||
$works_count = count($works);
|
||||
$share = $month_trxs;
|
||||
$month = $request->month;
|
||||
dd($share);
|
||||
|
||||
return view('transaction.recap', compact('month_trxs_total', 'yesterday_month_trxs_total', 'month', 'trx_data', 'sa_names', 'works', 'works_count', 'trxs', 'month_trxs','dealer', 'share', 'mechanic'));
|
||||
}
|
||||
@@ -568,7 +570,6 @@ class TransactionController extends Controller
|
||||
$prev_mth_end = $prev_mth[0].'-'.$prev_mth[1].'-'.date('t');
|
||||
}
|
||||
|
||||
// dd($prev_mth_end);
|
||||
$yesterday_month_trx = Transaction::whereNull('deleted_at')->where('work_id', $work1->id)->where('dealer_id', $id)->whereDate('date', '>=', $prev_mth_start)->whereDate('date', '<=', $prev_mth_end)->sum('qty');
|
||||
|
||||
if(array_key_exists($work1->id, $yesterday_month_trxs_total)) {
|
||||
@@ -678,15 +679,12 @@ class TransactionController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// dd($works);
|
||||
// dd([$month_trxs_total, $yesterday_month_trxs_total]);
|
||||
$final_month_trxs_total = [];
|
||||
$final_yesterday_month_trxs_total = [];
|
||||
foreach($works as $work1) {
|
||||
$final_month_trxs_total[$work1->id] = $month_trxs_total[$work1->id];
|
||||
$final_yesterday_month_trxs_total[$work1->id] = $yesterday_month_trxs_total[$work1->id];
|
||||
}
|
||||
// dd([$final_month_trxs_total, $final_yesterday_month_trxs_total]);
|
||||
$month_trxs_total = array_values($final_month_trxs_total);
|
||||
$yesterday_month_trxs_total = array_values($final_yesterday_month_trxs_total);
|
||||
|
||||
@@ -994,19 +992,31 @@ class TransactionController extends Controller
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
Transaction::find($id)->update([
|
||||
$request->validate([
|
||||
'spk' => 'required|string|max:255',
|
||||
'date' => 'required|date',
|
||||
'police_number' => 'required|string|max:255',
|
||||
'work_id' => 'required|exists:works,id',
|
||||
'qty' => 'required|integer|min:1',
|
||||
'warranty' => 'required|in:0,1',
|
||||
'user_sa_id' => 'required|exists:users,id',
|
||||
]);
|
||||
|
||||
$transaction = Transaction::findOrFail($id);
|
||||
|
||||
$transaction->update([
|
||||
"spk" => $request->spk,
|
||||
"date" => $request->date,
|
||||
"police_number" => $request->police_number,
|
||||
"work_id" => $request->work_id,
|
||||
"qty" => $request->qty,
|
||||
"warranty" => $request->warranty,
|
||||
"user_sa_id" => $request->sa_id,
|
||||
"user_sa_id" => $request->user_sa_id,
|
||||
]);
|
||||
|
||||
$response = [
|
||||
"status" => 200,
|
||||
"message" => "Data updated successfully"
|
||||
"message" => "Transaksi berhasil diperbarui"
|
||||
];
|
||||
|
||||
return response()->json($response);
|
||||
@@ -1147,6 +1157,8 @@ class TransactionController extends Controller
|
||||
'sa_name' => $transaction->sa_name,
|
||||
'status' => $this->getStatusBadge($transaction->status),
|
||||
'action' => $this->getActionButtons($transaction),
|
||||
'action_precheck' => $this->getActionButtonsPrecheck($transaction),
|
||||
'action_postcheck' => $this->getActionButtonsPostcheck($transaction),
|
||||
'claimed_at' => $transaction->claimed_at,
|
||||
'claimed_by' => $transaction->claimed_by
|
||||
];
|
||||
@@ -1259,38 +1271,108 @@ class TransactionController extends Controller
|
||||
{
|
||||
$buttons = '';
|
||||
|
||||
// Only show buttons for mechanics
|
||||
// Edit button - show for all users (not just mechanics)
|
||||
$buttons .= '<button class="btn btn-sm btn-warning mr-1"
|
||||
data-action="' . route('transaction.update', $transaction->id) . '"
|
||||
data-url="' . route('transaction.edit', $transaction->id) . '"
|
||||
onclick="editTransaction(' . $transaction->id . ')"
|
||||
id="editTransaction' . $transaction->id . '"
|
||||
title="Edit Transaksi"
|
||||
style="font-size: 11px; padding: 4px 8px;">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</button>';
|
||||
|
||||
// Delete button - show for all users
|
||||
$buttons .= '<button class="btn btn-sm btn-danger mr-1"
|
||||
onclick="deleteTransaction(' . $transaction->id . ')"
|
||||
title="Hapus Transaksi"
|
||||
style="font-size: 11px; padding: 4px 8px;">
|
||||
<i class="fas fa-trash"></i> Hapus
|
||||
</button>';
|
||||
|
||||
// Only show claim buttons for mechanics
|
||||
if (Auth::user()->role_id == 3) {
|
||||
|
||||
// Claim button - show only if not claimed yet
|
||||
if (empty($transaction->claimed_at) && empty($transaction->claimed_by)) {
|
||||
$buttons .= '<button class="btn btn-sm btn-success mr-1" onclick="claimTransaction(' . $transaction->id . ')" title="Klaim Pekerjaan">';
|
||||
$buttons .= 'Klaim';
|
||||
$buttons .= '<button class="btn btn-sm btn-success mr-1" onclick="claimTransaction(' . $transaction->id . ')" title="Klaim Pekerjaan" style="font-size: 11px; padding: 4px 8px;">';
|
||||
$buttons .= '<i class="fas fa-hand-paper"></i> Klaim';
|
||||
$buttons .= '</button>';
|
||||
} else {
|
||||
if($transaction->claimed_by == Auth::user()->id) {
|
||||
// Check if precheck exists
|
||||
$precheck = \App\Models\Precheck::where('transaction_id', $transaction->id)->first();
|
||||
if (!$precheck) {
|
||||
$buttons .= '<a href="/transaction/prechecks/' . $transaction->id . '" class="btn btn-sm btn-warning mr-1" title="Precheck">';
|
||||
$buttons .= 'Precheck';
|
||||
$buttons .= '</a>';
|
||||
} else {
|
||||
// Check if postcheck exists
|
||||
$postcheck = \App\Models\Postcheck::where('transaction_id', $transaction->id)->first();
|
||||
if (!$postcheck) {
|
||||
$buttons .= '<a href="/transaction/postchecks/' . $transaction->id . '" class="btn btn-sm btn-info mr-1" title="Postcheck">';
|
||||
$buttons .= 'Postcheck';
|
||||
$buttons .= '</a>';
|
||||
} else {
|
||||
$buttons .= '<span class="badge badge-success">Selesai</span>';
|
||||
}
|
||||
if ($transaction->claimed_by == Auth::user()->id) {
|
||||
$precheck = Precheck::where('transaction_id', $transaction->id)->first();
|
||||
$postcheck = Postcheck::where('transaction_id', $transaction->id)->first();
|
||||
|
||||
if ($precheck && $postcheck) {
|
||||
$buttons .= '<span class="badge badge-success" style="font-size: 10px;"><i class="fas fa-check"></i> Selesai</span>';
|
||||
}
|
||||
}
|
||||
$buttons .= '<span class="badge badge-info">Sudah Diklaim</span>';
|
||||
$buttons .= '<span class="badge badge-info" style="font-size: 10px;"><i class="fas fa-check-circle"></i> Sudah Diklaim</span>';
|
||||
}
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
private function getActionButtonsPrecheck($transaction)
|
||||
{
|
||||
$buttons = '';
|
||||
|
||||
if (Auth::user()->role_id == 3) {
|
||||
$precheck = Precheck::where('transaction_id', $transaction->id)->first();
|
||||
|
||||
if ($precheck) {
|
||||
$buttons .= '<a href="' . route('prechecks.edit', [$transaction->id, $precheck->id]) . '"
|
||||
class="btn btn-sm btn-warning mr-1" title="Edit Precheck" style="font-size: 11px; padding: 4px 8px;">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>';
|
||||
$buttons .= '<a href="' . route('prechecks.print', $transaction->id) . '"
|
||||
class="btn btn-sm btn-primary mr-1" title="Lihat Precheck" target="_blank" style="font-size: 11px; padding: 4px 8px;">
|
||||
<i class="fas fa-eye"></i> Lihat
|
||||
</a>';
|
||||
} else {
|
||||
if (empty($transaction->claimed_at) && empty($transaction->claimed_by)) {
|
||||
$buttons .= '<span class="badge badge-danger" style="font-size: 10px;">Transaksi Belum Diklaim</span>';
|
||||
}else{
|
||||
$buttons .= '<a href="' . route('prechecks.create', $transaction->id) . '"
|
||||
class="btn btn-sm btn-success mr-1" title="Tambah Precheck" style="font-size: 11px; padding: 4px 8px;">
|
||||
<i class="fas fa-plus"></i> Tambah
|
||||
</a>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
private function getActionButtonsPostcheck($transaction)
|
||||
{
|
||||
$buttons = '';
|
||||
|
||||
if (Auth::user()->role_id == 3) {
|
||||
$postcheck = Postcheck::where('transaction_id', $transaction->id)->first();
|
||||
$precheck = Precheck::where('transaction_id', $transaction->id)->first();
|
||||
|
||||
if($precheck){
|
||||
if ($postcheck) {
|
||||
$buttons .= '<a href="' . route('postchecks.edit', [$transaction->id, $postcheck->id]) . '"
|
||||
class="btn btn-sm btn-warning mr-1" title="Edit Postcheck" style="font-size: 11px; padding: 4px 8px;">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>';
|
||||
$buttons .= '<a href="' . route('postchecks.print', $transaction->id) . '"
|
||||
class="btn btn-sm btn-primary mr-1" title="Lihat Postcheck" target="_blank" style="font-size: 11px; padding: 4px 8px;">
|
||||
<i class="fas fa-eye"></i> Lihat
|
||||
</a>';
|
||||
} else {
|
||||
$buttons .= '<a href="' . route('postchecks.create', $transaction->id) . '"
|
||||
class="btn btn-sm btn-success mr-1" title="Tambah Postcheck" style="font-size: 11px; padding: 4px 8px;">
|
||||
<i class="fas fa-plus"></i> Tambah
|
||||
</a>';
|
||||
}
|
||||
}else{
|
||||
$buttons .= '<span class="badge badge-danger" style="font-size: 10px;">Precheck Belum Disimpan</span>';
|
||||
}
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PostchecksController extends Controller
|
||||
{
|
||||
public function index(Transaction $transaction)
|
||||
public function create(Transaction $transaction)
|
||||
{
|
||||
$acConditions = Postcheck::getAcConditionOptions();
|
||||
$blowerConditions = Postcheck::getBlowerConditionOptions();
|
||||
$evaporatorConditions = Postcheck::getEvaporatorConditionOptions();
|
||||
$compressorConditions = Postcheck::getCompressorConditionOptions();
|
||||
|
||||
return view('transaction.postchecks', compact(
|
||||
return view('transaction.postchecks.create', compact(
|
||||
'transaction',
|
||||
'acConditions',
|
||||
'blowerConditions',
|
||||
@@ -62,76 +62,15 @@ class PostchecksController extends Controller
|
||||
'compressor_condition' => $request->compressor_condition,
|
||||
'postcheck_notes' => $request->postcheck_notes,
|
||||
];
|
||||
|
||||
// Handle file uploads
|
||||
// Handle file uploads securely
|
||||
$imageFields = [
|
||||
'front_image', 'cabin_temperature_image', 'ac_image',
|
||||
'front_image', 'cabin_temperature_image', 'ac_image',
|
||||
'blower_image', 'evaporator_image'
|
||||
];
|
||||
|
||||
foreach ($imageFields as $field) {
|
||||
if ($request->hasFile($field) && $request->file($field)->isValid()) {
|
||||
try {
|
||||
$file = $request->file($field);
|
||||
|
||||
// Generate unique filename with transaction ID
|
||||
$filename = time() . '_' . uniqid() . '_' . $transaction->id . '_' . $field . '.' . $file->getClientOriginalExtension();
|
||||
|
||||
// Create directory path: transactions/{transaction_id}/postcheck/
|
||||
$directory = 'transactions/' . $transaction->id . '/postcheck';
|
||||
|
||||
// Ensure base storage directory exists
|
||||
$this->ensureStorageDirectoryExists();
|
||||
|
||||
// Ensure transactions directory exists
|
||||
if (!Storage::disk('public')->exists('transactions')) {
|
||||
Storage::disk('public')->makeDirectory('transactions', 0755, true);
|
||||
Log::info('Created transactions directory');
|
||||
}
|
||||
|
||||
// Ensure transaction ID directory exists
|
||||
$transactionDir = 'transactions/' . $transaction->id;
|
||||
if (!Storage::disk('public')->exists($transactionDir)) {
|
||||
Storage::disk('public')->makeDirectory($transactionDir, 0755, true);
|
||||
Log::info('Created transaction directory: ' . $transactionDir);
|
||||
}
|
||||
|
||||
// Ensure postcheck directory exists
|
||||
if (!Storage::disk('public')->exists($directory)) {
|
||||
Storage::disk('public')->makeDirectory($directory, 0755, true);
|
||||
Log::info('Created postcheck directory: ' . $directory);
|
||||
}
|
||||
|
||||
// Store file in organized directory structure
|
||||
$path = $file->storeAs($directory, $filename, 'public');
|
||||
|
||||
// Store file path
|
||||
$data[$field] = $path;
|
||||
|
||||
// Store metadata
|
||||
$data[$field . '_metadata'] = [
|
||||
'original_name' => $file->getClientOriginalName(),
|
||||
'size' => $file->getSize(),
|
||||
'mime_type' => $file->getMimeType(),
|
||||
'uploaded_at' => now()->toISOString(),
|
||||
'transaction_id' => $transaction->id,
|
||||
'filename' => $filename,
|
||||
];
|
||||
|
||||
Log::info('File uploaded successfully: ' . $path);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Log error for debugging
|
||||
Log::error('File upload failed: ' . $e->getMessage(), [
|
||||
'field' => $field,
|
||||
'file' => $file->getClientOriginalName(),
|
||||
'transaction_id' => $transaction->id,
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
return back()->withErrors(['error' => 'Gagal mengupload file: ' . $field . '. Error: ' . $e->getMessage()]);
|
||||
}
|
||||
$storedPath = $this->processImageUpload($request, $field, $transaction);
|
||||
if ($storedPath) {
|
||||
$data[$field] = $storedPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +83,91 @@ class PostchecksController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(Transaction $transaction, Postcheck $postcheck)
|
||||
{
|
||||
$acConditions = Postcheck::getAcConditionOptions();
|
||||
$blowerConditions = Postcheck::getBlowerConditionOptions();
|
||||
$evaporatorConditions = Postcheck::getEvaporatorConditionOptions();
|
||||
$compressorConditions = Postcheck::getCompressorConditionOptions();
|
||||
|
||||
return view('transaction.postchecks.edit', compact(
|
||||
'transaction',
|
||||
'postcheck',
|
||||
'acConditions',
|
||||
'blowerConditions',
|
||||
'evaporatorConditions',
|
||||
'compressorConditions'
|
||||
));
|
||||
}
|
||||
|
||||
public function update(Request $request, Transaction $transaction, Postcheck $postcheck)
|
||||
{
|
||||
$request->validate([
|
||||
'kilometer' => 'required|numeric|min:0',
|
||||
'pressure_high' => 'required|numeric|min:0',
|
||||
'pressure_low' => 'nullable|numeric|min:0',
|
||||
'cabin_temperature' => 'nullable|numeric',
|
||||
'cabin_temperature_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
'ac_condition' => 'nullable|in:' . implode(',', Postcheck::getAcConditionOptions()),
|
||||
'ac_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
'blower_condition' => 'nullable|in:' . implode(',', Postcheck::getBlowerConditionOptions()),
|
||||
'blower_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
'evaporator_condition' => 'nullable|in:' . implode(',', Postcheck::getEvaporatorConditionOptions()),
|
||||
'evaporator_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
'compressor_condition' => 'nullable|in:' . implode(',', Postcheck::getCompressorConditionOptions()),
|
||||
'postcheck_notes' => 'nullable|string',
|
||||
'front_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
]);
|
||||
|
||||
$updateData = [
|
||||
'kilometer' => $request->kilometer,
|
||||
'pressure_high' => $request->pressure_high,
|
||||
'pressure_low' => $request->pressure_low,
|
||||
'cabin_temperature' => $request->cabin_temperature,
|
||||
'ac_condition' => $request->ac_condition,
|
||||
'blower_condition' => $request->blower_condition,
|
||||
'evaporator_condition' => $request->evaporator_condition,
|
||||
'compressor_condition' => $request->compressor_condition,
|
||||
'postcheck_notes' => $request->postcheck_notes,
|
||||
];
|
||||
|
||||
$imageFields = [
|
||||
'front_image', 'cabin_temperature_image', 'ac_image',
|
||||
'blower_image', 'evaporator_image'
|
||||
];
|
||||
|
||||
foreach ($imageFields as $field) {
|
||||
$newPath = $this->processImageUpload($request, $field, $transaction);
|
||||
if ($newPath) {
|
||||
// delete old file if exists
|
||||
if ($postcheck->{$field}) {
|
||||
$this->deleteIfExists($postcheck->{$field});
|
||||
}
|
||||
$updateData[$field] = $newPath;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$postcheck->update($updateData);
|
||||
return redirect()->route('transaction')->with('success', 'Postcheck berhasil diperbarui');
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Postcheck update failed: ' . $e->getMessage());
|
||||
return back()->withErrors(['error' => 'Gagal memperbarui data postcheck. Silakan coba lagi.']);
|
||||
}
|
||||
}
|
||||
|
||||
public function print($transaction_id)
|
||||
{
|
||||
try {
|
||||
$postcheck = Postcheck::where('transaction_id', $transaction_id)->firstOrFail();
|
||||
|
||||
return view('transaction.postchecks.print', compact('postcheck'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error printing postcheck: ' . $e->getMessage());
|
||||
return back()->with('error', 'Gagal membuka halaman print postcheck.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the base storage directory exists
|
||||
*/
|
||||
@@ -185,4 +209,69 @@ class PostchecksController extends Controller
|
||||
rmdir($testDir);
|
||||
Log::info('Storage directory is properly configured: ' . $storagePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Securely process image upload to prevent RCE.
|
||||
* - Only allows jpeg and png
|
||||
* - Generates safe filename
|
||||
* - Validates actual image content using getimagesize
|
||||
*/
|
||||
private function processImageUpload(Request $request, string $field, Transaction $transaction): ?string
|
||||
{
|
||||
if (!($request->hasFile($field) && $request->file($field)->isValid())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$file = $request->file($field);
|
||||
|
||||
// Double-check mime type from PHP, disallow svg/gif
|
||||
$allowedMimes = ['image/jpeg' => 'jpg', 'image/png' => 'png'];
|
||||
$mime = $file->getMimeType();
|
||||
if (!array_key_exists($mime, $allowedMimes)) {
|
||||
throw new \RuntimeException('Tipe file tidak diperbolehkan');
|
||||
}
|
||||
|
||||
// Verify it's a real image by reading dimensions
|
||||
$imageInfo = @getimagesize($file->getRealPath());
|
||||
if ($imageInfo === false) {
|
||||
throw new \RuntimeException('File bukan gambar yang valid');
|
||||
}
|
||||
|
||||
// Prepare directory
|
||||
$directory = 'transactions/' . $transaction->id . '/postcheck';
|
||||
$this->ensureStorageDirectoryExists();
|
||||
if (!Storage::disk('public')->exists('transactions')) {
|
||||
Storage::disk('public')->makeDirectory('transactions', 0755, true);
|
||||
}
|
||||
if (!Storage::disk('public')->exists('transactions/' . $transaction->id)) {
|
||||
Storage::disk('public')->makeDirectory('transactions/' . $transaction->id, 0755, true);
|
||||
}
|
||||
if (!Storage::disk('public')->exists($directory)) {
|
||||
Storage::disk('public')->makeDirectory($directory, 0755, true);
|
||||
}
|
||||
|
||||
// Safe filename
|
||||
$ext = $allowedMimes[$mime];
|
||||
$filename = time() . '_' . bin2hex(random_bytes(6)) . '_' . $transaction->id . '_' . $field . '.' . $ext;
|
||||
|
||||
// Store
|
||||
$path = $file->storeAs($directory, $filename, 'public');
|
||||
Log::info('Secure image stored', ['field' => $field, 'path' => $path]);
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file from public storage if it exists
|
||||
*/
|
||||
private function deleteIfExists(string $path): void
|
||||
{
|
||||
try {
|
||||
if ($path && Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Failed to delete old image', ['path' => $path, 'error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@ use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PrechecksController extends Controller
|
||||
{
|
||||
public function index(Transaction $transaction)
|
||||
public function create(Transaction $transaction)
|
||||
{
|
||||
$acConditions = Precheck::getAcConditionOptions();
|
||||
$blowerConditions = Precheck::getBlowerConditionOptions();
|
||||
$evaporatorConditions = Precheck::getEvaporatorConditionOptions();
|
||||
$compressorConditions = Precheck::getCompressorConditionOptions();
|
||||
|
||||
return view('transaction.prechecks', compact(
|
||||
return view('transaction.prechecks.create', compact(
|
||||
'transaction',
|
||||
'acConditions',
|
||||
'blowerConditions',
|
||||
@@ -74,6 +74,11 @@ class PrechecksController extends Controller
|
||||
try {
|
||||
$file = $request->file($field);
|
||||
|
||||
// Enhanced security validation
|
||||
if (!$this->isValidImageFile($file)) {
|
||||
return back()->withErrors(['error' => 'File tidak valid atau berbahaya: ' . $field]);
|
||||
}
|
||||
|
||||
// Generate unique filename with transaction ID
|
||||
$filename = time() . '_' . uniqid() . '_' . $transaction->id . '_' . $field . '.' . $file->getClientOriginalExtension();
|
||||
|
||||
@@ -144,6 +149,158 @@ class PrechecksController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(Transaction $transaction, Precheck $precheck)
|
||||
{
|
||||
|
||||
$acConditions = Precheck::getAcConditionOptions();
|
||||
$blowerConditions = Precheck::getBlowerConditionOptions();
|
||||
$evaporatorConditions = Precheck::getEvaporatorConditionOptions();
|
||||
$compressorConditions = Precheck::getCompressorConditionOptions();
|
||||
|
||||
return view('transaction.prechecks.edit', compact(
|
||||
'transaction',
|
||||
'precheck',
|
||||
'acConditions',
|
||||
'blowerConditions',
|
||||
'evaporatorConditions',
|
||||
'compressorConditions'
|
||||
));
|
||||
}
|
||||
|
||||
public function update(Request $request, Transaction $transaction, Precheck $precheck)
|
||||
{
|
||||
|
||||
$request->validate([
|
||||
'kilometer' => 'required|numeric|min:0',
|
||||
'pressure_high' => 'required|numeric|min:0',
|
||||
'pressure_low' => 'nullable|numeric|min:0',
|
||||
'cabin_temperature' => 'nullable|numeric',
|
||||
'cabin_temperature_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
'ac_condition' => 'nullable|in:' . implode(',', Precheck::getAcConditionOptions()),
|
||||
'ac_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
'blower_condition' => 'nullable|in:' . implode(',', Precheck::getBlowerConditionOptions()),
|
||||
'blower_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
'evaporator_condition' => 'nullable|in:' . implode(',', Precheck::getEvaporatorConditionOptions()),
|
||||
'evaporator_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
'compressor_condition' => 'nullable|in:' . implode(',', Precheck::getCompressorConditionOptions()),
|
||||
'precheck_notes' => 'nullable|string',
|
||||
'front_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'kilometer' => $request->kilometer,
|
||||
'pressure_high' => $request->pressure_high,
|
||||
'pressure_low' => $request->pressure_low,
|
||||
'cabin_temperature' => $request->cabin_temperature,
|
||||
'ac_condition' => $request->ac_condition,
|
||||
'blower_condition' => $request->blower_condition,
|
||||
'evaporator_condition' => $request->evaporator_condition,
|
||||
'compressor_condition' => $request->compressor_condition,
|
||||
'precheck_notes' => $request->precheck_notes,
|
||||
];
|
||||
|
||||
// Handle file uploads with security validation
|
||||
$imageFields = [
|
||||
'front_image', 'cabin_temperature_image', 'ac_image',
|
||||
'blower_image', 'evaporator_image'
|
||||
];
|
||||
|
||||
foreach ($imageFields as $field) {
|
||||
if ($request->hasFile($field) && $request->file($field)->isValid()) {
|
||||
try {
|
||||
$file = $request->file($field);
|
||||
|
||||
// Enhanced security validation
|
||||
if (!$this->isValidImageFile($file)) {
|
||||
return back()->withErrors(['error' => 'File tidak valid atau berbahaya: ' . $field]);
|
||||
}
|
||||
|
||||
// Generate unique filename with transaction ID
|
||||
$filename = time() . '_' . uniqid() . '_' . $transaction->id . '_' . $field . '.' . $file->getClientOriginalExtension();
|
||||
|
||||
// Create directory path: transactions/{transaction_id}/precheck/
|
||||
$directory = 'transactions/' . $transaction->id . '/precheck';
|
||||
|
||||
// Ensure base storage directory exists
|
||||
$this->ensureStorageDirectoryExists();
|
||||
|
||||
// Ensure transactions directory exists
|
||||
if (!Storage::disk('public')->exists('transactions')) {
|
||||
Storage::disk('public')->makeDirectory('transactions', 0755, true);
|
||||
Log::info('Created transactions directory');
|
||||
}
|
||||
|
||||
// Ensure transaction ID directory exists
|
||||
$transactionDir = 'transactions/' . $transaction->id;
|
||||
if (!Storage::disk('public')->exists($transactionDir)) {
|
||||
Storage::disk('public')->makeDirectory($transactionDir, 0755, true);
|
||||
Log::info('Created transaction directory: ' . $transactionDir);
|
||||
}
|
||||
|
||||
// Ensure precheck directory exists
|
||||
if (!Storage::disk('public')->exists($directory)) {
|
||||
Storage::disk('public')->makeDirectory($directory, 0755, true);
|
||||
Log::info('Created precheck directory: ' . $directory);
|
||||
}
|
||||
|
||||
// Delete old file if exists
|
||||
if ($precheck->$field && Storage::disk('public')->exists($precheck->$field)) {
|
||||
Storage::disk('public')->delete($precheck->$field);
|
||||
}
|
||||
|
||||
// Store file in organized directory structure
|
||||
$path = $file->storeAs($directory, $filename, 'public');
|
||||
|
||||
// Store file path
|
||||
$data[$field] = $path;
|
||||
|
||||
// Store metadata
|
||||
$data[$field . '_metadata'] = [
|
||||
'original_name' => $file->getClientOriginalName(),
|
||||
'size' => $file->getSize(),
|
||||
'mime_type' => $file->getMimeType(),
|
||||
'uploaded_at' => now()->toISOString(),
|
||||
'transaction_id' => $transaction->id,
|
||||
'filename' => $filename,
|
||||
];
|
||||
|
||||
Log::info('File uploaded successfully: ' . $path);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Log error for debugging
|
||||
Log::error('File upload failed: ' . $e->getMessage(), [
|
||||
'field' => $field,
|
||||
'file' => $file->getClientOriginalName(),
|
||||
'transaction_id' => $transaction->id,
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
return back()->withErrors(['error' => 'Gagal mengupload file: ' . $field . '. Error: ' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$precheck->update($data);
|
||||
return redirect()->route('transaction')->with('success', 'Precheck berhasil diperbarui');
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Precheck update failed: ' . $e->getMessage());
|
||||
return back()->withErrors(['error' => 'Gagal memperbarui data precheck. Silakan coba lagi.']);
|
||||
}
|
||||
}
|
||||
|
||||
public function print($transaction_id)
|
||||
{
|
||||
try {
|
||||
$precheck = Precheck::where('transaction_id', $transaction_id)->firstOrFail();
|
||||
return view('transaction.prechecks.print', compact('precheck'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error printing precheck: ' . $e->getMessage());
|
||||
return back()->with('error', 'Gagal membuka halaman print precheck.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the base storage directory exists
|
||||
*/
|
||||
@@ -185,4 +342,138 @@ class PrechecksController extends Controller
|
||||
rmdir($testDir);
|
||||
Log::info('Storage directory is properly configured: ' . $storagePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced security validation for image files to prevent RCE attacks
|
||||
*
|
||||
* @param \Illuminate\Http\UploadedFile $file
|
||||
* @return bool
|
||||
*/
|
||||
private function isValidImageFile($file)
|
||||
{
|
||||
try {
|
||||
// 1. Check file extension (whitelist approach)
|
||||
$allowedExtensions = ['jpg', 'jpeg', 'png'];
|
||||
$extension = strtolower($file->getClientOriginalExtension());
|
||||
|
||||
if (!in_array($extension, $allowedExtensions)) {
|
||||
Log::warning('Invalid file extension: ' . $extension, [
|
||||
'filename' => $file->getClientOriginalName(),
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Check MIME type
|
||||
$allowedMimeTypes = [
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/png'
|
||||
];
|
||||
|
||||
$mimeType = $file->getMimeType();
|
||||
if (!in_array($mimeType, $allowedMimeTypes)) {
|
||||
Log::warning('Invalid MIME type: ' . $mimeType, [
|
||||
'filename' => $file->getClientOriginalName(),
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. Verify file is actually an image using getimagesize
|
||||
$imageInfo = @getimagesize($file->getPathname());
|
||||
if ($imageInfo === false) {
|
||||
Log::warning('File is not a valid image: ' . $file->getClientOriginalName(), [
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 4. Check image dimensions (prevent extremely large images)
|
||||
$maxWidth = 5000;
|
||||
$maxHeight = 5000;
|
||||
if ($imageInfo[0] > $maxWidth || $imageInfo[1] > $maxHeight) {
|
||||
Log::warning('Image dimensions too large: ' . $imageInfo[0] . 'x' . $imageInfo[1], [
|
||||
'filename' => $file->getClientOriginalName(),
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 5. Check file size (max 20MB)
|
||||
$maxSize = 20 * 1024 * 1024; // 20MB
|
||||
if ($file->getSize() > $maxSize) {
|
||||
Log::warning('File size too large: ' . $file->getSize(), [
|
||||
'filename' => $file->getClientOriginalName(),
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 6. Check for suspicious content in filename
|
||||
$filename = $file->getClientOriginalName();
|
||||
$suspiciousPatterns = [
|
||||
'<?php', '<?=', '<script', 'javascript:', 'data:', 'vbscript:',
|
||||
'..', '~', '$', '`', '|', '&', ';', '(', ')', '{', '}',
|
||||
'exec', 'system', 'shell_exec', 'passthru', 'eval'
|
||||
];
|
||||
|
||||
foreach ($suspiciousPatterns as $pattern) {
|
||||
if (stripos($filename, $pattern) !== false) {
|
||||
Log::warning('Suspicious filename pattern detected: ' . $pattern, [
|
||||
'filename' => $filename,
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Additional security: Check file header (magic bytes)
|
||||
$handle = fopen($file->getPathname(), 'rb');
|
||||
if ($handle) {
|
||||
$header = fread($handle, 8);
|
||||
fclose($handle);
|
||||
|
||||
// Check for valid image headers
|
||||
$validHeaders = [
|
||||
"\xFF\xD8\xFF", // JPEG
|
||||
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", // PNG
|
||||
];
|
||||
|
||||
$isValidHeader = false;
|
||||
foreach ($validHeaders as $validHeader) {
|
||||
if (substr($header, 0, strlen($validHeader)) === $validHeader) {
|
||||
$isValidHeader = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isValidHeader) {
|
||||
Log::warning('Invalid file header detected', [
|
||||
'filename' => $filename,
|
||||
'user_id' => auth()->id(),
|
||||
'header' => bin2hex($header)
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Log::info('File validation passed', [
|
||||
'filename' => $filename,
|
||||
'size' => $file->getSize(),
|
||||
'mime_type' => $mimeType,
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
|
||||
return true;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('File validation error: ' . $e->getMessage(), [
|
||||
'filename' => $file->getClientOriginalName(),
|
||||
'user_id' => auth()->id(),
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ class adminRole
|
||||
{
|
||||
// check if user can access admin area
|
||||
$user = Privilege::join('menus AS m', 'm.id', '=', 'privileges.menu_id')->where('m.link', 'adminarea')->where('role_id', Auth::user()->role_id)->where('view', 1)->get();
|
||||
// dd($user);
|
||||
if (!$user) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class Postcheck extends Model
|
||||
*/
|
||||
public function getFrontImageUrlAttribute()
|
||||
{
|
||||
return $this->front_image ? Storage::disk('public')->url($this->front_image) : null;
|
||||
return $this->front_image ? asset('storage/' . ltrim($this->front_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ class Postcheck extends Model
|
||||
*/
|
||||
public function getCabinTemperatureImageUrlAttribute()
|
||||
{
|
||||
return $this->cabin_temperature_image ? Storage::disk('public')->url($this->cabin_temperature_image) : null;
|
||||
return $this->cabin_temperature_image ? asset('storage/' . ltrim($this->cabin_temperature_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +91,7 @@ class Postcheck extends Model
|
||||
*/
|
||||
public function getAcImageUrlAttribute()
|
||||
{
|
||||
return $this->ac_image ? Storage::disk('public')->url($this->ac_image) : null;
|
||||
return $this->ac_image ? asset('storage/' . ltrim($this->ac_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +99,7 @@ class Postcheck extends Model
|
||||
*/
|
||||
public function getBlowerImageUrlAttribute()
|
||||
{
|
||||
return $this->blower_image ? Storage::disk('public')->url($this->blower_image) : null;
|
||||
return $this->blower_image ? asset('storage/' . ltrim($this->blower_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +107,7 @@ class Postcheck extends Model
|
||||
*/
|
||||
public function getEvaporatorImageUrlAttribute()
|
||||
{
|
||||
return $this->evaporator_image ? Storage::disk('public')->url($this->evaporator_image) : null;
|
||||
return $this->evaporator_image ? asset('storage/' . ltrim($this->evaporator_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,7 +75,7 @@ class Precheck extends Model
|
||||
*/
|
||||
public function getFrontImageUrlAttribute()
|
||||
{
|
||||
return $this->front_image ? Storage::disk('public')->url($this->front_image) : null;
|
||||
return $this->front_image ? asset('storage/' . ltrim($this->front_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ class Precheck extends Model
|
||||
*/
|
||||
public function getCabinTemperatureImageUrlAttribute()
|
||||
{
|
||||
return $this->cabin_temperature_image ? Storage::disk('public')->url($this->cabin_temperature_image) : null;
|
||||
return $this->cabin_temperature_image ? asset('storage/' . ltrim($this->cabin_temperature_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +91,7 @@ class Precheck extends Model
|
||||
*/
|
||||
public function getAcImageUrlAttribute()
|
||||
{
|
||||
return $this->ac_image ? Storage::disk('public')->url($this->ac_image) : null;
|
||||
return $this->ac_image ? asset('storage/' . ltrim($this->ac_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +99,7 @@ class Precheck extends Model
|
||||
*/
|
||||
public function getBlowerImageUrlAttribute()
|
||||
{
|
||||
return $this->blower_image ? Storage::disk('public')->url($this->blower_image) : null;
|
||||
return $this->blower_image ? asset('storage/' . ltrim($this->blower_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +107,7 @@ class Precheck extends Model
|
||||
*/
|
||||
public function getEvaporatorImageUrlAttribute()
|
||||
{
|
||||
return $this->evaporator_image ? Storage::disk('public')->url($this->evaporator_image) : null;
|
||||
return $this->evaporator_image ? asset('storage/' . ltrim($this->evaporator_image, '/')) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user