StoreItemService.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\StoreItemStatusEnum;
  4. use App\Models\StoreItem;
  5. use App\Models\StoreItemInterest;
  6. use App\Models\StoreItemVariation;
  7. use Illuminate\Database\Eloquent\Collection;
  8. use Illuminate\Support\Arr;
  9. use Illuminate\Support\Facades\Auth;
  10. use Illuminate\Support\Facades\DB;
  11. class StoreItemService
  12. {
  13. public function getAll(bool $onlyActive = false): Collection
  14. {
  15. $userId = Auth::id();
  16. $query = StoreItem::with(['category', 'media', 'variations'])
  17. ->withCount('interests')
  18. ->orderBy('name');
  19. if ($onlyActive) {
  20. $query->where('status', StoreItemStatusEnum::ACTIVE);
  21. }
  22. if ($userId) {
  23. $query->withExists(['interests as user_interested' => fn($q) => $q->where('user_id', $userId)]);
  24. }
  25. return $query->get();
  26. }
  27. public function findById(int $id, bool $onlyActive = false): ?StoreItem
  28. {
  29. $query = StoreItem::with(['category', 'media', 'variations']);
  30. if ($onlyActive) {
  31. $query->where('status', StoreItemStatusEnum::ACTIVE);
  32. }
  33. return $query->find($id);
  34. }
  35. public function create(array $data): StoreItem
  36. {
  37. return DB::transaction(function () use ($data) {
  38. $variations = $data['variations'] ?? [];
  39. $item = StoreItem::create(Arr::except($data, ['variations']));
  40. foreach ($variations as $variation) {
  41. $item->variations()->create($variation);
  42. }
  43. return $item->load(['category', 'media', 'variations']);
  44. });
  45. }
  46. public function update(int $id, array $data): ?StoreItem
  47. {
  48. return DB::transaction(function () use ($id, $data) {
  49. $model = StoreItem::findOrFail($id);
  50. $variations = array_key_exists('variations', $data) ? $data['variations'] : null;
  51. $model->update(Arr::except($data, ['variations']));
  52. if (!is_null($variations)) {
  53. $model->variations()->delete();
  54. foreach ($variations as $variation) {
  55. $model->variations()->create($variation);
  56. }
  57. }
  58. return $model->fresh(['category', 'media', 'variations']);
  59. });
  60. }
  61. public function delete(int $id): bool
  62. {
  63. $model = StoreItem::find($id);
  64. if (!$model) return false;
  65. return $model->delete();
  66. }
  67. public function getAllPaginated(array $filters = [], int $perPage = 10): \Illuminate\Contracts\Pagination\LengthAwarePaginator
  68. {
  69. $query = StoreItem::with(['category', 'media', 'variations'])
  70. ->withCount('interests')
  71. ->orderBy('name');
  72. if (!empty($filters['search'])) {
  73. $search = $filters['search'];
  74. $query->where('name', 'ilike', "%{$search}%");
  75. }
  76. if (!empty($filters['status'])) {
  77. $query->where('status', $filters['status']);
  78. }
  79. if (!empty($filters['category_id'])) {
  80. $query->where('category_id', $filters['category_id']);
  81. }
  82. return $query->paginate($perPage);
  83. }
  84. public function toggleStatus(int $id): ?StoreItem
  85. {
  86. $model = StoreItem::find($id);
  87. if (!$model) return null;
  88. $model->status = $model->status->value === 'active'
  89. ? StoreItemStatusEnum::INACTIVE
  90. : StoreItemStatusEnum::ACTIVE;
  91. $model->save();
  92. return $model->fresh(['category', 'media', 'variations']);
  93. }
  94. public function getMyInterests(): Collection
  95. {
  96. $userId = Auth::id();
  97. return StoreItem::with(['category', 'media', 'variations'])
  98. ->withCount('interests')
  99. ->whereHas('interests', fn($q) => $q->where('user_id', $userId))
  100. ->orderBy('name')
  101. ->get();
  102. }
  103. public function toggleInterest(int $storeItemId): array
  104. {
  105. $userId = Auth::id();
  106. $existing = StoreItemInterest::where('user_id', $userId)
  107. ->where('store_item_id', $storeItemId)
  108. ->first();
  109. if ($existing) {
  110. $existing->delete();
  111. return ['interested' => false];
  112. }
  113. StoreItemInterest::create(['user_id' => $userId, 'store_item_id' => $storeItemId]);
  114. return ['interested' => true];
  115. }
  116. public function getInterestsByItem(int $storeItemId): array
  117. {
  118. return StoreItemInterest::with('user')
  119. ->where('store_item_id', $storeItemId)
  120. ->get()
  121. ->map(fn($interest) => [
  122. 'id' => $interest->user?->id,
  123. 'name' => $interest->user?->name,
  124. 'email' => $interest->user?->email,
  125. ])
  126. ->values()
  127. ->toArray();
  128. }
  129. public function addVariation(int $storeItemId, array $data): StoreItemVariation
  130. {
  131. $item = StoreItem::findOrFail($storeItemId);
  132. return $item->variations()->create($data);
  133. }
  134. public function updateVariation(int $storeItemId, int $variationId, array $data): StoreItemVariation
  135. {
  136. $variation = StoreItemVariation::where('store_item_id', $storeItemId)
  137. ->findOrFail($variationId);
  138. $variation->update($data);
  139. return $variation->fresh();
  140. }
  141. public function deleteVariation(int $storeItemId, int $variationId): void
  142. {
  143. StoreItemVariation::where('store_item_id', $storeItemId)
  144. ->findOrFail($variationId)
  145. ->delete();
  146. }
  147. }