You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DocumentDTO.php 3.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. namespace App\DTO;
  3. use App\Enums\Setting\Font;
  4. use App\Models\Accounting\Document;
  5. use App\Models\Setting\DocumentDefault;
  6. use App\Utilities\Currency\CurrencyAccessor;
  7. use App\Utilities\Currency\CurrencyConverter;
  8. use Filament\FontProviders\BunnyFontProvider;
  9. use Illuminate\Contracts\Support\Htmlable;
  10. readonly class DocumentDTO
  11. {
  12. /**
  13. * @param LineItemDTO[] $lineItems
  14. */
  15. public function __construct(
  16. public string $header,
  17. public ?string $subheader,
  18. public ?string $footer,
  19. public ?string $terms,
  20. public ?string $logo,
  21. public string $number,
  22. public ?string $referenceNumber,
  23. public string $date,
  24. public string $dueDate,
  25. public string $currencyCode,
  26. public ?string $subtotal,
  27. public ?string $discount,
  28. public ?string $tax,
  29. public string $total,
  30. public string $amountDue,
  31. public CompanyDTO $company,
  32. public ClientDTO $client,
  33. public iterable $lineItems,
  34. public DocumentLabelDTO $label,
  35. public DocumentColumnLabelDTO $columnLabel,
  36. public string $accentColor = '#000000',
  37. public bool $showLogo = true,
  38. public Font $font = Font::Inter,
  39. ) {}
  40. public static function fromModel(Document $document): self
  41. {
  42. /** @var DocumentDefault $settings */
  43. $settings = $document->company->documentDefaults()
  44. ->type($document::documentType())
  45. ->first() ?? $document->company->defaultInvoice;
  46. $currencyCode = $document->currency_code ?? CurrencyAccessor::getDefaultCurrency();
  47. $discount = $document->discount_total > 0 ? self::formatToMoney($document->discount_total, $currencyCode) : null;
  48. $tax = $document->tax_total > 0 ? self::formatToMoney($document->tax_total, $currencyCode) : null;
  49. if (! $discount && ! $tax) {
  50. $subtotal = null;
  51. } else {
  52. $subtotal = self::formatToMoney($document->subtotal, $currencyCode);
  53. }
  54. return new self(
  55. header: $document->header,
  56. subheader: $document->subheader,
  57. footer: $document->footer,
  58. terms: $document->terms,
  59. logo: $document->logo,
  60. number: $document->documentNumber(),
  61. referenceNumber: $document->referenceNumber(),
  62. date: $document->documentDate(),
  63. dueDate: $document->dueDate(),
  64. currencyCode: $currencyCode,
  65. subtotal: $subtotal,
  66. discount: $discount,
  67. tax: $tax,
  68. total: self::formatToMoney($document->total, $currencyCode),
  69. amountDue: self::formatToMoney($document->amountDue(), $currencyCode),
  70. company: CompanyDTO::fromModel($document->company),
  71. client: ClientDTO::fromModel($document->client),
  72. lineItems: $document->lineItems->map(fn ($item) => LineItemDTO::fromModel($item)),
  73. label: $document::documentType()->getLabels(),
  74. columnLabel: DocumentColumnLabelDTO::fromModel($settings),
  75. accentColor: $settings->accent_color ?? '#000000',
  76. showLogo: $settings->show_logo ?? false,
  77. font: $settings->font ?? Font::Inter,
  78. );
  79. }
  80. protected static function formatToMoney(float | string $value, ?string $currencyCode): string
  81. {
  82. return CurrencyConverter::formatToMoney($value, $currencyCode);
  83. }
  84. public function getFontHtml(): Htmlable
  85. {
  86. return app(BunnyFontProvider::class)->getHtml($this->font->getLabel());
  87. }
  88. }