|
|
@@ -3,7 +3,9 @@
|
|
|
namespace App\Services;
|
|
|
|
|
|
use App\Models\StudentContract;
|
|
|
+use App\Models\StudentContractInstallment;
|
|
|
use App\Models\StudentMedia;
|
|
|
+use Carbon\Carbon;
|
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
|
|
@@ -50,7 +52,109 @@ public function create(array $data): StudentContract
|
|
|
}
|
|
|
unset($data['due_day']);
|
|
|
|
|
|
- return StudentContract::create($data);
|
|
|
+ $contract = StudentContract::create($data);
|
|
|
+
|
|
|
+ $this->generateInstallments($contract);
|
|
|
+
|
|
|
+ return $contract;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function generateInstallments(StudentContract $contract): void
|
|
|
+ {
|
|
|
+ $recurringDay = $contract->recurring_day ?? 1;
|
|
|
+ $rows = [];
|
|
|
+ $now = now();
|
|
|
+
|
|
|
+ // --- Matrícula ---
|
|
|
+ if ($contract->tax_register && $contract->installments && $contract->enrollment_due_date) {
|
|
|
+ $value = round($contract->tax_register / $contract->installments, 2);
|
|
|
+ $dates = $this->buildInstallmentDates(
|
|
|
+ $contract->enrollment_due_date->format('Y-m-d'),
|
|
|
+ $recurringDay,
|
|
|
+ $contract->installments,
|
|
|
+ );
|
|
|
+
|
|
|
+ foreach ($dates as $i => $date) {
|
|
|
+ $rows[] = [
|
|
|
+ 'student_contract_id' => $contract->id,
|
|
|
+ 'unit_id' => $contract->unit_id,
|
|
|
+ 'student_id' => $contract->student_id,
|
|
|
+ 'type' => 'enrollment',
|
|
|
+ 'history' => 'REF. MATRÍCULA',
|
|
|
+ 'installment_number' => $i + 1,
|
|
|
+ 'total_installments' => $contract->installments,
|
|
|
+ 'value' => $value,
|
|
|
+ 'paid_value' => 0,
|
|
|
+ 'discount' => 0,
|
|
|
+ 'fine' => 0,
|
|
|
+ 'due_date' => $date->format('Y-m-d'),
|
|
|
+ 'status' => 'pending',
|
|
|
+ 'created_at' => $now,
|
|
|
+ 'updated_at' => $now,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // --- Pacote ---
|
|
|
+ if ($contract->package_value && $contract->package_installments && $contract->package_due_date) {
|
|
|
+ $value = round($contract->package_value / $contract->package_installments, 2);
|
|
|
+ $dates = $this->buildInstallmentDates(
|
|
|
+ $contract->package_due_date->format('Y-m-d'),
|
|
|
+ $recurringDay,
|
|
|
+ $contract->package_installments,
|
|
|
+ );
|
|
|
+
|
|
|
+ foreach ($dates as $i => $date) {
|
|
|
+ $rows[] = [
|
|
|
+ 'student_contract_id' => $contract->id,
|
|
|
+ 'unit_id' => $contract->unit_id,
|
|
|
+ 'student_id' => $contract->student_id,
|
|
|
+ 'type' => 'package',
|
|
|
+ 'history' => 'REF. PACOTE',
|
|
|
+ 'installment_number' => $i + 1,
|
|
|
+ 'total_installments' => $contract->package_installments,
|
|
|
+ 'value' => $value,
|
|
|
+ 'paid_value' => 0,
|
|
|
+ 'discount' => 0,
|
|
|
+ 'fine' => 0,
|
|
|
+ 'due_date' => $date->format('Y-m-d'),
|
|
|
+ 'status' => 'pending',
|
|
|
+ 'created_at' => $now,
|
|
|
+ 'updated_at' => $now,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!empty($rows)) {
|
|
|
+ StudentContractInstallment::insert($rows);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Monta o array de datas para N parcelas.
|
|
|
+ *
|
|
|
+ * - 1ª parcela: usa exatamente $firstDate (data escolhida pelo usuário)
|
|
|
+ * - 2ª em diante: dia $recurringDay avançando mês a mês a partir do mês da 1ª
|
|
|
+ *
|
|
|
+ * Exemplo: firstDate=25/05/2026, recurringDay=5, count=3
|
|
|
+ * → [25/05/2026, 05/06/2026, 05/07/2026]
|
|
|
+ */
|
|
|
+ private function buildInstallmentDates(string $firstDate, int $recurringDay, int $count): array
|
|
|
+ {
|
|
|
+ $dates = [];
|
|
|
+ $first = Carbon::createFromFormat('Y-m-d', $firstDate);
|
|
|
+ $dates[] = $first->copy();
|
|
|
+
|
|
|
+ $baseMonth = $first->copy()->startOfMonth();
|
|
|
+
|
|
|
+ for ($i = 1; $i < $count; $i++) {
|
|
|
+ $next = $baseMonth->copy()->addMonths($i);
|
|
|
+ $day = min($recurringDay, $next->daysInMonth);
|
|
|
+ $next->setDay($day);
|
|
|
+ $dates[] = $next;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $dates;
|
|
|
}
|
|
|
|
|
|
public function update(int $id, array $data): ?StudentContract
|