Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

DocumentDefault.php 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. namespace App\Models\Setting;
  3. use App\Concerns\Blamable;
  4. use App\Concerns\CompanyOwned;
  5. use App\Enums\Accounting\DocumentType;
  6. use App\Enums\Setting\Font;
  7. use App\Enums\Setting\PaymentTerms;
  8. use App\Enums\Setting\Template;
  9. use Database\Factories\Setting\DocumentDefaultFactory;
  10. use Illuminate\Database\Eloquent\Builder;
  11. use Illuminate\Database\Eloquent\Casts\AsArrayObject;
  12. use Illuminate\Database\Eloquent\Casts\Attribute;
  13. use Illuminate\Database\Eloquent\Factories\Factory;
  14. use Illuminate\Database\Eloquent\Factories\HasFactory;
  15. use Illuminate\Database\Eloquent\Model;
  16. use Illuminate\Support\Facades\Storage;
  17. class DocumentDefault extends Model
  18. {
  19. use Blamable;
  20. use CompanyOwned;
  21. use HasFactory;
  22. protected $table = 'document_defaults';
  23. protected $fillable = [
  24. 'company_id',
  25. 'type',
  26. 'logo',
  27. 'show_logo',
  28. 'number_prefix',
  29. 'payment_terms',
  30. 'header',
  31. 'subheader',
  32. 'terms',
  33. 'footer',
  34. 'accent_color',
  35. 'font',
  36. 'template',
  37. 'item_name',
  38. 'unit_name',
  39. 'price_name',
  40. 'amount_name',
  41. 'created_by',
  42. 'updated_by',
  43. ];
  44. protected $casts = [
  45. 'type' => DocumentType::class,
  46. 'show_logo' => 'boolean',
  47. 'payment_terms' => PaymentTerms::class,
  48. 'font' => Font::class,
  49. 'template' => Template::class,
  50. 'item_name' => AsArrayObject::class,
  51. 'unit_name' => AsArrayObject::class,
  52. 'price_name' => AsArrayObject::class,
  53. 'amount_name' => AsArrayObject::class,
  54. ];
  55. protected $appends = [
  56. 'logo_url',
  57. ];
  58. protected function logoUrl(): Attribute
  59. {
  60. return Attribute::get(static function (mixed $value, array $attributes): ?string {
  61. return $attributes['logo'] ? Storage::disk('public')->url($attributes['logo']) : null;
  62. });
  63. }
  64. public function scopeType(Builder $query, string | DocumentType $type): Builder
  65. {
  66. return $query->where($this->qualifyColumn('type'), $type);
  67. }
  68. public function scopeInvoice(Builder $query): Builder
  69. {
  70. return $query->type(DocumentType::Invoice);
  71. }
  72. public function scopeRecurringInvoice(Builder $query): Builder
  73. {
  74. return $query->type(DocumentType::RecurringInvoice);
  75. }
  76. public function scopeBill(Builder $query): Builder
  77. {
  78. return $query->type(DocumentType::Bill);
  79. }
  80. public function scopeEstimate(Builder $query): Builder
  81. {
  82. return $query->type(DocumentType::Estimate);
  83. }
  84. public function getNumberNext(?string $prefix = null, int | string | null $next = null): string
  85. {
  86. $numberPrefix = $prefix ?? $this->number_prefix ?? '';
  87. $numberNext = (string) ($next ?? (static::getBaseNumber() + 1));
  88. return $numberPrefix . $numberNext;
  89. }
  90. public static function getBaseNumber(): int
  91. {
  92. return 1000;
  93. }
  94. public static function getAvailableItemNameOptions(): array
  95. {
  96. $options = [
  97. 'items' => 'Items',
  98. 'products' => 'Products',
  99. 'services' => 'Services',
  100. 'other' => 'Other',
  101. ];
  102. return array_map(translate(...), $options);
  103. }
  104. public static function getAvailableUnitNameOptions(): array
  105. {
  106. $options = [
  107. 'quantity' => 'Quantity',
  108. 'hours' => 'Hours',
  109. 'other' => 'Other',
  110. ];
  111. return array_map(translate(...), $options);
  112. }
  113. public static function getAvailablePriceNameOptions(): array
  114. {
  115. $options = [
  116. 'price' => 'Price',
  117. 'rate' => 'Rate',
  118. 'other' => 'Other',
  119. ];
  120. return array_map(translate(...), $options);
  121. }
  122. public static function getAvailableAmountNameOptions(): array
  123. {
  124. $options = [
  125. 'amount' => 'Amount',
  126. 'total' => 'Total',
  127. 'other' => 'Other',
  128. ];
  129. return array_map(translate(...), $options);
  130. }
  131. public function getLabelOptionFor(string $optionType, ?string $optionValue)
  132. {
  133. $optionValue = $optionValue ?? $this->{$optionType}['option'];
  134. if (! $optionValue) {
  135. return null;
  136. }
  137. $options = match ($optionType) {
  138. 'item_name' => static::getAvailableItemNameOptions(),
  139. 'unit_name' => static::getAvailableUnitNameOptions(),
  140. 'price_name' => static::getAvailablePriceNameOptions(),
  141. 'amount_name' => static::getAvailableAmountNameOptions(),
  142. default => [],
  143. };
  144. return $options[$optionValue] ?? null;
  145. }
  146. public function resolveColumnLabel(string $column, string $default, ?array $data = null): string
  147. {
  148. if ($data) {
  149. $custom = $data[$column]['custom'] ?? null;
  150. $option = $data[$column]['option'] ?? null;
  151. } else {
  152. $custom = $this->{$column}['custom'] ?? null;
  153. $option = $this->{$column}['option'] ?? null;
  154. }
  155. if ($custom) {
  156. return $custom;
  157. }
  158. return $this->getLabelOptionFor($column, $option) ?? $default;
  159. }
  160. protected static function newFactory(): Factory
  161. {
  162. return DocumentDefaultFactory::new();
  163. }
  164. }