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