Deploy Ladill POS / deploy (push) Successful in 31s
Send real receipt emails from the customer display and sale page, store branch promo content for the idle screen, and fold selected tips into totals.
73 lines
1.9 KiB
PHP
73 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Pos;
|
|
|
|
use App\Mail\DigitalReceiptMail;
|
|
use App\Models\PosSale;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use RuntimeException;
|
|
|
|
class ReceiptEmailService
|
|
{
|
|
/**
|
|
* Email a digital receipt for a sale. Updates customer_email when empty.
|
|
*
|
|
* @return array{ok: bool, message: string}
|
|
*/
|
|
public function send(PosSale $sale, string $email): array
|
|
{
|
|
$email = strtolower(trim($email));
|
|
if ($email === '' || ! filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
throw new RuntimeException('A valid email address is required.');
|
|
}
|
|
|
|
$sale->loadMissing(['lines', 'location']);
|
|
|
|
if (! $sale->customer_email) {
|
|
$sale->forceFill(['customer_email' => $email])->save();
|
|
}
|
|
|
|
try {
|
|
Mail::to($email)->send(new DigitalReceiptMail($sale));
|
|
} catch (\Throwable $e) {
|
|
Log::warning('pos.receipt_email_failed', [
|
|
'sale_id' => $sale->id,
|
|
'email' => $email,
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
|
|
throw new RuntimeException('Could not send the receipt email. Please try again.');
|
|
}
|
|
|
|
return [
|
|
'ok' => true,
|
|
'message' => 'Receipt sent to '.$email,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Best-effort send after a paid sale when an email is already on the sale.
|
|
*/
|
|
public function sendIfPresent(PosSale $sale): bool
|
|
{
|
|
$email = trim((string) ($sale->customer_email ?? ''));
|
|
if ($email === '') {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
$this->send($sale, $email);
|
|
|
|
return true;
|
|
} catch (\Throwable $e) {
|
|
Log::info('pos.receipt_email_skipped', [
|
|
'sale_id' => $sale->id,
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|