StoreItemService.php 4.9 KB

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