'bool', 'type' => TicketTypeEnum::class, 'status' => TicketStatusEnum::class, 'last_activity' => 'timestamp', ]; /** * Perform any actions required after the model boots. * * @return void */ protected static function booted() { static::creating(function (Ticket $ticket) { // If bug force the ticket status on new. All the others are estimateTodo. if ($ticket->type->equals(TicketTypeEnum::bug)) { $ticket->status = TicketStatusEnum::new; } else { $ticket->status = TicketStatusEnum::estimateTodo; } }); static::updating(function (Ticket $ticket) { if (!$ticket->original['status'] !== $ticket->status->value) { event(new TicketStatusChanged( $ticket, TicketStatusEnum::make($ticket->original['status']), auth()->user(), null, false )); event(new NotifySubscriptions($ticket, sprintf( '%s a modifié le statut en %s', auth()->user()->name, $ticket->status->label() ))); event(new NotifyAdmin($ticket, sprintf( '%s a modifié le statut en %s', auth()->user()->name, $ticket->status->label() ))); } }); } // * RELATIONSHIPS /** * HasOne Credit\Estimation relation * * @return \Illuminate\Database\Eloquent\Relations\HasOne */ public function estimation() { return $this->hasOne(Estimation::class); } /** * BelongsTo Site relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function site() { return $this->belongsTo(Site::class); } /** * BelongsTo User relation * The user that created the ticket * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() { return $this->belongsTo(User::class, 'created_by'); } /** * BelongsTo User relation * The user that is in charge of the ticket * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function assignedUser() { return $this->belongsTo(User::class, 'assigned_to'); } /** * HasMany Message relation * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function messages() { return $this->hasMany(Message::class, 'ticket_id'); } /** * BelongsToMany User relation * The Users that are following this ticket * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function subscriptions() { return $this->belongsToMany(User::class, 'subscriptions'); } /** * BelongsToMany Label relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function labels() { return $this->belongsToMany(Label::class, 'label_ticket'); } /** * BelongsTo ticket_type * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function ticketType() { return $this->belongsTo(TicketType::class, 'type', 'type'); } // * METHODS /** * Parse message @user tags and send emails to concerned users * returns and array with to users notified * * @param Message $message * @return Collection */ public function sendBeenMentionnedToUser(Message $message): Collection { $ticket = $this; // Find @user + send mail si un seul user est trouvé. /** @var \Illuminate\Support\Collection<\App\Models\User> */ $usersNotified = collect([]); $matches = []; $ticket->load('site'); \preg_match_all('/@\w*/', $message->message, $matches); $matches = collect($matches[0] ?? [])->unique(); foreach ($matches as $pseudo_usertag) { try { /** @var \App\Models\User $user */ $user = User::where('name', 'LIKE', '%' . ltrim($pseudo_usertag, '@') . '%') ->where('email', '!=', $ticket->user->email) ->where(function ($q) use ($ticket) { $q->whereHas('sites', function ($q) use ($ticket) { $q->where('id', $ticket->site->id); }) ->orWhere('role', RoleEnum::admin) ->orWhere('role', RoleEnum::developper); })->firstOrFail(); if ($ticket->is_internal) { if ($user->isAdmin()) { $usersNotified->add($user); SendTicketMentionMail::dispatchAfterResponse( $user, new TicketMention($ticket, $message->message) ); } } else { $usersNotified->add($user); SendTicketMentionMail::dispatchAfterResponse( $user, new TicketMention($ticket, $message->message) ); } } catch (ModelNotFoundException $e) { continue; } //end try } //end foreach return $usersNotified; } /** * full_name getter * * @return string */ public function getFullNameAttribute(): string { return trans('Ticket n° :ticketId : :ticketSiteName', [ 'ticketId' => $this->id, 'ticketSiteName' => $this->site->name ]); } /** * Check if an account has the same brand as this ticket. * * @param Account $account * @return boolean */ public function accountIsValidForThisTicket(Account $account): bool { /** @var \App\Models\Brand|null */ if (!($siteBrand = optional($this->site)->brand)) { return false; } /** @var \App\Models\Brand */ $accountBrand = $account->brand; return !\is_null($accountBrand->id) and $accountBrand->id === $siteBrand->id; } /** * Format the ticket name to contain more information. * * @param self $ticket * @return string */ public static function formatName(self $ticket): string { return sprintf( 'Ticket %d (%s): %s', $ticket->id, $ticket->user ? $ticket->user->name : trans('Utilisateur supprimé'), Str::limit(\preg_replace('/[[:cntrl:]]+/', '', $ticket->text), 35), ); } }