Add Remember mail for sending

This commit is contained in:
Philipp Lang 2023-12-18 02:17:31 +01:00
parent afbfdf7ca2
commit 156b92f765
8 changed files with 125 additions and 3 deletions

View File

@ -3,8 +3,12 @@
namespace App\Invoice\Actions;
use App\Invoice\BillDocument;
use App\Invoice\BillKind;
use App\Invoice\Enums\InvoiceStatus;
use App\Invoice\Mails\BillMail;
use App\Invoice\Mails\RememberMail;
use App\Invoice\Models\Invoice;
use App\Invoice\RememberDocument;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Lorisleiva\Actions\Concerns\AsAction;
@ -31,13 +35,20 @@ class InvoiceSendAction
*/
public function handle(): int
{
foreach (Invoice::whereNeedsBill()->get() as $invoice) {
foreach (Invoice::whereNeedsBill()->where('via', BillKind::EMAIL)->get() as $invoice) {
$document = BillDocument::fromInvoice($invoice);
$path = Storage::disk('temp')->path(Tex::compile($document)->storeIn('', 'temp'));
Mail::to($invoice->getMailRecipient())->send(new BillMail($invoice, $path));
$invoice->sent($document);
}
foreach (Invoice::whereNeedsRemember()->where('via', BillKind::EMAIL)->get() as $invoice) {
$document = RememberDocument::fromInvoice($invoice);
$path = Storage::disk('temp')->path(Tex::compile($document)->storeIn('', 'temp'));
Mail::to($invoice->getMailRecipient())->send(new RememberMail($invoice, $path));
$invoice->sent($document);
}
return 0;
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace App\Invoice\Mails;
use App\Invoice\Models\Invoice;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class RememberMail extends Mailable
{
use Queueable;
use SerializesModels;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(public Invoice $invoice, public string $filename)
{
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->markdown('mail.invoice.remember')
->attach($this->filename)
->replyTo('kasse@stamm-silva.de')
->subject('Zahlungserinnerung | DPSG Stamm Silva');
}
}

View File

@ -6,6 +6,7 @@ use App\Invoice\BillDocument;
use App\Invoice\BillKind;
use App\Invoice\Enums\InvoiceStatus;
use App\Invoice\InvoiceDocument;
use App\Invoice\RememberDocument;
use App\Member\Member;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -28,6 +29,7 @@ class Invoice extends Model
/** @var array<int, string> */
public $dates = [
'sent_at',
'last_remembered_at',
];
/**
@ -82,6 +84,19 @@ class Invoice extends Model
return $query->where('status', InvoiceStatus::NEW);
}
/**
* @param Builder<self> $query
*
* @return Builder<self>
*/
public function scopeWhereNeedsRemember(Builder $query): Builder
{
return $query->where('status', InvoiceStatus::SENT)->whereNotNull('sent_at')->where(function ($query) {
return $query->orWhere('last_remembered_at', '<=', now()->subMonths(3))
->orWhereNull('last_remembered_at');
});
}
public function getMailRecipient(): stdClass
{
return (object) [
@ -98,5 +113,12 @@ class Invoice extends Model
'status' => InvoiceStatus::SENT,
]);
}
if (is_a($document, RememberDocument::class)) {
$this->update([
'last_remembered_at' => now(),
'status' => InvoiceStatus::SENT,
]);
}
}
}

View File

@ -29,6 +29,7 @@ class InvoiceFactory extends Factory
'status' => InvoiceStatus::NEW->value,
'via' => BillKind::POST->value,
'usage' => $this->faker->words(4, true),
'mail_email' => $this->faker->safeEmail(),
];
}

View File

@ -22,6 +22,7 @@ return new class extends Migration
$table->string('via');
$table->string('usage');
$table->string('mail_email')->nullable();
$table->datetime('last_remembered_at')->nullable();
$table->timestamps();
});

View File

@ -7,8 +7,10 @@ use App\Invoice\BillDocument;
use App\Invoice\BillKind;
use App\Invoice\Enums\InvoiceStatus;
use App\Invoice\Mails\BillMail;
use App\Invoice\Mails\RememberMail;
use App\Invoice\Models\Invoice;
use App\Invoice\Models\InvoicePosition;
use App\Invoice\RememberDocument;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
@ -19,7 +21,7 @@ class InvoiceSendActionTest extends TestCase
{
use DatabaseTransactions;
public function testItCanCreatePdfPayments(): void
public function testItSendsInvoices(): void
{
Mail::fake();
Tex::spy();
@ -27,7 +29,7 @@ class InvoiceSendActionTest extends TestCase
$this->withoutExceptionHandling()->login()->loginNami();
$invoice = Invoice::factory()
->to(ReceiverRequestFactory::new()->name('Familie Muster'))
->has(InvoicePosition::factory()->description('lalab')->withMember(), 'positions')
->has(InvoicePosition::factory()->withMember(), 'positions')
->via(BillKind::EMAIL)
->create(['mail_email' => 'max@muster.de']);
@ -38,4 +40,53 @@ class InvoiceSendActionTest extends TestCase
$this->assertEquals(InvoiceStatus::SENT, $invoice->fresh()->status);
$this->assertEquals(now()->format('Y-m-d'), $invoice->fresh()->sent_at->format('Y-m-d'));
}
public function testItRemembersInvoices(): void
{
Mail::fake();
Tex::spy();
Storage::fake('temp');
$this->withoutExceptionHandling()->login()->loginNami();
$invoice = Invoice::factory()
->to(ReceiverRequestFactory::new()->name('Familie Muster'))
->has(InvoicePosition::factory()->withMember(), 'positions')
->via(BillKind::EMAIL)
->status(InvoiceStatus::SENT)
->create(['sent_at' => now()->subMonths(6), 'mail_email' => 'max@muster.de']);
InvoiceSendAction::run();
Mail::assertSent(RememberMail::class, fn ($mail) => $mail->build() && $mail->hasTo('max@muster.de', 'Familie Muster') && Storage::disk('temp')->path('zahlungserinnerung-fur-familie-muster.pdf') === $mail->filename && Storage::disk('temp')->exists('zahlungserinnerung-fur-familie-muster.pdf'));
Tex::assertCompiled(RememberDocument::class, fn ($document) => 'Familie Muster' === $document->toName);
$this->assertEquals(now()->format('Y-m-d'), $invoice->fresh()->last_remembered_at->format('Y-m-d'));
}
public function testItDoesntRememberWhenNotDue(): void
{
Mail::fake();
$this->withoutExceptionHandling()->login()->loginNami();
Invoice::factory()
->has(InvoicePosition::factory()->withMember(), 'positions')
->via(BillKind::EMAIL)
->status(InvoiceStatus::SENT)
->create(['sent_at' => now()->subMonths(6), 'last_remembered_at' => now()->subMonth()]);
InvoiceSendAction::run();
Mail::assertNotSent(RememberMail::class);
}
public function testItDoesntSendPostInvoices(): void
{
Mail::fake();
$this->withoutExceptionHandling()->login()->loginNami();
Invoice::factory()
->has(InvoicePosition::factory()->withMember(), 'positions')
->via(BillKind::POST)
->create();
InvoiceSendAction::run();
Mail::assertNotSent(BillMail::class);
}
}