inspiren-sem-tool/tests/Feature/ClientLatestRemainingAmountTest.php

169 lines
5.0 KiB
PHP

<?php
use App\Models\BillingItemType;
use App\Models\Client;
use App\Models\ClientInvoice;
use App\Models\ClientInvoicePayment;
use App\Models\ClientInvoicePaymentItem;
use App\Services\ClientInvoicePaymentSyncService;
use Illuminate\Support\Carbon;
function createRemainingAmountPaymentItem(
ClientInvoice $invoice,
int $billingItemTypeId,
array $attributes = [],
): ClientInvoicePaymentItem {
$payment = ClientInvoicePayment::query()->create([
'client_invoice_id' => $invoice->id,
]);
return ClientInvoicePaymentItem::query()->create(array_merge([
'client_invoice_payment_id' => $payment->id,
'billing_item_types_id' => $billingItemTypeId,
], $attributes));
}
beforeEach(function () {
BillingItemType::query()->insert([
[
'id' => 1,
'name' => ClientInvoicePaymentSyncService::MEDIA_SEARCH_NAME,
'nett_contribution' => true,
'fee_type' => 'Media',
],
[
'id' => 2,
'name' => ClientInvoicePaymentSyncService::MANAGEMENT_SEARCH_NAME,
'nett_contribution' => false,
'fee_type' => 'Management',
],
]);
});
afterEach(function () {
Carbon::setTestNow();
});
test('it treats google search management spending on credit card invoices as credit card media spend', function () {
$client = Client::factory()->create();
$payToUsInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-PAY-TO-US',
'is_credit_card' => false,
]);
createRemainingAmountPaymentItem($payToUsInvoice, 1, [
'final_net_amount' => 200,
'spending' => 0,
'is_creditcard' => false,
]);
$creditCardInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-CREDIT-CARD',
'is_credit_card' => true,
]);
createRemainingAmountPaymentItem($creditCardInvoice, 2, [
'spending' => 125,
'is_creditcard' => false,
]);
expect($client->latestRemainingAmount())->toBe('200.00');
});
test('it keeps google search management spending billable on non credit card invoices', function () {
$client = Client::factory()->create();
$invoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-PAY-TO-US',
'is_credit_card' => false,
]);
createRemainingAmountPaymentItem($invoice, 1, [
'final_net_amount' => 200,
'spending' => 0,
'is_creditcard' => false,
]);
createRemainingAmountPaymentItem($invoice, 2, [
'spending' => 125,
'is_creditcard' => false,
]);
expect($client->latestRemainingAmount())->toBe('75.00');
});
test('it allows negative remaining amount when billable spending exceeds invoice net amount', function () {
$client = Client::factory()->create();
$invoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-OVERSPEND',
'is_credit_card' => false,
]);
createRemainingAmountPaymentItem($invoice, 1, [
'final_net_amount' => 100,
'spending' => 175,
'is_creditcard' => false,
]);
expect($client->latestRemainingAmount())->toBe('-75.00');
});
test('it uses linked invoice payment dates when they are the latest range', function () {
Carbon::setTestNow('2026-06-25 10:00:00');
$client = Client::factory()->create();
$olderInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-OLDER',
]);
createRemainingAmountPaymentItem($olderInvoice, 1, [
'start_date' => '2026-06-01',
'end_date' => '2026-06-30',
]);
$linkedInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-LINKED-SOURCE',
]);
createRemainingAmountPaymentItem($linkedInvoice, 2, [
'start_date' => '2026-08-01',
'end_date' => '2026-08-31',
]);
$linkedPaymentInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-LINKED-PAYMENT',
'linked_invoice_id' => $linkedInvoice->id,
]);
createRemainingAmountPaymentItem($linkedPaymentInvoice, 2, [
'start_date' => '2026-09-01',
'end_date' => '2026-09-30',
]);
expect($client->latestPaymentDateRange())->toBe([
'start_date' => '2026-09-01',
'end_date' => '2026-09-30',
])->and($client->latestRemainingDays())->toBe(29);
});
test('it counts remaining days from today within the latest range', function () {
Carbon::setTestNow('2026-06-25 10:00:00');
$client = Client::factory()->create();
$invoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-CURRENT',
]);
createRemainingAmountPaymentItem($invoice, 1, [
'start_date' => '2026-06-01',
'end_date' => '2026-06-30',
]);
expect($client->latestRemainingDays())->toBe(5);
});