with('tenant:id,tenant_code,tenant_name') ->when(! $actor->isMasterAdmin(), fn ($q) => $q->where('tenant_id', $tenantId)) ->when($actor->isMasterAdmin() && $tenantId, fn ($q) => $q->where('tenant_id', $tenantId)) ->when(! empty($filters['status']), fn ($q) => $q->where('status', $filters['status'])) ->when(! empty($filters['search']), fn ($q) => $q->where('name', 'ILIKE', "%{$filters['search']}%")) ->orderBy($filters['sort_by'] ?? 'id', $filters['sort_direction'] ?? 'desc') ->paginate($filters['per_page'] ?? 10); } public function find(int $id): BillingProfile { return BillingProfile::with('tenant:id,tenant_code,tenant_name')->findOrFail($id); } public function create(array $data, User $actor, ?int $tenantId): BillingProfile { $data['tenant_id'] = $actor->isMasterAdmin() ? ($data['tenant_id'] ?? $tenantId) : $tenantId; if (! $data['tenant_id']) { throw ValidationException::withMessages(['tenant_id' => 'Tenant wajib dipilih.']); } $data['tax_rate'] = $data['tax_type'] === 'non_tax' ? 0 : ($data['tax_rate'] ?? 11); $data['status'] ??= 'active'; $data = $this->normalizeSchedule($data); return BillingProfile::create($data)->load('tenant:id,tenant_code,tenant_name'); } public function update(BillingProfile $profile, array $data, User $actor): BillingProfile { if (! $actor->isMasterAdmin()) { unset($data['tenant_id']); } if (($data['tax_type'] ?? $profile->tax_type) === 'non_tax') { $data['tax_rate'] = 0; } $data = $this->normalizeSchedule($data, $profile); $profile->update($data); return $profile->fresh()->load('tenant:id,tenant_code,tenant_name'); } public function delete(BillingProfile $profile): void { if ($profile->customers()->exists() || $profile->invoices()->exists()) { throw ValidationException::withMessages(['profile' => 'Profile tagihan masih digunakan customer atau invoice.']); } $profile->delete(); } private function normalizeSchedule(array $data, ?BillingProfile $profile = null): array { $type = $data['schedule_type'] ?? $profile?->schedule_type ?? 'fixed_date'; $data['schedule_type'] = $type; if ($type === 'installation_date') { $data['invoice_day'] = $profile?->invoice_day ?? 1; $data['send_day'] = $profile?->send_day ?? 1; $data['warning_day'] = $profile?->warning_day ?? 1; $data['isolation_day'] = $profile?->isolation_day ?? 1; } else { $data['invoice_days_before'] = null; $data['send_days_before'] = null; $data['warning_days_before'] = null; $data['isolation_days_after'] = null; } return $data; } }