Skip to content

Commit f73459a

Browse files
n8barclaude
andauthored
Invoice email states the invoice's real status (#186)
The invoice-ready mail printed a fixed "Open"; a resent paid invoice arrived saying it was open (#185). Invoice::statusLabel() gives the mail the same wording for paid, partial, pending, void, draft, and open. Closes #185 Claude-Session: https://claude.ai/code/session_012bBptf9B3BtyeQaTWMrosd Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 51baa75 commit f73459a

3 files changed

Lines changed: 65 additions & 1 deletion

File tree

‎app/Models/Invoice.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ public function scopeOwnedBy(Builder $query, User|int $user): Builder
183183
return $query->where('user_id', $userId);
184184
}
185185

186+
public function statusLabel(): string
187+
{
188+
return match ($this->status) {
189+
'paid' => 'Paid',
190+
'partial' => 'Partially paid',
191+
'pending' => 'Payment pending',
192+
'void' => 'Void',
193+
'draft' => 'Draft',
194+
default => 'Open',
195+
};
196+
}
197+
186198
public function scopeOpen(Builder $query): Builder
187199
{
188200
return $query->whereIn('status', ['draft', 'sent', 'partial']);

‎resources/views/mail/invoice-ready.blade.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<x-mail::panel>
1313
**Due date:** {{ optional($invoice->due_date)->toFormattedDateString() ?? '—' }}
1414
**Amount (BTC):** {{ $invoice->amount_btc ?? '—' }}
15-
**Status:** Open
15+
**Status:** {{ $invoice->statusLabel() }}
1616
</x-mail::panel>
1717

1818
<x-mail::panel>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace Tests\Feature;
4+
5+
use App\Mail\InvoiceReadyMail;
6+
use App\Models\Client;
7+
use App\Models\Invoice;
8+
use App\Models\InvoiceDelivery;
9+
use App\Models\User;
10+
use Illuminate\Foundation\Testing\RefreshDatabase;
11+
use Tests\TestCase;
12+
13+
/**
14+
* The invoice email states the invoice's real status, not a fixed word (#185).
15+
*/
16+
class InvoiceReadyMailStatusTest extends TestCase
17+
{
18+
use RefreshDatabase;
19+
20+
public function test_the_invoice_email_reports_the_invoice_status(): void
21+
{
22+
$owner = User::factory()->create();
23+
$client = Client::create(['user_id' => $owner->id, 'name' => 'Status Client', 'email' => 'status@example.com']);
24+
25+
foreach ([['paid', 'Paid'], ['partial', 'Partially paid'], ['sent', 'Open'], ['void', 'Void']] as [$status, $label]) {
26+
$invoice = Invoice::create([
27+
'user_id' => $owner->id,
28+
'client_id' => $client->id,
29+
'number' => 'INV-STATUS-'.strtoupper($status),
30+
'amount_usd' => 10,
31+
'btc_rate' => 40_000,
32+
'amount_btc' => 0.00025,
33+
'payment_address' => 'tb1qq0example'.$status,
34+
'status' => $status,
35+
'invoice_date' => now()->toDateString(),
36+
]);
37+
$invoice->enablePublicShare();
38+
$delivery = InvoiceDelivery::create([
39+
'invoice_id' => $invoice->id,
40+
'user_id' => $owner->id,
41+
'type' => 'send',
42+
'status' => 'queued',
43+
'recipient' => $client->email,
44+
'dispatched_at' => now(),
45+
]);
46+
47+
$html = (new InvoiceReadyMail($invoice->fresh(), $delivery))->render();
48+
49+
$this->assertStringContainsString('Status:</strong> '.$label, $html, "status {$status}");
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)