InhabitantClassificationService.php 4.1 KB

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