79 lines
3.5 KiB
PHP
79 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Customer;
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
use App\Services\Billing\BillingProfileService;
|
|
use App\Services\Billing\InvoiceService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class BillingWorkflowTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_invoice_moves_from_running_to_overdue_and_paid(): void
|
|
{
|
|
$tenant = Tenant::create(['tenant_code' => 'BILL-A', 'tenant_name' => 'Billing Tenant']);
|
|
$owner = User::factory()->create(['access_level' => 'tenant_owner']);
|
|
$owner->userTenants()->create(['tenant_id' => $tenant->id, 'is_default' => true]);
|
|
$profile = app(BillingProfileService::class)->create([
|
|
'name' => 'Bulanan Reguler',
|
|
'invoice_day' => 1,
|
|
'send_day' => 2,
|
|
'warning_day' => 10,
|
|
'isolation_day' => 15,
|
|
'tax_type' => 'exclusive',
|
|
'tax_rate' => 11,
|
|
], $owner, $tenant->id);
|
|
$customer = Customer::create([
|
|
'tenant_id' => $tenant->id,
|
|
'customer_code' => 'CUST-BILL',
|
|
'name' => 'Customer Billing',
|
|
'status' => 'active',
|
|
'billing_profile_id' => $profile->id,
|
|
]);
|
|
$service = app(InvoiceService::class);
|
|
$invoice = $service->create([
|
|
'customer_id' => $customer->id,
|
|
'period_start' => now()->startOfMonth()->toDateString(),
|
|
'period_end' => now()->endOfMonth()->toDateString(),
|
|
'issue_date' => now()->subDays(20)->toDateString(),
|
|
'send_date' => now()->subDays(18)->toDateString(),
|
|
'warning_date' => now()->subDays(10)->toDateString(),
|
|
'isolation_date' => now()->subDay()->toDateString(),
|
|
'subtotal' => 100000,
|
|
], $owner, $tenant->id);
|
|
|
|
$this->assertSame('overdue', $invoice->status);
|
|
$this->assertSame('111000.00', $invoice->total);
|
|
$this->assertCount(1, $service->list('overdue', ['per_page' => 10], $owner, $tenant->id));
|
|
|
|
$paid = $service->pay($invoice, ['amount' => 111000, 'payment_method' => 'cash'], $owner);
|
|
|
|
$this->assertSame('paid', $paid->status);
|
|
$this->assertSame('paid', $paid->payment_status);
|
|
$this->assertSame('0.00', $paid->balance);
|
|
$this->assertCount(1, $service->list('paid', ['per_page' => 10], $owner, $tenant->id));
|
|
}
|
|
|
|
public function test_profile_and_invoice_lists_are_tenant_scoped(): void
|
|
{
|
|
$tenantA = Tenant::create(['tenant_code' => 'BILL-LA', 'tenant_name' => 'Billing A']);
|
|
$tenantB = Tenant::create(['tenant_code' => 'BILL-LB', 'tenant_name' => 'Billing B']);
|
|
$owner = User::factory()->create(['access_level' => 'tenant_owner']);
|
|
$owner->userTenants()->create(['tenant_id' => $tenantA->id, 'is_default' => true]);
|
|
$master = User::factory()->create(['is_master' => true, 'access_level' => 'master_admin']);
|
|
$service = app(BillingProfileService::class);
|
|
$base = ['invoice_day' => 1, 'send_day' => 2, 'warning_day' => 10, 'isolation_day' => 15, 'tax_type' => 'non_tax'];
|
|
$service->create([...$base, 'name' => 'Profile A'], $owner, $tenantA->id);
|
|
$service->create([...$base, 'name' => 'Profile B', 'tenant_id' => $tenantB->id], $master, null);
|
|
|
|
$result = $service->list(['per_page' => 100], $owner, $tenantA->id);
|
|
|
|
$this->assertSame(['Profile A'], $result->getCollection()->pluck('name')->all());
|
|
}
|
|
}
|