ClassPackageUnitService.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace App\Services;
  3. use App\Models\ClassPackage;
  4. use App\Models\ClassPackageUnit;
  5. use App\Models\IrrecusableProposalUnit;
  6. use App\Models\IrrecusableProposalUnitProduct;
  7. use App\Models\PavaoProposalUnit;
  8. use App\Models\PavaoProposalUnitProduct;
  9. use Illuminate\Database\Eloquent\Collection;
  10. class ClassPackageUnitService
  11. {
  12. public function __construct(
  13. protected ProposalPricingService $pricingService,
  14. ) {}
  15. private const EAGER_LOAD = [
  16. 'pavaoProposalUnit.products.product',
  17. 'irrecusableProposalUnit.products.product',
  18. ];
  19. public function getByUnit(int $unitId): Collection
  20. {
  21. return ClassPackageUnit::with(self::EAGER_LOAD)
  22. ->where('unit_id', $unitId)
  23. ->where('visible', true)
  24. ->orderBy('name')
  25. ->get();
  26. }
  27. public function getAllByUnit(int $unitId): Collection
  28. {
  29. return ClassPackageUnit::with(self::EAGER_LOAD)
  30. ->where('unit_id', $unitId)
  31. ->orderBy('name')
  32. ->get();
  33. }
  34. public function findByIdForUnit(int $id, int $unitId): ClassPackageUnit
  35. {
  36. return ClassPackageUnit::with(self::EAGER_LOAD)
  37. ->where('unit_id', $unitId)
  38. ->findOrFail($id);
  39. }
  40. public function create(array $data): ClassPackageUnit
  41. {
  42. $pavao = array_key_exists('pavao', $data) ? $data['pavao'] : null;
  43. $irrecusavel = array_key_exists('irrecusavel', $data) ? $data['irrecusavel'] : null;
  44. unset($data['pavao'], $data['irrecusavel']);
  45. $packageUnit = ClassPackageUnit::create($data);
  46. if ($pavao !== null) {
  47. $this->pricingService->upsert(PavaoProposalUnit::class, PavaoProposalUnitProduct::class, 'class_package_unit_id', $packageUnit->id, $pavao);
  48. }
  49. if ($irrecusavel !== null) {
  50. $this->pricingService->upsert(IrrecusableProposalUnit::class, IrrecusableProposalUnitProduct::class, 'class_package_unit_id', $packageUnit->id, $irrecusavel, withCondition: true);
  51. }
  52. return $packageUnit->load(self::EAGER_LOAD);
  53. }
  54. public function update(int $id, int $unitId, array $data): ClassPackageUnit
  55. {
  56. $packageUnit = $this->findByIdForUnit($id, $unitId);
  57. $pavaoProvided = array_key_exists('pavao', $data);
  58. $irrecusavelProvided = array_key_exists('irrecusavel', $data);
  59. $pavao = $data['pavao'] ?? null;
  60. $irrecusavel = $data['irrecusavel'] ?? null;
  61. unset($data['pavao'], $data['irrecusavel']);
  62. $packageUnit->update($data);
  63. // Edits here only affect this unit's own copy — never propagate up to the base package.
  64. if ($pavaoProvided) {
  65. if ($pavao !== null) {
  66. $this->pricingService->upsert(PavaoProposalUnit::class, PavaoProposalUnitProduct::class, 'class_package_unit_id', $packageUnit->id, $pavao);
  67. } else {
  68. $this->pricingService->deleteFor(PavaoProposalUnit::class, 'class_package_unit_id', $packageUnit->id);
  69. }
  70. }
  71. if ($irrecusavelProvided) {
  72. if ($irrecusavel !== null) {
  73. $this->pricingService->upsert(IrrecusableProposalUnit::class, IrrecusableProposalUnitProduct::class, 'class_package_unit_id', $packageUnit->id, $irrecusavel, withCondition: true);
  74. } else {
  75. $this->pricingService->deleteFor(IrrecusableProposalUnit::class, 'class_package_unit_id', $packageUnit->id);
  76. }
  77. }
  78. return $packageUnit->fresh(self::EAGER_LOAD);
  79. }
  80. public function toggleVisibility(int $id, int $unitId): ClassPackageUnit
  81. {
  82. $packageUnit = $this->findByIdForUnit($id, $unitId);
  83. $packageUnit->update(['visible' => !$packageUnit->visible]);
  84. return $packageUnit->fresh();
  85. }
  86. public function delete(int $id, int $unitId): bool
  87. {
  88. $packageUnit = $this->findByIdForUnit($id, $unitId);
  89. return $packageUnit->delete();
  90. }
  91. public function replicateFromBasePackage(int $unitId, ClassPackage $basePackage): ClassPackageUnit
  92. {
  93. $packageUnit = ClassPackageUnit::create([
  94. 'unit_id' => $unitId,
  95. 'class_package_id' => $basePackage->id,
  96. 'name' => $basePackage->name,
  97. 'quantity_classes' => $basePackage->quantity_classes,
  98. 'class_duration_minutes' => $basePackage->class_duration_minutes,
  99. 'weekday' => $basePackage->weekday,
  100. 'start_time' => $basePackage->start_time,
  101. 'second_weekday' => $basePackage->second_weekday,
  102. 'second_start_time' => $basePackage->second_start_time,
  103. 'visible' => true,
  104. ]);
  105. $this->pricingService->cloneToUnit(
  106. $basePackage->pavaoProposal,
  107. PavaoProposalUnit::class,
  108. PavaoProposalUnitProduct::class,
  109. 'class_package_unit_id',
  110. $packageUnit->id,
  111. 'pavao_proposal_id',
  112. );
  113. $this->pricingService->cloneToUnit(
  114. $basePackage->irrecusableProposal,
  115. IrrecusableProposalUnit::class,
  116. IrrecusableProposalUnitProduct::class,
  117. 'class_package_unit_id',
  118. $packageUnit->id,
  119. 'irrecusable_proposal_id',
  120. withCondition: true,
  121. );
  122. return $packageUnit;
  123. }
  124. }