StoreItemService.php 5.1 KB

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