ServicePackageItemService.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\ServicePackageStatusEnum;
  4. use App\Enums\PaymentStatusEnum;
  5. use App\Models\ServicePackage;
  6. use App\Models\ServicePackageItem;
  7. use App\Models\Payment;
  8. use App\Models\Schedule;
  9. use Illuminate\Database\Eloquent\Collection;
  10. use Illuminate\Support\Facades\DB;
  11. use Illuminate\Validation\ValidationException;
  12. class ServicePackageItemService
  13. {
  14. public function getAll(): Collection
  15. {
  16. return ServicePackageItem::query()
  17. ->orderBy('created_at', 'desc')
  18. ->get();
  19. }
  20. public function findById(int $id): ?ServicePackageItem
  21. {
  22. return ServicePackageItem::find($id);
  23. }
  24. public function create(array $data): ServicePackageItem
  25. {
  26. return DB::transaction(function () use ($data) {
  27. [$servicePackage, $schedule] = $this->validateItem(data_get($data, 'service_package_id'), data_get($data, 'schedule_id'));
  28. if (! $servicePackage->provider_id) {
  29. $servicePackage->update(['provider_id' => $schedule->provider_id]);
  30. }
  31. return ServicePackageItem::create($data);
  32. });
  33. }
  34. public function update(int $id, array $data): ?ServicePackageItem
  35. {
  36. return DB::transaction(function () use ($id, $data): ?ServicePackageItem {
  37. $model = $this->findById($id);
  38. if (! $model) {
  39. return null;
  40. }
  41. $servicePackageId = data_get($data, 'service_package_id', $model->service_package_id);
  42. $scheduleId = data_get($data, 'schedule_id', $model->schedule_id);
  43. [$servicePackage, $schedule] = $this->validateItem($servicePackageId, $scheduleId);
  44. if (! $servicePackage->provider_id) {
  45. $servicePackage->update(['provider_id' => $schedule->provider_id]);
  46. }
  47. $model->update($data);
  48. return $model->fresh();
  49. });
  50. }
  51. public function delete(int $id): bool
  52. {
  53. $model = $this->findById($id);
  54. if (!$model) {
  55. return false;
  56. }
  57. return DB::transaction(function () use ($model): bool {
  58. $this->validateItem($model->service_package_id, $model->schedule_id);
  59. return $model->delete();
  60. });
  61. }
  62. private function validateItem(int $servicePackageId, int $scheduleId): array
  63. {
  64. $servicePackage = ServicePackage::query()->lockForUpdate()->findOrFail($servicePackageId);
  65. $schedule = Schedule::query()->findOrFail($scheduleId);
  66. if ($servicePackage->status !== ServicePackageStatusEnum::OPEN) {
  67. throw ValidationException::withMessages([
  68. 'service_package_id' => __('messages.service_package_must_be_open_for_changes'),
  69. ]);
  70. }
  71. if ($schedule->client_id !== $servicePackage->client_id) {
  72. throw ValidationException::withMessages([
  73. 'schedule_id' => __('messages.service_package_schedule_same_client'),
  74. ]);
  75. }
  76. if (! $schedule->provider_id || ($servicePackage->provider_id && $schedule->provider_id !== $servicePackage->provider_id)) {
  77. throw ValidationException::withMessages([
  78. 'schedule_id' => __('messages.service_package_same_provider'),
  79. ]);
  80. }
  81. $belongsToAnotherPackage = ServicePackageItem::query()
  82. ->where('schedule_id', $scheduleId)
  83. ->where('service_package_id', '!=', $servicePackageId)
  84. ->exists();
  85. if ($belongsToAnotherPackage) {
  86. throw ValidationException::withMessages([
  87. 'schedule_id' => __('messages.service_package_schedule_already_assigned'),
  88. ]);
  89. }
  90. $hasActivePayment = Payment::query()
  91. ->where('schedule_id', $scheduleId)
  92. ->whereIn('status', [
  93. PaymentStatusEnum::PENDING->value,
  94. PaymentStatusEnum::PROCESSING->value,
  95. PaymentStatusEnum::AUTHORIZED->value,
  96. PaymentStatusEnum::PAID->value,
  97. ])
  98. ->exists();
  99. if ($hasActivePayment) {
  100. throw ValidationException::withMessages([
  101. 'schedule_id' => __('messages.service_package_schedule_has_active_payment'),
  102. ]);
  103. }
  104. return [$servicePackage, $schedule];
  105. }
  106. }