authorize('customers.manage'); $this->customer = Customer::query()->where('uuid', $uuid)->firstOrFail(); } /** * Start an answer to one request: subject prefilled, the request remembered. */ public function answer(string $uuid): void { $this->authorize('customers.manage'); $request = $this->customer->supportRequests()->where('uuid', $uuid)->first(); if ($request === null) { return; } $this->answering = $request->uuid; $this->subject = __('customer_message.re', ['subject' => $request->subject]); $this->body = ''; } public function cancelAnswer(): void { $this->answering = null; $this->subject = ''; $this->body = ''; } /** * Send it, record it, and close the request it answers. * * The register row is written here rather than left to the MessageSent * listener, because this is the one mail whose BODY is worth keeping: an * operator typed it, and "what exactly did I write to them in March" is a * question the mail server's log cannot answer either. */ public function send(): void { $this->authorize('customers.manage'); $data = $this->validate(); Mail::to($this->customer->email)->send( new OperatorMessageMail($this->customer, $data['subject'], $data['body']) ); // The listener has already written a row for the delivery — it fires on // every mail this application sends. This adds what only the console // knows: that a person wrote it, and what they wrote. SentMail::query() ->where('customer_id', $this->customer->id) ->where('to', $this->customer->email) ->latest('id') ->limit(1) ->update(['from_operator' => true, 'body' => $data['body']]); if ($this->answering !== null) { $this->customer->supportRequests() ->where('uuid', $this->answering) ->update(['status' => 'answered', 'answered_at' => now()]); } $this->cancelAnswer(); $this->dispatch('notify', message: __('customer_message.sent')); } public function render() { $this->authorize('customers.manage'); return view('livewire.admin.customer-detail', [ 'requests' => $this->customer->supportRequests() ->with('instance') ->latest('id') ->get(), // The whole conversation as it left here, newest first. Capped: // this is a page, not an export, and a customer of three years has // a few hundred rows nobody scrolls. 'mails' => SentMail::query() ->where('customer_id', $this->customer->id) ->latest('sent_at') ->limit(50) ->get(), 'instance' => $this->customer->instances()->latest('id')->first(), 'subscription' => $this->customer->subscriptions()->latest('id')->first(), ]); } }