File: /var/www/ipsremont-demo/app/Http/Controllers/RepairController.php
<?php
namespace App\Http\Controllers;
use App\Helpers\UserHelper;
use App\Http\Requests\Category\UploadRequest;
use App\Http\Requests\IdRequest;
use App\Http\Requests\Order\AddToCartRequest;
use App\Http\Requests\Repair\CreateRequest;
use App\Http\Requests\Repair\IndexRequest;
use App\Http\Requests\Repair\RepairRequest;
use App\Http\Requests\Repair\UpdateRequest;
use App\Models\Device;
use App\Models\ErrorCodes;
use App\Models\Order;
use App\Models\Permission;
use App\Models\Repair\Repair;
use App\Models\RepairAttachment;
use App\Models\RepairItems;
use App\Repository\Repair\RepairRepository;
use App\Services\Branch\BranchService;
use App\Services\Errors\ErrorsService;
use App\Services\Order\OrderService;
use App\Services\Repair\RepairService;
use App\Services\RepairItems\RepairItemsService;
use App\Services\Service\ServiceService;
use App\Services\Status\StatusService;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
class RepairController extends Controller
{
/** @var string */
protected string $permission = Permission::repairs;
protected string $protectedRedirect = 'repairs.index';
/** @var RepairService */
protected RepairService $service;
/**
* RepairController constructor.
*/
public function __construct()
{
parent::__construct();
$this->service = new RepairService();
}
public function index(IndexRequest $request)
{
$user = UserHelper::getUser();
$data = $this->service->search($request);
$columns = Repair::columns();
$canBranchesAll = can(Permission::branchesAll);
$branches = BranchService::getDisplayed();
if ($user->isService()) {
$services = [];
if ($request->service_id) {
$selectedService = ServiceService::getById($request->service_id);
$services[$request->service_id] = $selectedService->name;
}
} else {
$services = ServiceService::getAvailable()->get()->pluck('name', 'id')->toArray();
}
$statuses = StatusService::getRepairAll();
$devices = [];
if (isset($request->device_id)) {
/** @var Device $device */
$device = Device::query()->where('id', $request->device_id)->first();
$devices[$device->id] = $device->getNumber() . ', ' . $device->getName() . ' ' . $device->getManufacturer();
}
if ($user->isService()) {
$canActions = canServiceActions($user->getCurrentServiceId());
} elseif ($request->service_id) {
$canActions = canServiceActions($request->service_id);
} else {
$canActions = true;
}
return view('repairs.list', compact('canBranchesAll', 'user', 'data', 'columns', 'branches', 'services', 'statuses', 'devices', 'canActions'))
->with(['sections' => ['service_id', 'branch_id', 'status', 'device_id'], 'activeMenu' => 'index']);
}
/** Show the form for creating a new resource */
public function create(IdRequest $request)
{
$order = null;
if ($request->id) {
$order = OrderService::getById($request->id);
if (!empty($order->repair_id)) {
return redirect()->route('repairs.show', $order->repair_id)->with(['messageError' => __('repairs.messageOrderHasRepair')]);
}
if (Order::STATUS_CANCELED == $order->status) {
return redirect(route('orders.index'))->with(['messageError' => __('orders.messageStatusCanceledRepairError')]);
}
if ($redirect = $this->isRedirected($order->service_id)) {
return $redirect;
}
}
$model = new Repair();
$model->order_id = $order->id ?? 0;
$validate = new CreateRequest();
return view('repairs.create', compact('model', 'validate', 'order'))->with(['sections' => ['device_id'], 'activeMenu' => 'index']);
}
public function store(CreateRequest $request)
{
if ($request->order_id) {
$order = OrderService::getById($request->order_id);
if ($order->repair_id) {
return redirect()->route('repairs.show', $order->repair_id)->with(['messageError' => __('repairs.messageOrderHasRepair')]);
}
if ($order->status == 'canceled') {
return redirect(route('orders.index'))->with(['messageError' => __('orders.messageStatusCanceledRepairError')]);
}
if ($redirect = $this->isRedirected($order->service_id)) {
return $redirect;
}
}
$repair = $this->service->save($request);
if (!empty($request->get('fileId'))) {
RepairAttachment::query()->whereIn('id', $request->get('fileId'))->update(['repair_id' => $repair->id]);
}
if (!$repair) {
return redirect()->route('repairs.index');
}
return redirect()->route('repairs.show', $repair->id)->with(['messageSuccess' => __('repairs.messageCreate')]);
}
public function edit($id)
{
/** @var Repair $model */
$model = RepairService::getAvailableByStatus($id);
if ($redirect = $this->isRedirected($model->service_id)) {
return $redirect;
}
$statuses = StatusService::getRepairForForm();
$validate = new UpdateRequest();
$device = $model->device;
$devices = [];
if (isset($device)) {
$devices[$device->id] = $device->getNumber() . ', ' . $device->getName() . ' ' . $device->getManufacturer();
} else {
$devices[] = $model->device_sku . ', ' . $model->device_name;
}
$categories = Repair::getCategories();
$price = $model->service->getPrice()->get();
$error_categories = ErrorsService::getCategories();
$errorExternalGroup = substr($model->error_code, 0, 3);
$selectedCategoryId = ErrorCodes::query()->where('external_group_id', $errorExternalGroup)->where('external_id', 0)->value('id');
$error_codes = [];
if (isset($selectedCategoryId)) {
$codes = ErrorsService::getCodes($selectedCategoryId);
foreach ($codes as $code) {
$error_codes[$code['id']] = $code['text'];
}
}
/** @var Collection|RepairItems[] $parts */
$parts = RepairItemsService::getByRepairId($model->id);
$total = 0;
foreach ($parts as $part) {
$total += $part->amount * $part->price;
}
$columns = Repair::cart_columns('create');
$data = compact('model', 'validate', 'statuses', 'devices', 'categories', 'price', 'error_categories', 'error_codes', 'parts', 'columns', 'total', 'selectedCategoryId');
return view('repairs.edit', $data)->with(['sections' => ['status', 'device_id', 'category_id', 'error_category', 'error_code'], 'activeMenu' => 'index']);
}
public function update(UpdateRequest $request)
{
$model = RepairService::getAvailableByStatus($request->id);
if ($redirect = $this->isRedirected($model->service_id)) {
return $redirect;
}
$this->service->update($request);
return redirect()->route('repairs.index')->with(['messageSuccess' => __('repairs.messageUpdate')]);
}
public function show($id)
{
$model = RepairService::getById($id);
$user = UserHelper::getUser();
$twins = RepairService::getTwins($model);
$parts = RepairItemsService::getByRepairId($id);
$total = 0;
foreach ($parts as $part) {
$total += $part->amount * $part->price;
}
$columns = Repair::cart_columns();
$validate = new UpdateRequest();
if ($user->isService()) {
$canActions = canServiceActions($user->getCurrentServiceId());
} elseif ($model->service_id) {
$canActions = canServiceActions($model->service_id);
} else {
$canActions = true;
}
return view('repairs.show', compact('model', 'user', 'twins', 'parts', 'columns', 'total', 'validate', 'canActions'))->with(['activeMenu' => 'index']);
}
public function reporting()
{
$user = UserHelper::getUser();
if (empty($user) || !$user->isService()) {
return redirect()->route('repairs.index');
}
$dates = RepairService::getDatesForReport();
$warning = empty($dates);
$documents = RepairRepository::getReportsDocuments();
return view('repairs.reporting', compact('dates', 'warning', 'documents'));
}
/**
* Генерация «Гарантийной отчётности»
*
* @param RepairRequest $request
*
* @return \Illuminate\Http\RedirectResponse|\Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public function formReport(RepairRequest $request)
{
$startDate = $request->date_start;
$endDate = $request->date_end;
if (empty($startDate) || empty($endDate)) {
return redirect()->route('repairs.reporting');
}
$repairs = RepairService::getRepairsForReport($startDate, $endDate);
$filteredRepairs = [];
// Фильтруем Наряды которые не должны попасть в выгрузку
foreach ($repairs as $key => $repair) {
$orders = $repair->orders;
$hasOrders = !$orders->isEmpty();
$orders = $orders->filter(fn($order) => Order::REPAIR_WARRANTY === $order->repair)->all();
if ($hasOrders && empty($orders)) {
continue;
}
$filteredRepairs[] = $repair;
}
/** @var Repair[] $repairs */
$repairs = $filteredRepairs;
if (empty($repairs)) {
return redirect()->route('repairs.reporting');
}
$file = RepairService::createReport($repairs);
foreach ($repairs as $repair) {
$repair->status = Repair::STATUS_REPORT;
$repair->save();
}
return response()->download($file);
}
public function removeCustomPart(AddToCartRequest $request)
{
RepairItemsService::delete($request->part_id);
}
public function uploadFile(UploadRequest $request, $id = 0): JsonResponse
{
$file = $request->file('file');
$result = $file->storeAs(RepairAttachment::PATH, $file->hashName());
$repairAttachment = new RepairAttachment();
$repairAttachment->repair_id = empty($id) ? null : $id;
$repairAttachment->path = $result;
$repairAttachment->original_name = $file->getClientOriginalName();
$repairAttachment->save();
return response()->json(['success' => $repairAttachment->id]);
}
public function download(int $id)
{
/** @var RepairAttachment $attachment */
$attachment = RepairAttachment::query()->find($id);
if (empty($attachment)) {
return redirect()->route('home');
}
$filePath = storage_path($attachment->path);
if (!file_exists($filePath)) {
return redirect()->route('home');
}
return Response::download($filePath, $attachment->original_name);
}
public function deleteAttachment(int $id, Request $request)
{
/** @var RepairAttachment $attachment */
$attachment = RepairAttachment::query()->find($id);
if (empty($attachment)) {
return redirect()->route('home');
}
$filePath = storage_path($attachment->path);
$actTcId = $attachment->repair_id;
if (file_exists($filePath)) {
$attachment->delete();
}
$backUrl = $request->get('backUrl');
if (empty($backUrl)) {
return redirect()->route('home');
}
return redirect()->route($backUrl, $actTcId);
}
}