fix:change tour sections
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\TourStoreRequest;
|
||||
use App\Http\Requests\Admin\TourUpdateRequest;
|
||||
use App\Models\ActivityLog;
|
||||
use App\Models\File;
|
||||
use App\Models\Tour;
|
||||
use App\Models\TourDate;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class TourController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$tours = Tour::query()
|
||||
->with([
|
||||
'file',
|
||||
'tourDates',
|
||||
])
|
||||
|
||||
|
||||
->when($request->filled('search'), function (Builder $query) use ($request) {
|
||||
|
||||
$search = $request->input('search');
|
||||
|
||||
$query->where(function (Builder $query) use ($search) {
|
||||
|
||||
$query->where('title', 'LIKE', "%{$search}%")
|
||||
->orWhere('summary', 'LIKE', "%{$search}%")
|
||||
->orWhere('origin', 'LIKE', "%{$search}%")
|
||||
->orWhere('destination', 'LIKE', "%{$search}%");
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
// فیلتر وضعیت
|
||||
->when($request->filled('status'), function (Builder $query) use ($request) {
|
||||
|
||||
$query->where(
|
||||
'status',
|
||||
$request->input('status')
|
||||
);
|
||||
|
||||
})
|
||||
|
||||
->orderByDesc('created_at')
|
||||
->paginate(15)
|
||||
->withQueryString();
|
||||
|
||||
return view('admin.tours.index', compact('tours'));
|
||||
}
|
||||
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('admin.tours.create');
|
||||
}
|
||||
|
||||
public function store(TourStoreRequest $request)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
|
||||
// ذخیره تصویر
|
||||
$image = $request->file('image');
|
||||
|
||||
$path = $image->store('tours', 'public');
|
||||
|
||||
$file = File::create([
|
||||
'name' => pathinfo(
|
||||
$image->hashName(),
|
||||
PATHINFO_FILENAME
|
||||
),
|
||||
'extension' => $image->getClientOriginalExtension(),
|
||||
'size' => $image->getSize(),
|
||||
'original_name' => $image->getClientOriginalName(),
|
||||
'path' => $path,
|
||||
]);
|
||||
|
||||
|
||||
// ایجاد تور
|
||||
$tour = Tour::create([
|
||||
'title' => $request->title,
|
||||
'summary' => $request->input('summary') ?? '',
|
||||
'descriptions' => $request->input('descriptions') ?? '',
|
||||
'file_id' => $file->id,
|
||||
'origin' => $request->origin,
|
||||
'destination' => $request->destination,
|
||||
'duration' => $request->duration,
|
||||
'price' => $request->price,
|
||||
'views' => 0,
|
||||
'status' => $request->status,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
|
||||
// ایجاد تاریخ تور
|
||||
TourDate::create([
|
||||
'tour_id' => $tour->id,
|
||||
'start_date' => $request->start_date,
|
||||
'end_date' => $request->end_date,
|
||||
'price' => $request->tour_date_price,
|
||||
'capacity' => $request->capacity,
|
||||
'status' => $request->tour_date_status,
|
||||
]);
|
||||
|
||||
|
||||
DB::commit();
|
||||
|
||||
} catch (\Exception $exception) {
|
||||
|
||||
DB::rollBack();
|
||||
|
||||
Log::error($exception);
|
||||
|
||||
return back()
|
||||
->withErrors([
|
||||
'general' => 'خطایی در ایجاد تور رخ داده است.'
|
||||
])
|
||||
->withInput();
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->route('admin.tours.index')
|
||||
->with('success', 'تور با موفقیت ایجاد شد.');
|
||||
}
|
||||
|
||||
public function edit(Tour $tour)
|
||||
{
|
||||
$tour->load([
|
||||
'file',
|
||||
'tourDates',
|
||||
]);
|
||||
|
||||
$createdLog = ActivityLog::query()
|
||||
->where('model_type', Tour::class)
|
||||
->where('model_id', $tour->id)
|
||||
->where('action', 'created')
|
||||
->with('admin')
|
||||
->first();
|
||||
|
||||
$lastUpdatedLog = ActivityLog::query()
|
||||
->where('model_type', Tour::class)
|
||||
->where('model_id', $tour->id)
|
||||
->where('action', 'updated')
|
||||
->with('admin')
|
||||
->latest('created_at')
|
||||
->first();
|
||||
|
||||
return view('admin.tours.edit', compact(
|
||||
'tour',
|
||||
'createdLog',
|
||||
'lastUpdatedLog'
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
public function update(TourUpdateRequest $request, Tour $tour)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
|
||||
// فایل قبلی
|
||||
$fileId = $tour->file_id;
|
||||
|
||||
|
||||
// اگر عکس جدید انتخاب شده باشد
|
||||
if ($request->hasFile('image')) {
|
||||
|
||||
$image = $request->file('image');
|
||||
|
||||
$path = $image->store('tours', 'public');
|
||||
|
||||
$file = File::create([
|
||||
'name' => pathinfo(
|
||||
$image->hashName(),
|
||||
PATHINFO_FILENAME
|
||||
),
|
||||
'extension' => $image->getClientOriginalExtension(),
|
||||
'size' => $image->getSize(),
|
||||
'original_name' => $image->getClientOriginalName(),
|
||||
'path' => $path,
|
||||
]);
|
||||
|
||||
$fileId = $file->id;
|
||||
}
|
||||
|
||||
|
||||
// ویرایش اطلاعات تور
|
||||
$tour->update([
|
||||
'title' => $request->title,
|
||||
'summary' => $request->input('summary') ?? '',
|
||||
'descriptions' => $request->input('descriptions') ?? '',
|
||||
'file_id' => $fileId,
|
||||
'origin' => $request->origin,
|
||||
'destination' => $request->destination,
|
||||
'duration' => $request->duration,
|
||||
'price' => $request->price,
|
||||
'status' => $request->status,
|
||||
]);
|
||||
|
||||
|
||||
// تاریخ تور
|
||||
$tourDate = $tour->tourDates()->first();
|
||||
|
||||
|
||||
if ($tourDate) {
|
||||
|
||||
$tourDate->update([
|
||||
'start_date' => $request->start_date,
|
||||
'end_date' => $request->end_date,
|
||||
'price' => $request->tour_date_price,
|
||||
'capacity' => $request->capacity,
|
||||
'status' => $request->tour_date_status,
|
||||
]);
|
||||
|
||||
} else {
|
||||
|
||||
// اگر تور تاریخ نداشت، یک تاریخ جدید ایجاد شود
|
||||
$tour->tourDates()->create([
|
||||
'start_date' => $request->start_date,
|
||||
'end_date' => $request->end_date,
|
||||
'price' => $request->tour_date_price,
|
||||
'capacity' => $request->capacity,
|
||||
'status' => $request->tour_date_status,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
DB::commit();
|
||||
|
||||
} catch (\Exception $exception) {
|
||||
|
||||
DB::rollBack();
|
||||
|
||||
Log::error($exception);
|
||||
|
||||
return back()
|
||||
->withErrors([
|
||||
'general' => 'خطایی در ویرایش تور رخ داده است.'
|
||||
])
|
||||
->withInput();
|
||||
}
|
||||
|
||||
|
||||
return redirect()
|
||||
->route('admin.tours.index')
|
||||
->with('success', 'تور با موفقیت ویرایش شد.');
|
||||
}
|
||||
|
||||
public function destroy(Tour $tour)
|
||||
{
|
||||
if ($tour->tourDates()->whereHas('bookings')->exists()) {
|
||||
|
||||
return back()->withErrors([
|
||||
'error' => 'این تور دارای رزرو است و قابل حذف نیست.'
|
||||
]);
|
||||
}
|
||||
|
||||
$tour->tourDates()->delete();
|
||||
|
||||
$tour->delete();
|
||||
|
||||
return redirect()
|
||||
->route('admin.tours.index')
|
||||
->with('success', 'تور با موفقیت حذف شد.');
|
||||
}
|
||||
|
||||
public function logs(Tour $tour)
|
||||
{
|
||||
$logs = ActivityLog::query()
|
||||
->where('model_type', Tour::class)
|
||||
->where('model_id', $tour->id)
|
||||
->with('admin')
|
||||
->orderByDesc('created_at')
|
||||
->paginate(20);
|
||||
|
||||
return view('admin.tours.logs', compact('tour', 'logs'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Enums\TourDateStatus;
|
||||
use App\Enums\TourStatus;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class TourStoreRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
|
||||
'title' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
],
|
||||
|
||||
'summary' => [
|
||||
'required',
|
||||
'string',
|
||||
],
|
||||
|
||||
'descriptions' => [
|
||||
'required',
|
||||
'string',
|
||||
],
|
||||
|
||||
'origin' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
],
|
||||
|
||||
'destination' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
],
|
||||
|
||||
'duration' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
],
|
||||
|
||||
'price' => [
|
||||
'required',
|
||||
'numeric',
|
||||
'min:0',
|
||||
],
|
||||
|
||||
'status' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::in([
|
||||
TourStatus::DISABLE->value,
|
||||
TourStatus::ENABLE->value,
|
||||
]),
|
||||
],
|
||||
|
||||
'image' => [
|
||||
'required',
|
||||
'image',
|
||||
'mimes:jpg,jpeg,png,webp',
|
||||
'max:2048',
|
||||
],
|
||||
|
||||
'start_date' => [
|
||||
'required',
|
||||
'date',
|
||||
'after_or_equal:today',
|
||||
],
|
||||
|
||||
'end_date' => [
|
||||
'required',
|
||||
'date',
|
||||
'after_or_equal:start_date',
|
||||
],
|
||||
|
||||
'tour_date_price' => [
|
||||
'required',
|
||||
'numeric',
|
||||
'min:0',
|
||||
],
|
||||
|
||||
'capacity' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
],
|
||||
|
||||
'tour_date_status' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::in([
|
||||
TourDateStatus::DISABLE->value,
|
||||
TourDateStatus::ENABLE->value,
|
||||
]),
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Enums\TourDateStatus;
|
||||
use App\Enums\TourStatus;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class TourUpdateRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'title' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
],
|
||||
|
||||
'summary' => [
|
||||
'nullable',
|
||||
'string',
|
||||
],
|
||||
|
||||
'descriptions' => [
|
||||
'nullable',
|
||||
'string',
|
||||
],
|
||||
|
||||
'origin' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
],
|
||||
|
||||
'destination' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
],
|
||||
|
||||
'duration' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
],
|
||||
|
||||
'price' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:0',
|
||||
],
|
||||
|
||||
'image' => [
|
||||
'nullable',
|
||||
'image',
|
||||
'mimes:jpg,jpeg,png,webp',
|
||||
'max:2048',
|
||||
],
|
||||
|
||||
'status' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::in([
|
||||
TourStatus::DISABLE->value,
|
||||
TourStatus::ENABLE->value,
|
||||
]),
|
||||
],
|
||||
|
||||
'start_date' => [
|
||||
'required',
|
||||
'date',
|
||||
'after_or_equal:today',
|
||||
],
|
||||
|
||||
'end_date' => [
|
||||
'required',
|
||||
'date',
|
||||
'after_or_equal:start_date',
|
||||
],
|
||||
|
||||
'tour_date_price' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:0',
|
||||
],
|
||||
|
||||
'capacity' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
],
|
||||
|
||||
'tour_date_status' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::in([
|
||||
TourDateStatus::DISABLE->value,
|
||||
TourDateStatus::ENABLE->value,
|
||||
]),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user