CaiWuXiTong/modules/EcommerceFinance/Jobs/MatchSettlementLines.php
WuYongJie 2b6c4030e5
Some checks failed
Tests / PHP 8.1 (push) Has been cancelled
Tests / PHP 8.2 (push) Has been cancelled
Tests / PHP 8.3 (push) Has been cancelled
chore: 补充财务与支付模块源码
2026-07-20 18:40:05 +08:00

74 lines
2.4 KiB
PHP

<?php
namespace Modules\EcommerceFinance\Jobs;
use App\Abstracts\JobShouldQueue;
use Modules\EcommerceFinance\Models\Order;
use Modules\EcommerceFinance\Models\ReconciliationMatch;
use Modules\EcommerceFinance\Models\Settlement;
use Modules\EcommerceFinance\Models\SettlementLine;
class MatchSettlementLines extends JobShouldQueue
{
public function __construct(private readonly int $settlementId)
{
}
public function handle(): void
{
$settlement = Settlement::withoutGlobalScopes()->findOrFail($this->settlementId);
$lines = SettlementLine::withoutGlobalScopes()->where('settlement_id', $settlement->id)->get();
foreach ($lines as $line) {
$order = null;
$status = 'ignored';
$matchedAmount = '0';
if (! empty($line->external_order_id)) {
$order = Order::withoutGlobalScopes()
->where('store_id', $settlement->store_id)
->where('external_order_id', $line->external_order_id)
->first();
if (! $order) {
$status = 'unmatched';
} else {
$matchedAmount = $line->amount;
$status = $this->amountMatches($line->amount, $this->expectedAmount($order, $line->line_type))
? 'auto_matched'
: 'partial_matched';
}
}
ReconciliationMatch::withoutGlobalScopes()->updateOrCreate(
['settlement_line_id' => $line->id, 'order_id' => $order?->id],
[
'company_id' => $settlement->company_id,
'match_type' => $status === 'auto_matched' ? 'rule' : 'exception',
'matched_amount' => $matchedAmount,
'status' => $status,
'rule_version' => '1.0',
]
);
}
}
private function expectedAmount(Order $order, string $lineType): string
{
if ($lineType === 'refund') {
return $order->refunded_amount;
}
return bcsub(
bcadd($order->buyer_paid_amount, $order->platform_subsidy_amount, 6),
$order->refunded_amount,
6
);
}
private function amountMatches(string $actual, string $expected): bool
{
return bccomp(ltrim($actual, '-'), ltrim($expected, '-'), 6) === 0;
}
}