HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/ipsremont-demo/app/Repository/Repair/RepairRepository.php
<?php

namespace App\Repository\Repair;

use App\Helpers\UserHelper;
use App\Http\Requests\Repair\CustomParts;
use App\Http\Requests\Repair\IndexRequest;
use App\Models\ManagerService;
use App\Models\Repair\Repair;
use App\Models\RepairPrice;
use App\Models\Service\Service;
use App\Repository\BaseRepository;
use App\Repository\Device\DeviceRepository;
use App\Services\Order\OrderService;
use App\Services\RepairItems\RepairItemsService;
use App\Traits\GridTrait;
use App\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;

class RepairRepository extends BaseRepository
{

    use GridTrait;

    /**
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function getQuery()
    {
        return Repair::query();
    }

    /**
     * Return items, available for me
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function getDisplayed()
    {
        return static::getAvailable();
    }

    /**
     * @param IndexRequest $request
     *
     * @return mixed
     */
    public function search(IndexRequest $request)
    {
        $query = self::getAvailable();

        $this->makeQueryOrdered(Repair::class, $query, $request);

        if (isset($request->branch_id) && !empty($request->branch_id)) {
            $query->where('branch_id', $request->branch_id);
        }
        if (isset($request->service_id) && !empty($request->service_id)) {
            $query->where('service_id', $request->service_id);
        }
        if (isset($request->status) && !empty($request->status)) {
            $query->where('status', $request->status);
        }
        if (isset($request->id) && !empty($request->id)) {
            $query->where('id', $request->id);
        }
        if (isset($request->order_id) && !empty($request->order_id)) {
            $query->whereHas('orders', function ($query) use ($request) {
                $query->where('id', $request->order_id);
            });
        }
        if (isset($request->device_id) && !empty($request->device_id)) {
            $query->where('device_id', $request->device_id);
        }

        if (isset($request->serial_number) && !empty($request->serial_number)) {
            $query->where('serial_number', 'like', '%' . $request->serial_number . '%');
        }
        if (isset($request->client) && !empty($request->client)) {
            $query->where(function ($query) use ($request) {
                $query
                    ->orWhere('name', 'like', '%' . $request->client . '%')
                    ->orWhere('email', 'like', '%' . $request->client . '%')
                    ->orWhere('phone', 'like', '%' . $request->client . '%');
            });
        }

        if (isset($request->date_start) && !empty($request->date_start)) {
            $query->where('repair_date', '>=', $request->date_start);
            $query->where('repair_date', '<=', $request->date_end);
        }

        $perPage = $request->per_page ?? config('crud.defaultPerPage');
        $data = $query->paginate((int) $perPage)->appends($request->all());

        return $data;
    }

    /**
     * @param $id
     */
    public static function delete($id)
    {
        self::getById($id)->delete();
    }

    /**
     * @param $id
     */
    public static function save($fields)
    {
        $repair = new Repair();
        $repair->fill($fields);

        if ($fields['order_id']) {
            $order = OrderService::getById($fields['order_id']);
            if (!canServiceActions($order->service_id)) {
                return false;
            }
        } else {
            $order = null;
        }

        $repair->user_id = Auth::user()->id;
        $repair->service_id = $order ? $order->service_id : Auth::user()->service_id;
        $repair->branch_id = $order ? $order->branch_id : Auth::user()->getFirstBranchId();
        $repair->status = '';
        $repair->created_by_manager = Auth::user()->isManager();

        $repair->use_catalog_component = $fields['use_catalog_component'] ?? 1;
        if ($repair->use_catalog_component) {
            if (!empty($fields['device_id'])) {
                $device = DeviceRepository::getById($fields['device_id']);
                $repair->device_external_id = $device->external_id;
            }
            $repair->device_sku = '';
            $repair->device_name = '';
        } else {
            $repair->device_external_id = 0;
            $repair->device_sku = $fields['custom_component_sku'];
            $repair->device_name = $fields['custom_component_name'];
        }

        $repair->save();

        if ($order) {
            $order->refresh();
            $order->repair_id = $repair->id;
            $order->update();
        }

        $repair->status = 'new';
        $repair->update();

        return $repair;
    }

    /**
     * @param Repair $repair
     * @param array $fields
     */
    public static function update($repair, $fields)
    {
        $changeDevice = (($repair->device_id ?? null) <> $fields['device_id']);
        $repair->fill($fields);

        if ($changeDevice) {
            if ($repair->device_id) {
                $device = DeviceRepository::getById($repair->device_id);
                $repair->device_external_id = $device->external_id;
            } else {
                $repair->device_external_id = 0;
            }
        }

        if (isset($fields['parts'])) {
            foreach ($fields['parts'] as $part) {
                if (strripos($part['price'], ',')) {
                    $price = explode(',', $part['price']);
                    $part['price'] = (double) $price[0] . '.' . $price[1];
                }
                RepairItemsService::save($part);
            }
        }

        $repair->update();
    }

    public static function getAvailableByStatus()
    {
        $user = UserHelper::getUser();
        $statuses = $user->isService() ? Repair::getEditableStatuses() : Repair::getManagerEditableStatuses();

        return self::getAvailable()->whereIn('status', $statuses);
    }

    public static function closeFromAct($id, $status, $category, $date, $description)
    {
        $model = self::getById($id);
        if ($model->status != Repair::STATUS_CANCELED && $model->status != Repair::STATUS_COMPLETED && $model->status != Repair::STATUS_REPORT) {
            $model->status = $status;
            $model->category_id = $category;
            $model->closed_at = $date;
            $model->work_description = $description;
            $model->update();
        }
    }

    public static function getPrice($serviceId, $repairCategory, $deviceExternalId): int
    {
        $price = RepairPrice::where('device_external_id', $deviceExternalId)->where('service_id', $serviceId)->first();

        if (empty($price)) {
            return 0;
        }

        switch ($repairCategory) {
            case 1:
                return $price->repair_category_1;
            case 2:
                return $price->repair_category_2;
            case 3:
                return $price->repair_category_3;
            default:
                return 0;
        }
    }

    public static function getDatesForReport(): Builder
    {
        return self::getAvailable()->where('status', 'completed')->whereNotNull('close_date')->groupBy('close_date');
    }

    public static function getRepairsForReport(string $startDate, string $endDate)
    {
        return self::getAvailable()->where('status', Repair::STATUS_COMPLETED)->whereBetween('closed_at', [$startDate, $endDate]);
    }

    public static function getRepairsForExport(bool $withErrors = false, array $branchIds = []): Builder
    {
        $exportStatuses = [Repair::EXPORT_STATUS_NEW];
        if ($withErrors) {
            $exportStatuses[] = Repair::EXPORT_STATUS_ERROR;
        }

        $repairs = self::getAvailable()->where('status', Repair::STATUS_REPORT)->whereIn('export_status', $exportStatuses);
        if (!empty($branchIds)) {
            $repairs->whereIn('branch_id', $branchIds);
        }

        return $repairs;
    }

    public static function getReportsDocuments(?User $user = null): array
    {
        $user ??= UserHelper::getUser();
        $userServiceIds = ManagerService::query()->where('user_id', $user->id)->pluck('service_id')->toArray();
        $files = Storage::disk('reports')->files();
        $documents = [];
        $servicesIds = [];
        foreach ($files as $file) {
            if (!preg_match('/^report_(\d+)_(\d{4}-\d{2}-\d{2})_(\d{4}-\d{2}-\d{2}).xls$/', $file, $matches)) {
                continue;
            }
            $serviceId = $matches[1];
            if ($user->isManager() && !in_array($serviceId, $userServiceIds)) {
                continue;
            }
            if ($user->isService() && $user->getService()->id != $serviceId) {
                continue;
            }

            $servicesIds[] = $serviceId;
            $documents[] = [
                'name' => $file,
                'serviceId' => $serviceId,
                'startDate' => date('d.m.Y', strtotime($matches[2])),
                'endDate' => date('d.m.Y', strtotime($matches[3])),
                'sortDate' => strtotime($matches[2]),
            ];
        }
        $services = Service::query()->whereIn('id', $servicesIds)->get()->keyBy('id');

        $documents = array_filter($documents, fn($document) => !empty($services[$document['serviceId']]));
        foreach ($documents as &$document) {
            $document['service'] = $services[$document['serviceId']]->name;
        }

        uasort($documents, fn($a, $b) => $b['sortDate'] <=> $a['sortDate']);

        return $documents;
    }

}