169 lines
5.0 KiB
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);
|
|
});
|