CaiWuXiTong/tests/Unit/EcommerceFinance/DingProcessPaymentLineAllocatorTest.php

196 lines
6.6 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Illuminate\Support\Carbon;
use Modules\EcommerceFinance\Services\DingProcessPaymentLineAllocator;
use Tests\TestCase;
class DingProcessPaymentLineAllocatorTest extends TestCase
{
public function test_it_splits_a_multi_line_payment_across_referenced_details(): void
{
$rows = (new DingProcessPaymentLineAllocator())->allocate(
[
['business_id' => 'approval-2', 'line_no' => 1, 'amount' => '100.00'],
['business_id' => 'approval-2', 'line_no' => 2, 'amount' => '200.00'],
],
[[
'business_id' => 'approval-2',
'process_instance_id' => 'process-2',
'payment_no' => 1,
'sequence_spec' => '1-2',
'amount' => '300.00',
'paid_at' => '2026-10-15 00:00',
]],
'personal_permission',
Carbon::parse('2026-11-02 12:00:00'),
);
$this->assertSame(
[[1, 100.0], [2, 200.0]],
array_map(
static fn (array $row): array => [
(int) $row['line_no'],
(float) $row['amount'],
],
$rows,
),
);
}
public function test_it_allocates_partial_payments_to_the_correct_months(): void
{
Carbon::setTestNow('2026-11-02 12:00:00');
try {
$rows = (new DingProcessPaymentLineAllocator())->allocate(
[
['business_id' => 'approval-1', 'line_no' => 1, 'amount' => '100.00'],
['business_id' => 'approval-1', 'line_no' => 2, 'amount' => '50.00'],
],
[
[
'business_id' => 'approval-1',
'process_instance_id' => 'process-1',
'payment_no' => 1,
'sequence_spec' => '1',
'amount' => '40.00',
'paid_at' => '2026-09-30 00:00',
],
[
'business_id' => 'approval-1',
'process_instance_id' => 'process-1',
'payment_no' => 2,
'sequence_spec' => '1',
'amount' => '60.00',
'paid_at' => '2026-10-15 00:00',
],
[
'business_id' => 'approval-1',
'process_instance_id' => 'process-1',
'payment_no' => 3,
'sequence_spec' => '2',
'amount' => '50.00',
'paid_at' => '2026-10-20 00:00',
],
],
'personal_permission',
Carbon::parse('2026-11-02 12:00:00'),
);
$this->assertSame(
[
['2026-09', '1', 40.0],
['2026-10', '1', 60.0],
['2026-10', '2', 50.0],
],
array_map(
static fn (array $row): array => [
$row['paid_month'],
(string) $row['line_no'],
(float) $row['amount'],
],
$rows,
),
);
} finally {
Carbon::setTestNow();
}
}
public function test_it_allocates_an_invalid_sequence_to_the_unique_matching_detail(): void
{
$rows = (new DingProcessPaymentLineAllocator())->allocate(
[
['business_id' => 'approval-3', 'line_no' => 1, 'amount' => '100.00'],
['business_id' => 'approval-3', 'line_no' => 2, 'amount' => '200.00'],
],
[[
'business_id' => 'approval-3',
'process_instance_id' => 'process-3',
'payment_no' => 1,
'sequence_spec' => '9',
'amount' => '200.00',
'paid_at' => '2026-10-15 00:00',
]],
'personal_permission',
Carbon::parse('2026-11-02 12:00:00'),
);
$this->assertSame(
[[2, 200.0]],
array_map(
static fn (array $row): array => [
(int) $row['line_no'],
(float) $row['amount'],
],
$rows,
),
);
}
public function test_it_allocates_a_payment_without_a_sequence_across_all_details(): void
{
$rows = (new DingProcessPaymentLineAllocator())->allocate(
[
['business_id' => 'approval-4', 'line_no' => 1, 'amount' => '100.00'],
['business_id' => 'approval-4', 'line_no' => 2, 'amount' => '200.00'],
],
[[
'business_id' => 'approval-4',
'process_instance_id' => 'process-4',
'payment_no' => 1,
'sequence_spec' => '',
'amount' => '300.00',
'paid_at' => '2026-10-15 00:00',
]],
'personal_permission',
Carbon::parse('2026-11-02 12:00:00'),
);
$this->assertSame(
[[1, 100.0], [2, 200.0]],
array_map(
static fn (array $row): array => [
(int) $row['line_no'],
(float) $row['amount'],
],
$rows,
),
);
}
public function test_it_does_not_drop_a_payment_when_the_sequence_and_amount_do_not_match(): void
{
$rows = (new DingProcessPaymentLineAllocator())->allocate(
[
['business_id' => 'approval-5', 'line_no' => 1, 'amount' => '100.00'],
['business_id' => 'approval-5', 'line_no' => 2, 'amount' => '200.00'],
],
[[
'business_id' => 'approval-5',
'process_instance_id' => 'process-5',
'payment_no' => 1,
'sequence_spec' => '9',
'amount' => '150.00',
'paid_at' => '2026-10-15 00:00',
]],
'personal_permission',
Carbon::parse('2026-11-02 12:00:00'),
);
$this->assertSame(
[[1, 50.0], [2, 100.0]],
array_map(
static fn (array $row): array => [
(int) $row['line_no'],
(float) $row['amount'],
],
$rows,
),
);
$this->assertSame(150.0, array_sum(array_column($rows, 'amount')));
}
}