82 lines
3.1 KiB
PHP
82 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Billing;
|
|
|
|
use App\Models\BillingProfile;
|
|
use App\Models\User;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
class BillingProfileService
|
|
{
|
|
public function list(array $filters, User $actor, ?int $tenantId)
|
|
{
|
|
return BillingProfile::query()->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;
|
|
}
|
|
}
|