pipicar/app/Http/Controllers/MobileApiController.php

468 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers;
use A7kz\Platform\Models\UniModel;
use A7kz\Platform\Modules\Platform\Acl\Facades\Acl;
use A7kz\Platform\Modules\Platform\Segment\Facades\Segment;
use App\Modules\applications\Enum\ApplicationStatus;
use App\Modules\auto\Enums\AutoStatusEnums;
use App\Service\DepositService;
use Carbon\CarbonPeriod;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Storage;
use Mpdf\Tag\Mark;
use function PHPUnit\Framework\isEmpty;
class MobileApiController extends Controller
{
public function getMarks(): JsonResponse {
$data = [];
$marks = UniModel::model('pipi_brand_models')->get();
if (!isset($marks)) {
return response()->json();
}
foreach ($marks as $mark) {
$brand = UniModel::model('pipi_auto_brands')->find($mark->brand_id);
$tariffs = UniModel::model('pipi_auto_tariffs')->where('model_id', $mark->id)->get();
$equipment = UniModel::model('pipi_auto_equipment')->where('id', $mark->equipment_id)->first();
if ($mark->name != 'Ввод остатков') {
foreach ($tariffs as $tariff) {
$tariffs_new[] = [
'name' => $tariff?->name,
'price' => $tariff?->base_rate,
'min' => $tariff?->day_range_start,
'max' => $tariff?->day_range_end,
];
}
$data[$mark->name . '-' . $mark->year] = [
'id' => $mark->id,
'brand' => $brand->name,
'mark' => $mark->name,
'year' => $mark->year,
'configuration' => $equipment?->name,
'tariffs' => $tariffs_new
];
}
}
if (empty($data)) {
$data = (object) [];
}
return response()->json($data);
}
/**
* @throws Exception
*/
public function sendApplication(Request $request): JsonResponse {
$data = $request->all();
$data['started_at'] = Carbon::createFromFormat('d-m-Y H:i', $data['started_at']);
$data['ended_at'] = Carbon::createFromFormat('d-m-Y H:i', $data['ended_at']);
$authToken = null;
$data['car_id'] = null;
if ($request->header('Authorization')) {
$user = auth()->guard('api')->user();
$data['user_id'] = $user?->id;
$authToken = $request->header('Authorization');
} else {
$user = UniModel::model('core_users')
->where('email', $data['email'])
->first();
if ($user) {
$data['user_id'] = $user->id;
$tokenResult = $user->createToken('auth_token');
$authToken = $tokenResult->accessToken;
} else {
$data['user_id'] = null;
}
}
$response = [
'status' => 'OK',
'message' => 'Заявка создана',
];
$car = $this->getAvailableCar($data['started_at'], $data['ended_at'], $data['mark_id'], $data['color_code']);
if (!isset($car)) {
return response()->json('Нет свободных машин');
}
$data['car_id'] = $car->id;
if ($data['user_id']) {
$period = CarbonPeriod::create($data['started_at'], $data['ended_at']);
$dates = array_map(fn($date) => $date->toDateString(), iterator_to_array($period));
foreach ($dates as $date) {
UniModel::model('pipi_auto_calendar')->create([
'auto_id' => $data['car_id'],
'date' => $date,
'status' => AutoStatusEnums::Rent->name
]);
}
$response['auth_token'] = $authToken;
$response['message'] = 'Заявка создана, и вы были автоматически авторизованы';
} elseif (!isset($data['user_id'])) {
$response['message'] = 'Заявка создана, с вами свяжется наш оператор';
}
$address_end = UniModel::model('pipi_address')->where('name', $data['address_end'])->first();
$address_start = UniModel::model('pipi_address')->where('name', $data['address_start'])->first();
dd($address_start, $address_end);
$service = new DepositService;
$sums = $service->calculateSummary($data['mark_id'], $data['started_at'], $data['ended_at']);
$sum = $sums['discounted_sum'];
if ($data['deposit'] != $sums['deposit_base']) {
$sum += $data['deposit'];
}
UniModel::model('pipi_applications')->create([
'rent_day' => $data['rent_day'],
'started_at' => $data['started_at'],
'ended_at' => $data['ended_at'],
'user_id' => $data['user_id'],
'phone' => $data['phone'] ?? '' ,
'car_id' => $data['car_id'],
'user_name' => $data['name'] ?? null,
'user_surname' => $data['surname'] ?? null,
'user_email' => $data['email'] ?? null,
'address_end' => $address_end->id,
'address_start' => $address_start->id,
'deposit' => $data['deposit'] ?? null,
'status' => ApplicationStatus::pending->value,
'sum' => $sum
]);
return response()->json($response);
}
public function getApplications(): JsonResponse
{
$request = request();
if ($request->header('Authorization')) {
$user = auth()->guard('api')->user();
} else {
return response()->json([
'status' => false,
'message' => __('Вы не авторизованы')
]);
}
$status = $request->query('status');
$data = [];
$query = UniModel::model('pipi_applications')->where('user_id', $user->id);
if (isset($status)) {
$query->where('status', $status);
}
$applications = $query->get();
foreach ($applications as $app) {
$car = UniModel::model('pipi_auto')->find($app->car_id);
$model = UniModel::model('pipi_brand_models')->find($car->model_id);
$photo = UniModel::model('core_files')->find($model->photo_id);
$photo = url('api/files/file/' . ltrim($photo?->path, '/'));
$class_id = UniModel::model('pipi_auto_classes')->where('id', $model->class_id)->first();
$bodywork_id = UniModel::model('pipi_auto_bodywork')->where('id', $model->bodywork_id)->first();
$address = UniModel::model('pipi_address')->where('id', $model->address)->first();
$data[] = [
'id' => $app->id,
'rent_day' => $app->rent_day,
'started_at' => $app->started_at,
'ended_at' => $app->ended_at,
'status' => ApplicationStatus::from($app->status)->getName(),
'sum' => $app->sum ?? 0,
'address_end' => $address->name ?? '',
'car' => [
'name' => $model->name,
'year' => $model->year,
'people' => $model?->people ?? '5',
'actuator' => $model?->actuator ?? 'Передний',
'fuel_type' => $model?->fuel_type ?? 'АКПП',
'hp' => $model?->hp ?? '1.6',
'engine_capacity' => $model?->engine_capacity ?? '1591',
'fuel_tank' => $model?->fuel_tank ?? '50',
'class' => $class_id->name ?? 'Эконом',
'bodywork' => $bodywork_id->name ?? 'Седан',
'photo' => $photo ?? '',
]
];
}
if (empty($data)) {
$data = (object) $data;
}
return response()->json($data);
}
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (auth()->attempt($credentials)) {
$user = auth()->user();
$tokenResult = $user->createToken('auth_token');
$response = [
'access_token' => $tokenResult->plainTextToken,
'token_type' => 'Bearer',
'user' => [
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
],
];
return response()->json($response, 200);
} else {
return response()->json(['error' => 'Unauthorized'], 401);
}
}
public function checkAvailableCar($started_at = null, $ended_at = null, $modelId = null): bool {
if (!$started_at || !$ended_at || !$modelId) {
$request = request();
$started_at = $started_at ?? $request->input('started_at');
$ended_at = $ended_at ?? $request->input('ended_at');
$modelId = $modelId ?? $request->input('model_id');
}
if (!$started_at || !$ended_at || !$modelId) {
return false;
}
$started_at = Carbon::parse($started_at)->format('Y-m-d');
$ended_at = Carbon::parse($ended_at)->format('Y-m-d');
$cars = UniModel::model('pipi_auto')
->where('is_inactive', '=', false)
->where('model_id', $modelId)
->get();
$busyCars = UniModel::model('pipi_auto_calendar')
->whereBetween('date', [$started_at, $ended_at])
->pluck('auto_id')
->toArray();
$availableCars = $cars->reject(fn($car) => in_array($car->id, $busyCars));
return $availableCars->isNotEmpty();
}
public function getAvailableMarksList(Request $request): JsonResponse
{
$started_at = $request->query('started_at');
$ended_at = $request->query('ended_at');
$class = $request->query('class');
$bodywork = $request->query('bodywork');
$marks = UniModel::model('pipi_brand_models')->get();
$availableMarks = [];
if ($class) {
$class_id = UniModel::model('pipi_auto_classes')->where('name', $class)->first()?->id;
$marks = $marks->where('class_id', $class_id);
}
if ($bodywork) {
$bodywork_id = UniModel::model('pipi_auto_bodywork')->where('name', $bodywork)->first()?->id;
$marks = $marks->where('bodywork_id', $bodywork_id);
}
foreach ($marks as $mark) {
if ($mark->name === 'Ввод остатков') {
continue;
}
if (!$this->checkAvailableCar($started_at, $ended_at, $mark->id)) {
continue;
}
$cars = UniModel::model('pipi_auto')->where('model_id', $mark->id)->get();
if ($cars->isEmpty()) {
continue;
}
$brand = UniModel::model('pipi_auto_brands')->find($mark->brand_id);
$tariffs = UniModel::model('pipi_auto_tariffs')->where('model_id', $mark->id)->get();
$equipment = UniModel::model('pipi_auto_equipment')->where('id', $mark->equipment_id)->first();
$class = UniModel::model('pipi_auto_classes')->find($mark->class_id);
$bodywork = UniModel::model('pipi_auto_bodywork')->find($mark->bodywork_id);
$photo = UniModel::model('core_files')->find($mark?->photo_id);
$path = null;
if ($photo) {
$path = url('api/files/file/' . ltrim($photo->path, '/'));
}
$tariffs_new = [];
foreach ($tariffs as $tariff) {
$tariffs_new[] = [
'name' => $tariff?->name,
'price' => $tariff?->base_rate,
'min' => $tariff?->day_range_start,
'max' => $tariff?->day_range_end,
'deposit' => $tariff?->deposit,
];
}
$carsByColor = $cars->groupBy('color_id');
foreach ($carsByColor as $carColor => $carsOfColor) {
$carColor = UniModel::model('pipi_auto_colors')->find($carColor)->code;
$colorPath = $path;
if ($carsOfColor->first()->photo_id) {
$photo = UniModel::model('core_files')->find($carsOfColor->first()->photo_id);
$colorPath = url('api/files/file/' . ltrim($photo->path, '/'));
}
$key = $mark->name . '-' . $mark->year . '-' . $carColor;
$availableMarks[$key] = [
'id' => $mark->id,
'brand' => $brand?->name,
'mark' => $mark->name,
'year' => $mark->year,
'color' => $carColor,
'configuration' => $equipment?->name,
'people' => $mark?->people ?? '5',
'actuator' => $mark?->actuator ?? 'Передний',
'fuel_type' => $mark?->fuel_type ?? 'АКПП',
'hp' => $mark?->hp ?? '1.6',
'engine_capacity' => $mark?->engine_capacity ?? '1591',
'fuel_tank' => $mark?->fuel_tank ?? '50',
'class' => $class->name ?? 'Эконом',
'bodywork' => $bodywork->name ?? 'Седан',
'deposit' => $tariffs_new[0]['deposit'] ?? 30000,
'conditioner' => $mark?->conditioner,
'photo' => $colorPath,
'tariffs' => $tariffs_new,
];
}
}
if (empty($availableMarks)) {
$availableMarks = (object) [];
}
return response()->json($availableMarks);
}
public function getAvailableCar($started_at, $ended_at, $modelId, $color)
{
$started_at = Carbon::parse($started_at)->format('Y-m-d');
$ended_at = Carbon::parse($ended_at)->format('Y-m-d');
$color = UniModel::model('pipi_auto_colors')->where('code', $color)->first()->id;
$cars = UniModel::model('pipi_auto')
->where('color_id', $color)
->where('model_id', $modelId)
->get();
$busyCars = UniModel::model('pipi_auto_calendar')
->whereBetween('date', [$started_at, $ended_at])
->pluck('auto_id')
->toArray();
$availableCars = $cars->reject(fn($car) => in_array($car->id, $busyCars));
if ($availableCars->isNotEmpty()) {
return $availableCars->first();
} else {
return null;
}
}
public function getSum(Request $request)
{
$started_at = $request->input('started_at');
$ended_at = $request->input('ended_at');
$mark_id = $request->input('mark_id');
$start = Carbon::createFromFormat('d-m-Y H:i', $started_at);
$end = Carbon::createFromFormat('d-m-Y H:i', $ended_at);
try {
$service = new DepositService();
$summary = $service->calculateSummary($mark_id, $start, $end);
return response()->json($summary);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 400);
}
}
public function closeOrder(Request $request): JsonResponse
{
$order_id = $request->input('order_id');
$application = UniModel::model('pipi_applications')->find($order_id);
if (!isset($application)) {
return response()->json([
'success' => false,
'message' => __('Такой заявки не существует')
]);
}
if (count($request->file('photos')) != 5) {
return response()->json([
'success' => false,
'message' => __('Неверное количество фотографий')
]);
}
foreach ($request->file('photos') as $photo) {
$files[] = $this->uploadFile($photo);
}
$application->photos = $files;
$application->save();
return response()->json([
'success' => true,
'message' => __('Фото получены ожидайте закрытия заявки после проверки оператором'),
]);
}
private function uploadFile($file)
{
$ufile = UniModel::model(config('platform.file_manager.tables.files'));
$ufile->filename = $file->getClientOriginalName();
$ufile->path = $this->_gen_storage_file_name($file->getClientOriginalExtension());
$ufile->ext = $file->getClientOriginalExtension();
$ufile->size = $file->getSize();
$ufile->mime = $file->getClientMimeType();
$ufile->public = 1;
$ufile->user_file = 1;
$ufile->company_file = 1;
Storage::disk('file')->put($ufile->path, file_get_contents($file->getRealPath()));
$ufile->save();
return ['status' => 1, 'file_id' => $ufile->id, 'name' => 'photos', 'file_name' => $ufile->filename];
}
private function _gen_storage_file_name($ext): string
{
$storage_file_name = md5(time());
$folder1 = substr($storage_file_name, 0, 2);
$folder2 = substr($storage_file_name, 2, 3);
return $folder1 . '/' . $folder2 . '/' . $storage_file_name . '.' . $ext;
}
public function getAddress(): JsonResponse
{
$addresses = UniModel::model('pipi_address')->get();
foreach ($addresses as $address) {
$data[$address->id] = $address->name;
}
if (empty($data)) {
$data = (object) [];
}
return response()->json($data);
}
}