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;
}
}