CluPilotCloud/app/Mail/OrderConfirmationMail.php

79 lines
2.6 KiB
PHP

<?php
namespace App\Mail;
use App\Mail\Concerns\SendsFromMailbox;
use App\Models\Order;
use App\Services\Mail\MailPurpose;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
/**
* "We have your order, and here is what happens next."
*
* Sent when the payment lands, not when the machine is ready — those are
* minutes apart at best and can be much longer, and a customer who has just
* been charged and heard nothing assumes the worst about both.
*
* From the BILLING mailbox: it is a record of a payment, and a reply to it is
* a question about money rather than about a server.
*
* Deliberately says nothing about when the cloud will be ready. Provisioning
* takes as long as it takes, CloudReady announces the end of it, and a
* promised time that slips is worse than no promise at all.
*/
class OrderConfirmationMail extends Mailable implements ShouldQueue
{
use Queueable, SendsFromMailbox, SerializesModels;
public function __construct(public Order $order, public string $name) {}
public function envelope(): Envelope
{
return $this->mailboxEnvelope(
MailPurpose::BILLING,
__('orders.mail_subject', ['number' => $this->order->uuid ?? $this->order->id]),
);
}
public function content(): Content
{
return new Content(view: 'mail.order-confirmation', with: [
'name' => $this->name,
'order' => $this->order,
// Through the model, so the cart, the invoice list and this mail
// cannot each invent their own wording for the same row.
'label' => $this->order->label(),
'amount' => $this->amount(),
'location' => $this->location(),
'invoicesUrl' => route('invoices'),
]);
}
/** The charge, formatted where the currency is known rather than in a view. */
private function amount(): string
{
return number_format($this->order->amount_cents / 100, 2, ',', '.')
.' '.strtoupper((string) $this->order->currency);
}
private function location(): string
{
$datacenter = \App\Models\Datacenter::query()
->where('code', $this->order->datacenter)
->first();
if ($datacenter === null) {
return (string) $this->order->datacenter;
}
return $datacenter->facility
? $datacenter->name.' · '.$datacenter->facility
: $datacenter->name;
}
}