业绩明细:差额判定改为「原因优先 → 实收/应付口径兜底 → 待核实」;口径命中不再抹差额、页面与合计/筛选/联动同一套判定

This commit is contained in:
yueyang 2026-10-15 17:50:55 +08:00
parent 564eb1ef08
commit 173ca7c2ec
2 changed files with 38 additions and 9 deletions

View File

@ -745,6 +745,9 @@ class SyncStoreReceiptOrderMatches extends Command
// 差额归零、订单实付列显示实收金额。用于京东这类「账单收款=卖家实收」的平台,
// 避免把口径差当成对不上的差额。
if ($basis === 'paid' && $difference !== null && abs($difference) > 0.005) {
// 原因优先:这里只登记「口径能对上」的标识,不动差额(差额与原因由页面按
// 「先备注规则、后口径兜底」的顺序判定),避免把有明确原因的行悄悄抹平。
{
[$altStatus, $altAmount] = $this->matchOrderSide(
$core,
(string) $group['shop_key'],
@ -777,16 +780,11 @@ class SyncStoreReceiptOrderMatches extends Command
if ($altMatched && $altValue > 0.005
&& abs($income + $promoAmount - $altValue) <= 0.02) {
$paidAmount = round((float) $altAmount, 2);
$basisAmount = $paidAmount;
$difference = 0.0;
$remark = self::REMARK_SELLER_INCOME_BASIS;
} elseif ($payAmount !== null && abs($income + $promoAmount - $payAmount) <= 0.02) {
$paidAmount = round($payAmount, 2);
$basisAmount = $paidAmount;
$difference = 0.0;
$remark = self::REMARK_PAYABLE_BASIS;
}
}
}
if ($productAmount !== null) {
$goodsTotal += $productAmount;

View File

@ -362,6 +362,22 @@ class Pages extends Controller
}
/** 单行的「差额异常备注」(与筛选条件同一套口径,页面与导出共用)。 */
/**
* 页面口径的「有效差额」SQL:口径兜底行(备注为空、但能对上实收/应付)按 0 计。
* 合计、差额筛选、联动计数共用,保证三个地方的数字一致。
*/
private static function receiptEffectiveDifferenceSql(): string
{
$ruleUnion = '(' . implode(' OR ', array_map(
static fn (string $condition): string => '(' . $condition . ')',
self::receiptDifferenceRemarkConditions()
)) . ')';
return "CASE WHEN remark IN ('订单实付按卖家实收核对','订单实付按应付/已付核对')"
. " AND NOT COALESCE({$ruleUnion}, 0) THEN 0"
. ' ELSE COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0)) END';
}
private static function receiptDifferenceRemark(object $row): ?string
{
$basis = self::differenceBasis();
@ -463,6 +479,13 @@ class Pages extends Controller
}
}
// 原因优先:上面的规则都没命中时,如果这行的口径(卖家实收 / 应付已付)能对上账单,
// 就按口径兜底——差额按 0 展示、口径标识在「匹配原因」列,不再当异常。
$rawRemark = trim((string) ($row->remark ?? ''));
if (in_array($rawRemark, ['订单实付按卖家实收核对', '订单实付按应付/已付核对'], true)) {
return null;
}
// 有差额但没命中任何已知原因:标「差额待核实」,页面上不再出现"有差额但备注空白"的行。
return '差额待核实';
}
@ -1036,6 +1059,8 @@ class Pages extends Controller
// 计数与合计合并为一次全表扫描:重筛选项(如按备注筛选)下少一次全表重算。
$aggQuery = $base();
$applyFilters($aggQuery);
// 口径兜底行(备注为空、口径对上)的差额按 0 计——与页面行展示、差额筛选同一套判定。
$differenceExpr = self::receiptEffectiveDifferenceSql();
$agg = $aggQuery->selectRaw("
COUNT(*) as total,
SUM(payment_count) as payments,
@ -1046,7 +1071,7 @@ class Pages extends Controller
SUM(planting_amount) as planting_total,
SUM(product_amount) as goods_total,
SUM(paid_amount) as paid_total,
SUM(COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0))) as difference_total,
SUM({$differenceExpr}) as difference_total,
SUM(CASE WHEN payment_count > 1 THEN 1 ELSE 0 END) as multi_pay,
SUM(CASE WHEN income_amount = 0 THEN 1 ELSE 0 END) as zero_income,
SUM(CASE WHEN match_status = '已匹配' THEN 1 ELSE 0 END) as matched,
@ -1148,6 +1173,12 @@ class Pages extends Controller
);
}
// 口径兜底(原因优先之后):备注为空但带口径标识 → 差额按 0 展示。
if ($row->remark === null
&& in_array($rawRemark, ['订单实付按卖家实收核对', '订单实付按应付/已付核对'], true)) {
$row->difference = 0.0;
}
return $row;
});
@ -1226,7 +1257,7 @@ class Pages extends Controller
if ($has === $none) {
return;
}
$effective = 'COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0))';
$effective = self::receiptEffectiveDifferenceSql();
$query->whereRaw($has ? 'ABS(' . $effective . ') > 0.005' : 'ABS(' . $effective . ') <= 0.005');
}
@ -1261,7 +1292,7 @@ class Pages extends Controller
$query->where('online_order_no', 'like', '%' . addcslashes($orderNo, '%_\\') . '%');
}
$effective = 'COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0))';
$effective = self::receiptEffectiveDifferenceSql();
$row = $query->selectRaw('SUM(CASE WHEN ABS(' . $effective . ') > 0.005 THEN 1 ELSE 0 END) as has_diff, '
. 'SUM(CASE WHEN ABS(' . $effective . ') <= 0.005 THEN 1 ELSE 0 END) as none_diff')->first();