196 lines
6.6 KiB
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')));
|
|
}
|
|
}
|