114 lines
4.5 KiB
PHP
114 lines
4.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature\Api\Admin\Customer;
|
|
|
|
use App\Enums\Invoice\InvoiceStatus;
|
|
use App\Models\Customer;
|
|
use App\Models\Invoice;
|
|
use App\Models\Product;
|
|
use App\Models\Transaction;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Spatie\Permission\Models\Role;
|
|
use Tests\TestCase;
|
|
|
|
class CreateServicePaymentStatusTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private User $admin;
|
|
|
|
private Customer $customer;
|
|
|
|
private Product $product;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
Role::firstOrCreate(['name' => 'Full Administrator', 'guard_name' => 'admin']);
|
|
$this->admin = User::factory()->create();
|
|
$this->admin->assignRole('Full Administrator');
|
|
$this->customer = Customer::factory()->create(['total' => 1_000_000]);
|
|
$this->product = Product::factory()->create(['product_type' => 'hosting']);
|
|
}
|
|
|
|
private function createService(array $data)
|
|
{
|
|
return $this->actingAs($this->admin, 'admin')->postJson(
|
|
"/api/v1/administrator/customers/{$this->customer->uuid}/services",
|
|
['product_id' => $this->product->id, 'server_name' => 'site.vn', 'price' => 500_000, ...$data],
|
|
);
|
|
}
|
|
|
|
public function test_paid_in_full_marks_invoice_paid(): void
|
|
{
|
|
$this->createService(['payment_status' => 'paid', 'payment_method' => 'balance'])->assertCreated();
|
|
|
|
$invoice = Invoice::sole();
|
|
$this->assertSame(InvoiceStatus::PAID->value, (int) $invoice->status);
|
|
$this->assertSame(500_000, (int) $invoice->amount_paid);
|
|
$this->assertSame(500_000, (int) $this->customer->fresh()->total);
|
|
}
|
|
|
|
public function test_partial_payment_keeps_invoice_unpaid_with_prepaid_amount(): void
|
|
{
|
|
$this->createService(['payment_status' => 'partial', 'payment_method' => 'balance', 'amount_paid' => 200_000])->assertCreated();
|
|
|
|
$invoice = Invoice::sole();
|
|
$this->assertSame(InvoiceStatus::UNPAID->value, (int) $invoice->status);
|
|
$this->assertSame(500_000, (int) $invoice->total);
|
|
$this->assertSame(200_000, (int) $invoice->amount_paid);
|
|
$this->assertSame(200_000, (int) Transaction::sole()->amount);
|
|
$this->assertSame(800_000, (int) $this->customer->fresh()->total);
|
|
}
|
|
|
|
public function test_service_detail_lists_every_payment_installment_of_an_invoice(): void
|
|
{
|
|
$serviceId = $this->createService(['payment_status' => 'partial', 'payment_method' => 'balance', 'amount_paid' => 200_000])
|
|
->assertCreated()
|
|
->json('data.id');
|
|
$invoice = Invoice::sole();
|
|
$admin = $this->actingAs($this->admin, 'admin');
|
|
|
|
$admin->postJson("/api/v1/administrator/invoices/{$invoice->id}/paid", ['received_amount' => 100_000])->assertOk();
|
|
$admin->postJson("/api/v1/administrator/invoices/{$invoice->id}/paid", ['note' => 'Đợt cuối'])->assertOk();
|
|
|
|
$payments = $admin->getJson("/api/v1/administrator/services/{$serviceId}")
|
|
->assertOk()
|
|
->json('data.linked_invoices.0.payments');
|
|
|
|
$this->assertSame([200_000, 100_000, 200_000], array_column($payments, 'amount'));
|
|
$this->assertSame(InvoiceStatus::PAID->value, (int) $invoice->fresh()->status);
|
|
}
|
|
|
|
public function test_decimal_amounts_are_rounded_to_whole_dong(): void
|
|
{
|
|
$this->createService(['price' => 731.33, 'payment_status' => 'partial', 'payment_method' => 'balance', 'amount_paid' => 400.6])->assertCreated();
|
|
|
|
$invoice = Invoice::sole();
|
|
$this->assertSame(731, (int) $invoice->total);
|
|
$this->assertSame(401, (int) $invoice->amount_paid);
|
|
}
|
|
|
|
public function test_partial_payment_must_be_less_than_price(): void
|
|
{
|
|
$this->createService(['payment_status' => 'partial', 'payment_method' => 'balance', 'amount_paid' => 500_000])->assertStatus(422);
|
|
$this->createService(['payment_status' => 'partial', 'payment_method' => 'balance'])->assertStatus(422);
|
|
$this->assertSame(0, Invoice::count());
|
|
}
|
|
|
|
public function test_unpaid_creates_unpaid_invoice_without_transaction(): void
|
|
{
|
|
$this->createService(['payment_status' => 'unpaid'])->assertCreated();
|
|
|
|
$invoice = Invoice::sole();
|
|
$this->assertSame(InvoiceStatus::UNPAID->value, (int) $invoice->status);
|
|
$this->assertSame(0, (int) $invoice->amount_paid);
|
|
$this->assertSame(0, Transaction::count());
|
|
$this->assertSame(1_000_000, (int) $this->customer->fresh()->total);
|
|
}
|
|
}
|