StoreItemService.php 5.2 KB

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