CommonCatalogItem.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Models;
  4. use App\Helpers\Price;
  5. use Database\Factories\CommonCatalogItemFactory;
  6. use Illuminate\Database\Eloquent\Casts\Attribute;
  7. use Illuminate\Database\Eloquent\Factories\HasFactory;
  8. use Illuminate\Database\Eloquent\Model;
  9. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  10. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  11. use Illuminate\Database\Eloquent\Relations\HasMany;
  12. use Illuminate\Database\Eloquent\Relations\HasOne;
  13. use Illuminate\Database\Eloquent\SoftDeletes;
  14. class CommonCatalogItem extends Model
  15. {
  16. /** @use HasFactory<CommonCatalogItemFactory> */
  17. use HasFactory;
  18. use SoftDeletes;
  19. public const DEFAULT_SORT_BY = 'article';
  20. protected $fillable = [
  21. 'image_file_id',
  22. 'article',
  23. 'calculator_name',
  24. 'kind',
  25. 'dimension_length',
  26. 'dimension_width',
  27. 'dimension_height',
  28. 'site_length',
  29. 'site_width',
  30. 'dimensions',
  31. 'fall_height',
  32. 'additional_info',
  33. 'dimension_unit',
  34. 'weight',
  35. 'volume',
  36. 'places',
  37. 'composition',
  38. 'age_group',
  39. 'max_users',
  40. 'unit',
  41. 'series',
  42. 'trademark',
  43. 'calculator_enabled',
  44. 'builders_price',
  45. 'wholesale_price',
  46. 'recommended_price',
  47. 'retail_price',
  48. 'project_price',
  49. 'project_with_installation_price',
  50. 'pik_price',
  51. 'recommended_plus_10_price',
  52. 'note',
  53. ];
  54. protected $appends = [
  55. 'image',
  56. 'calculator_enabled_txt',
  57. 'builders_price_txt',
  58. 'wholesale_price_txt',
  59. 'recommended_price_txt',
  60. 'retail_price_txt',
  61. 'project_price_txt',
  62. 'project_with_installation_price_txt',
  63. 'pik_price_txt',
  64. 'recommended_plus_10_price_txt',
  65. ];
  66. protected function casts(): array
  67. {
  68. return [
  69. 'fall_height' => 'decimal:3',
  70. 'weight' => 'decimal:3',
  71. 'volume' => 'decimal:3',
  72. 'places' => 'integer',
  73. 'max_users' => 'integer',
  74. 'calculator_enabled' => 'boolean',
  75. ];
  76. }
  77. protected function buildersPrice(): Attribute
  78. {
  79. return $this->priceAttribute();
  80. }
  81. protected function wholesalePrice(): Attribute
  82. {
  83. return $this->priceAttribute();
  84. }
  85. protected function recommendedPrice(): Attribute
  86. {
  87. return $this->priceAttribute();
  88. }
  89. protected function retailPrice(): Attribute
  90. {
  91. return $this->priceAttribute();
  92. }
  93. protected function projectPrice(): Attribute
  94. {
  95. return $this->priceAttribute();
  96. }
  97. protected function projectWithInstallationPrice(): Attribute
  98. {
  99. return $this->priceAttribute();
  100. }
  101. protected function pikPrice(): Attribute
  102. {
  103. return $this->priceAttribute();
  104. }
  105. protected function recommendedPlus10Price(): Attribute
  106. {
  107. return $this->priceAttribute();
  108. }
  109. protected function calculatorEnabledTxt(): Attribute
  110. {
  111. return Attribute::make(
  112. get: fn (): string => match ($this->calculator_enabled) {
  113. true => 'да',
  114. false => 'нет',
  115. null => '',
  116. },
  117. );
  118. }
  119. protected function buildersPriceTxt(): Attribute
  120. {
  121. return $this->formattedPriceAttribute('builders_price');
  122. }
  123. protected function wholesalePriceTxt(): Attribute
  124. {
  125. return $this->formattedPriceAttribute('wholesale_price');
  126. }
  127. protected function recommendedPriceTxt(): Attribute
  128. {
  129. return $this->formattedPriceAttribute('recommended_price');
  130. }
  131. protected function retailPriceTxt(): Attribute
  132. {
  133. return $this->formattedPriceAttribute('retail_price');
  134. }
  135. protected function projectPriceTxt(): Attribute
  136. {
  137. return $this->formattedPriceAttribute('project_price');
  138. }
  139. protected function projectWithInstallationPriceTxt(): Attribute
  140. {
  141. return $this->formattedPriceAttribute('project_with_installation_price');
  142. }
  143. protected function pikPriceTxt(): Attribute
  144. {
  145. return $this->formattedPriceAttribute('pik_price');
  146. }
  147. protected function recommendedPlus10PriceTxt(): Attribute
  148. {
  149. return $this->formattedPriceAttribute('recommended_plus_10_price');
  150. }
  151. public function imageFile(): BelongsTo
  152. {
  153. return $this->belongsTo(File::class, 'image_file_id');
  154. }
  155. public function documents(): BelongsToMany
  156. {
  157. return $this->belongsToMany(
  158. File::class,
  159. 'common_catalog_item_documents',
  160. )->withTimestamps();
  161. }
  162. public function stockOrders(): HasMany
  163. {
  164. return $this->hasMany(StockOrder::class);
  165. }
  166. public function latestStockOrder(): HasOne
  167. {
  168. return $this->hasOne(StockOrder::class)->latestOfMany();
  169. }
  170. public function stockReservations(): HasMany
  171. {
  172. return $this->hasMany(StockReservation::class);
  173. }
  174. public function stockMovements(): HasMany
  175. {
  176. return $this->hasMany(StockMovement::class);
  177. }
  178. protected function image(): Attribute
  179. {
  180. return Attribute::make(
  181. get: fn (): string => (string) ($this->imageFile?->thumbnail_link ?? ''),
  182. );
  183. }
  184. private function priceAttribute(): Attribute
  185. {
  186. return Attribute::make(
  187. get: fn (mixed $value): ?float => $value === null ? null : (int) $value / 100,
  188. set: fn (mixed $value): ?int => $value === null || $value === ''
  189. ? null
  190. : (int) round((float) $value * 100),
  191. );
  192. }
  193. private function formattedPriceAttribute(string $field): Attribute
  194. {
  195. return Attribute::make(
  196. get: fn (): string => isset($this->attributes[$field]) && $this->attributes[$field] !== null
  197. ? Price::format((int) $this->attributes[$field] / 100)
  198. : '-',
  199. );
  200. }
  201. }