adrema/app/Invoice/Invoice.php

146 lines
4.1 KiB
PHP
Raw Normal View History

2022-11-07 16:18:11 +01:00
<?php
2023-04-18 22:08:45 +02:00
namespace App\Invoice;
2022-11-07 16:18:11 +01:00
2023-11-30 23:54:16 +01:00
use App\Member\Member;
2022-11-07 16:18:11 +01:00
use App\Payment\Payment;
use Exception;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Zoomyboy\Tex\Document;
use Zoomyboy\Tex\Engine;
use Zoomyboy\Tex\Template;
2023-04-18 22:08:45 +02:00
abstract class Invoice extends Document
2022-11-07 16:18:11 +01:00
{
abstract public function getSubject(): string;
abstract public function view(): string;
2023-11-30 23:54:16 +01:00
abstract public function afterSingle(Payment $payment): void;
2022-11-07 16:18:11 +01:00
abstract public function linkLabel(): string;
2022-12-07 00:40:53 +01:00
abstract public static function sendAllLabel(): string;
2022-11-07 16:18:11 +01:00
/**
* @param HasMany<Payment> $query
*
* @return HasMany<Payment>
*/
abstract public static function paymentsQuery(HasMany $query): HasMany;
/**
* @return array<int, string>
*/
2022-12-07 00:40:53 +01:00
abstract public static function getDescription(): array;
2022-11-07 16:18:11 +01:00
public string $until;
2023-11-30 23:54:16 +01:00
public string $filename;
2022-11-07 16:18:11 +01:00
/**
2023-11-30 23:54:16 +01:00
* @param array<string, string> $positions
2022-11-07 16:18:11 +01:00
*/
2023-11-30 23:54:16 +01:00
public function __construct(
public string $familyName,
public string $singleName,
public string $address,
public string $zip,
public string $location,
public array $positions,
public string $usage,
public ?string $email,
) {
2022-11-07 16:18:11 +01:00
$this->until = now()->addWeeks(2)->format('d.m.Y');
2023-11-30 23:54:16 +01:00
$this->filename = Str::slug("{$this->getSubject()} für {$familyName}");
2022-11-07 16:18:11 +01:00
}
2023-11-30 23:54:16 +01:00
/**
* @param Collection<(int|string), Member> $members
*/
public static function fromMembers(Collection $members): self
2022-11-07 16:18:11 +01:00
{
2023-11-30 23:54:16 +01:00
return static::withoutMagicalCreationFrom([
'familyName' => $members->first()->lastname,
'singleName' => $members->first()->lastname,
'address' => $members->first()->address,
'zip' => $members->first()->zip,
'location' => $members->first()->location,
'email' => $members->first()->email_parents ?: $members->first()->email,
'positions' => static::renderPositions($members),
'usage' => "Mitgliedsbeitrag für {$members->first()->lastname}",
]);
2022-11-07 16:18:11 +01:00
}
2023-11-30 23:54:16 +01:00
public function settings(): InvoiceSettings
2022-11-07 16:18:11 +01:00
{
2023-11-30 23:54:16 +01:00
return app(InvoiceSettings::class);
2022-11-07 16:18:11 +01:00
}
public function getEngine(): Engine
{
2023-07-18 14:18:44 +02:00
return Engine::PDFLATEX;
2022-11-07 16:18:11 +01:00
}
public function basename(): string
{
return $this->filename;
}
public function template(): Template
{
return Template::make('tex.templates.default');
}
public function setFilename(string $filename): self
{
$this->filename = $filename;
return $this;
}
public function getRecipient(): MailRecipient
{
2023-11-30 23:54:16 +01:00
throw_unless($this->email, Exception::class, 'Cannot get Recipient. Mail not set.');
2022-11-07 16:18:11 +01:00
2023-11-30 23:54:16 +01:00
return new MailRecipient($this->email, $this->familyName);
2022-11-07 16:18:11 +01:00
}
2022-11-07 16:42:25 +01:00
/**
* @return view-string
*/
public function mailView(): string
{
2023-11-30 23:54:16 +01:00
$view = 'mail.payment.' . Str::snake(class_basename($this));
2022-11-07 16:42:25 +01:00
2023-11-30 23:54:16 +01:00
throw_unless(view()->exists($view), Exception::class, 'Mail view ' . $view . ' existiert nicht.');
2022-11-07 16:42:25 +01:00
return $view;
}
2023-11-30 23:54:16 +01:00
/**
2023-12-01 01:25:02 +01:00
* @param Collection<(int|string), Member> $members
2023-11-30 23:54:16 +01:00
*
* @return array<string, string>
*/
public static function renderPositions(Collection $members): array
{
/** @var array<string, string> */
$result = [];
foreach ($members->pluck('payments')->flatten(1) as $payment) {
if ($payment->subscription->split) {
foreach ($payment->subscription->children as $child) {
$result["{$payment->subscription->name} ({$child->name}) {$payment->nr} für {$payment->member->firstname} {$payment->member->lastname}"] = static::number($child->amount);
}
} else {
$result["{$payment->subscription->name} {$payment->nr} für {$payment->member->firstname} {$payment->member->lastname}"] = static::number($payment->subscription->getAmount());
}
}
return $result;
}
public static function number(int $number): string
{
return number_format($number / 100, 2, '.', '');
}
2022-11-07 16:18:11 +01:00
}