InhabitantClassificationService.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. namespace App\Services;
  3. use App\Models\InhabitantClassification;
  4. use App\Models\Unit;
  5. use App\Models\UnitInhabitantClassification;
  6. use Illuminate\Database\Eloquent\Collection;
  7. class InhabitantClassificationService
  8. {
  9. public function getAll(): Collection
  10. {
  11. return InhabitantClassification::orderBy('id')->get();
  12. }
  13. public function getSelectList(): Collection
  14. {
  15. return InhabitantClassification::orderBy('id')
  16. ->get(['id', 'description', 'start', 'end', 'tbr_percentage']);
  17. }
  18. public function findById(int $id): ?InhabitantClassification
  19. {
  20. return InhabitantClassification::find($id);
  21. }
  22. public function create(array $data): InhabitantClassification
  23. {
  24. $model = InhabitantClassification::create($data);
  25. $this->propagateToAllUnits($model);
  26. return $model;
  27. }
  28. public function update(int $id, array $data): ?InhabitantClassification
  29. {
  30. $model = $this->findById($id);
  31. if (!$model) {
  32. return null;
  33. }
  34. $oldStart = $model->start;
  35. $oldEnd = $model->end;
  36. $oldTbrPercentage = $model->tbr_percentage;
  37. $oldDescription = $model->description;
  38. $model->update($data);
  39. $updated = $model->fresh();
  40. $this->propagateUpdateToUnits($updated, [
  41. 'description' => $oldDescription,
  42. 'start' => $oldStart,
  43. 'end' => $oldEnd,
  44. 'tbr_percentage' => $oldTbrPercentage,
  45. ]);
  46. return $updated;
  47. }
  48. public function delete(int $id): bool
  49. {
  50. $model = $this->findById($id);
  51. if (!$model) {
  52. return false;
  53. }
  54. return $model->delete();
  55. }
  56. //
  57. private function propagateToAllUnits(InhabitantClassification $parent): void
  58. {
  59. $existingUnitIds = UnitInhabitantClassification::where('start', $parent->start)
  60. ->where('end', $parent->end)
  61. ->pluck('unit_id');
  62. Unit::whereNotIn('id', $existingUnitIds)
  63. ->each(function (Unit $unit) use ($parent) {
  64. UnitInhabitantClassification::create([
  65. 'unit_id' => $unit->id,
  66. 'description' => $parent->description,
  67. 'start' => $parent->start,
  68. 'end' => $parent->end,
  69. 'tbr_percentage' => $parent->tbr_percentage,
  70. ]);
  71. });
  72. }
  73. private function propagateUpdateToUnits(InhabitantClassification $parent, array $old): void
  74. {
  75. // propaga a atualizacao para as classificacoes de unidades que tenham os mesmos valores antigos
  76. UnitInhabitantClassification::where('start', $old['start'])
  77. ->where('end', $old['end'])
  78. ->where('tbr_percentage', $old['tbr_percentage'])
  79. ->where('description', $old['description'])
  80. ->update([
  81. 'description' => $parent->description,
  82. 'start' => $parent->start,
  83. 'end' => $parent->end,
  84. 'tbr_percentage' => $parent->tbr_percentage,
  85. ]);
  86. // garante que todas as unidades tenham a classificacao, criando para as que ainda nao tem
  87. $coveredUnitIds = UnitInhabitantClassification::where(function ($q) use ($parent, $old) {
  88. $q->where(fn($q) => $q->where('start', $parent->start)->where('end', $parent->end))
  89. ->orWhere(fn($q) => $q->where('start', $old['start'])->where('end', $old['end']));
  90. })
  91. ->pluck('unit_id')
  92. ->unique();
  93. Unit::whereNotIn('id', $coveredUnitIds)
  94. ->each(function (Unit $unit) use ($parent) {
  95. UnitInhabitantClassification::create([
  96. 'unit_id' => $unit->id,
  97. 'description' => $parent->description,
  98. 'start' => $parent->start,
  99. 'end' => $parent->end,
  100. 'tbr_percentage' => $parent->tbr_percentage,
  101. ]);
  102. });
  103. }
  104. }