276 lines
8.7 KiB
PHP
276 lines
8.7 KiB
PHP
<?php
|
|
|
|
namespace Modules\Portal\Services;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Modules\Maintenance\Models\Equipment;
|
|
use Modules\Maintenance\Models\FieldMission;
|
|
use Modules\Maintenance\Models\PreventiveSchedule;
|
|
use Modules\Maintenance\Models\ProductionLine;
|
|
use Modules\Maintenance\Models\WorkOrder;
|
|
use Modules\Project\Entities\Project;
|
|
|
|
class CustomerMaintenanceScopeService
|
|
{
|
|
public function __construct(
|
|
protected int $businessId,
|
|
protected int $contactId
|
|
) {
|
|
}
|
|
|
|
public static function make(int $businessId, int $contactId): self
|
|
{
|
|
return new self($businessId, $contactId);
|
|
}
|
|
|
|
public static function forCurrentUser(): self
|
|
{
|
|
return new self(
|
|
(int) request()->session()->get('user.business_id'),
|
|
(int) auth()->user()->crm_contact_id
|
|
);
|
|
}
|
|
|
|
public function maintenanceEnabled(): bool
|
|
{
|
|
return Schema::hasTable('maintenance_equipment');
|
|
}
|
|
|
|
public function preventiveSchedulesAvailable(): bool
|
|
{
|
|
return Schema::hasTable('maintenance_preventive_schedules');
|
|
}
|
|
|
|
public function workOrdersAvailable(): bool
|
|
{
|
|
return Schema::hasTable('maintenance_work_orders');
|
|
}
|
|
|
|
public function fieldMissionsAvailable(): bool
|
|
{
|
|
return Schema::hasTable('maintenance_field_missions');
|
|
}
|
|
|
|
public function failureReportsAvailable(): bool
|
|
{
|
|
return Schema::hasTable('maintenance_failure_reports');
|
|
}
|
|
|
|
public function productionLinesAvailable(): bool
|
|
{
|
|
return Schema::hasTable('maintenance_production_lines');
|
|
}
|
|
|
|
public function projectIds(): Collection
|
|
{
|
|
if (! Schema::hasTable('pjt_projects')) {
|
|
return collect();
|
|
}
|
|
|
|
return Project::where('business_id', $this->businessId)
|
|
->where('contact_id', $this->contactId)
|
|
->pluck('id');
|
|
}
|
|
|
|
public function equipmentIds(): Collection
|
|
{
|
|
if (! $this->maintenanceEnabled()) {
|
|
return collect();
|
|
}
|
|
|
|
return Equipment::where('business_id', $this->businessId)
|
|
->where('customer_id', $this->contactId)
|
|
->pluck('id');
|
|
}
|
|
|
|
public function productionLineIds(): Collection
|
|
{
|
|
if (! $this->productionLinesAvailable()) {
|
|
return collect();
|
|
}
|
|
|
|
$projectIds = $this->projectIds();
|
|
|
|
if ($projectIds->isEmpty()) {
|
|
return collect();
|
|
}
|
|
|
|
return ProductionLine::where('business_id', $this->businessId)
|
|
->whereIn('project_id', $projectIds)
|
|
->pluck('id');
|
|
}
|
|
|
|
public function equipmentQuery(): Builder
|
|
{
|
|
return Equipment::where('business_id', $this->businessId)
|
|
->where('customer_id', $this->contactId);
|
|
}
|
|
|
|
public function projectQuery(): Builder
|
|
{
|
|
return Project::where('business_id', $this->businessId)
|
|
->where('contact_id', $this->contactId);
|
|
}
|
|
|
|
public function productionLineQuery(): Builder
|
|
{
|
|
if (! $this->productionLinesAvailable()) {
|
|
return ProductionLine::query()->whereRaw('0 = 1');
|
|
}
|
|
|
|
return ProductionLine::where('business_id', $this->businessId)
|
|
->whereIn('project_id', $this->projectIds());
|
|
}
|
|
|
|
public function preventiveScheduleQuery(): Builder
|
|
{
|
|
if (! $this->preventiveSchedulesAvailable()) {
|
|
return PreventiveSchedule::query()->whereRaw('0 = 1');
|
|
}
|
|
$equipmentIds = $this->equipmentIds();
|
|
$projectIds = $this->projectIds();
|
|
$lineIds = $this->productionLineIds();
|
|
|
|
$query = PreventiveSchedule::where('business_id', $this->businessId);
|
|
|
|
return $query->where(function ($q) use ($equipmentIds, $projectIds, $lineIds) {
|
|
$added = false;
|
|
if ($equipmentIds->isNotEmpty()) {
|
|
$q->whereIn('equipment_id', $equipmentIds);
|
|
$added = true;
|
|
}
|
|
if ($projectIds->isNotEmpty()) {
|
|
$added ? $q->orWhereIn('project_id', $projectIds) : $q->whereIn('project_id', $projectIds);
|
|
$added = true;
|
|
}
|
|
if ($lineIds->isNotEmpty()) {
|
|
$added ? $q->orWhereIn('production_line_id', $lineIds) : $q->whereIn('production_line_id', $lineIds);
|
|
$added = true;
|
|
}
|
|
if (! $added) {
|
|
$q->whereRaw('0 = 1');
|
|
}
|
|
});
|
|
}
|
|
|
|
public function workOrderQuery(): Builder
|
|
{
|
|
if (! $this->workOrdersAvailable()) {
|
|
return WorkOrder::query()->whereRaw('0 = 1');
|
|
}
|
|
$equipmentIds = $this->equipmentIds();
|
|
$projectIds = $this->projectIds();
|
|
$lineIds = $this->productionLineIds();
|
|
|
|
return WorkOrder::where('business_id', $this->businessId)
|
|
->where(function ($q) use ($equipmentIds, $projectIds, $lineIds) {
|
|
$added = false;
|
|
if ($equipmentIds->isNotEmpty()) {
|
|
$q->whereIn('equipment_id', $equipmentIds);
|
|
$added = true;
|
|
}
|
|
if ($projectIds->isNotEmpty()) {
|
|
$added ? $q->orWhereIn('project_id', $projectIds) : $q->whereIn('project_id', $projectIds);
|
|
$added = true;
|
|
}
|
|
if ($lineIds->isNotEmpty()) {
|
|
$added ? $q->orWhereIn('production_line_id', $lineIds) : $q->whereIn('production_line_id', $lineIds);
|
|
$added = true;
|
|
}
|
|
if (! $added) {
|
|
$q->whereRaw('0 = 1');
|
|
}
|
|
});
|
|
}
|
|
|
|
public function fieldMissionQuery(): Builder
|
|
{
|
|
if (! $this->fieldMissionsAvailable()) {
|
|
return FieldMission::query()->whereRaw('0 = 1');
|
|
}
|
|
$equipmentIds = $this->equipmentIds();
|
|
$projectIds = $this->projectIds();
|
|
|
|
return FieldMission::where('business_id', $this->businessId)
|
|
->where(function ($q) use ($equipmentIds, $projectIds) {
|
|
$added = false;
|
|
if ($equipmentIds->isNotEmpty()) {
|
|
$q->whereIn('equipment_id', $equipmentIds);
|
|
$added = true;
|
|
}
|
|
if ($projectIds->isNotEmpty()) {
|
|
$method = $added ? 'orWhere' : 'where';
|
|
$q->{$method}(function ($sq) use ($projectIds) {
|
|
$sq->where('source_type', 'project')
|
|
->whereIn('source_id', $projectIds);
|
|
});
|
|
}
|
|
if (! $added && $projectIds->isEmpty()) {
|
|
$q->whereRaw('0 = 1');
|
|
}
|
|
});
|
|
}
|
|
|
|
public function ownsEquipment(int $equipmentId): bool
|
|
{
|
|
return $this->equipmentIds()->contains($equipmentId);
|
|
}
|
|
|
|
public function ownsProject(int $projectId): bool
|
|
{
|
|
return $this->projectIds()->contains($projectId);
|
|
}
|
|
|
|
public function ownsProductionLine(int $lineId): bool
|
|
{
|
|
return $this->productionLineIds()->contains($lineId);
|
|
}
|
|
|
|
public function ownsPreventiveSchedule(int $scheduleId): bool
|
|
{
|
|
return $this->preventiveScheduleQuery()->where('id', $scheduleId)->exists();
|
|
}
|
|
|
|
public function ownsWorkOrder(int $workOrderId): bool
|
|
{
|
|
return $this->workOrderQuery()->where('id', $workOrderId)->exists();
|
|
}
|
|
|
|
public function ownsFieldMission(int $missionId): bool
|
|
{
|
|
return $this->fieldMissionQuery()->where('id', $missionId)->exists();
|
|
}
|
|
|
|
public function dashboardStats(): array
|
|
{
|
|
if (! $this->maintenanceEnabled()) {
|
|
return [];
|
|
}
|
|
|
|
$openStatuses = ['open', 'pending', 'in_progress', 'assigned', 'scheduled'];
|
|
|
|
return [
|
|
'projects' => $this->projectIds()->count(),
|
|
'equipment' => $this->equipmentIds()->count(),
|
|
'production_lines' => $this->productionLineIds()->count(),
|
|
'open_work_orders' => $this->workOrdersAvailable()
|
|
? $this->workOrderQuery()->whereIn('status', $openStatuses)->count()
|
|
: 0,
|
|
'upcoming_services' => $this->preventiveSchedulesAvailable()
|
|
? $this->preventiveScheduleQuery()
|
|
->where('is_active', true)
|
|
->whereNotNull('next_due_at')
|
|
->where('next_due_at', '<=', now()->addDays(30))
|
|
->count()
|
|
: 0,
|
|
'active_missions' => $this->fieldMissionsAvailable()
|
|
? $this->fieldMissionQuery()
|
|
->whereIn('status', ['planned', 'in_progress', 'scheduled'])
|
|
->count()
|
|
: 0,
|
|
];
|
|
}
|
|
}
|