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

136 lines
5.2 KiB
PHP

<?php
use App\Models\BillingItemType;
use App\Models\Client;
use App\Models\ClientInvoice;
use App\Models\ClientInvoicePayment;
use App\Models\ClientInvoicePaymentItem;
beforeEach(function () {
BillingItemType::query()->insert([
['id' => 1, 'name' => 'Media'],
['id' => 2, 'name' => 'Management'],
]);
});
test('it moves media date range and spending to management items on distinct referenced invoices', function () {
$client = Client::factory()->create();
$parentInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-PARENT',
]);
ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-LINKED-1',
'linked_invoice_id' => $parentInvoice->id,
]);
$secondLinkedInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-LINKED-2',
'linked_invoice_id' => $parentInvoice->id,
]);
$unlinkedInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-UNLINKED',
]);
$parentPayment = ClientInvoicePayment::query()->create([
'client_invoice_id' => $parentInvoice->id,
'payment_no' => 'P1',
]);
$childPayment = ClientInvoicePayment::query()->create([
'client_invoice_id' => $secondLinkedInvoice->id,
'payment_no' => 'P2',
]);
$unlinkedPayment = ClientInvoicePayment::query()->create([
'client_invoice_id' => $unlinkedInvoice->id,
'payment_no' => 'P3',
]);
$parentMediaItem = ClientInvoicePaymentItem::query()->create([
'client_invoice_payment_id' => $parentPayment->id,
'billing_item_types_id' => 1,
'start_date' => '2026-06-01',
'end_date' => '2026-06-30',
'spending' => 125.50,
]);
$parentManagementItem = ClientInvoicePaymentItem::query()->create([
'client_invoice_payment_id' => $parentPayment->id,
'billing_item_types_id' => 2,
'spending' => 10,
]);
$childMediaItem = ClientInvoicePaymentItem::query()->create([
'client_invoice_payment_id' => $childPayment->id,
'billing_item_types_id' => 1,
'start_date' => '2026-06-15',
'end_date' => '2026-06-20',
'spending' => 50,
]);
$childManagementItem = ClientInvoicePaymentItem::query()->create([
'client_invoice_payment_id' => $childPayment->id,
'billing_item_types_id' => 2,
]);
$unlinkedMediaItem = ClientInvoicePaymentItem::query()->create([
'client_invoice_payment_id' => $unlinkedPayment->id,
'billing_item_types_id' => 1,
'start_date' => '2026-07-01',
'end_date' => '2026-07-31',
'spending' => 99,
]);
$unlinkedManagementItem = ClientInvoicePaymentItem::query()->create([
'client_invoice_payment_id' => $unlinkedPayment->id,
'billing_item_types_id' => 2,
]);
$this->artisan('customer:repair-linked-invoice-payment-items')
->expectsOutputToContain('Done. 1 media item merged into management, 1 media item removed, 0 skipped.')
->assertSuccessful();
expect(ClientInvoicePaymentItem::query()->whereKey($parentMediaItem->id)->exists())->toBeFalse()
->and($parentManagementItem->fresh()->start_date->toDateString())->toBe('2026-06-01')
->and($parentManagementItem->fresh()->end_date->toDateString())->toBe('2026-06-30')
->and((float) $parentManagementItem->fresh()->spending)->toBe(135.50)
->and($childMediaItem->fresh())->not->toBeNull()
->and($childManagementItem->fresh()->start_date)->toBeNull()
->and($unlinkedMediaItem->fresh())->not->toBeNull()
->and($unlinkedManagementItem->fresh()->start_date)->toBeNull()
->and((float) $unlinkedManagementItem->fresh()->spending)->toBe(0.0);
});
test('dry run does not update or delete items', function () {
$client = Client::factory()->create();
$parentInvoice = ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-PARENT',
]);
ClientInvoice::query()->forceCreate([
'client_id' => $client->id,
'invoice_no' => 'INV-LINKED',
'linked_invoice_id' => $parentInvoice->id,
]);
$payment = ClientInvoicePayment::query()->create([
'client_invoice_id' => $parentInvoice->id,
]);
$mediaItem = ClientInvoicePaymentItem::query()->create([
'client_invoice_payment_id' => $payment->id,
'billing_item_types_id' => 1,
'start_date' => '2026-06-01',
'end_date' => '2026-06-30',
'spending' => 125.50,
]);
$managementItem = ClientInvoicePaymentItem::query()->create([
'client_invoice_payment_id' => $payment->id,
'billing_item_types_id' => 2,
]);
$this->artisan('customer:repair-linked-invoice-payment-items', ['--dry-run' => true])
->expectsOutputToContain('Done. 1 media item merged into management, 1 media item removed, 0 skipped.')
->assertSuccessful();
expect($mediaItem->fresh())->not->toBeNull()
->and($managementItem->fresh()->start_date)->toBeNull()
->and($managementItem->fresh()->end_date)->toBeNull()
->and((float) $managementItem->fresh()->spending)->toBe(0.0);
});