业绩明细:抖音负差额新增「实付已退款部分」备注(聚水潭退款单/取消子单金额≈差额时命中)
This commit is contained in:
parent
e883d262f0
commit
fba094ce26
@ -153,6 +153,35 @@ class Pages extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 「实付含已退款部分」的聚水潭证据 SQL(仅抖音负差额行计算,CASE 守卫保证其它行不触发子查询)。
|
||||
*
|
||||
* 退款单:经订单 o_id 关联(so_id 列没有索引,订单侧走 so_id 索引、退款单侧走 o_id 索引),
|
||||
* 只统计 SUCCESS 且非 Split 父单的叶子退款;分别取合计与单笔最大值。
|
||||
* 取消子单:同一单号下 ops_jst_orders 状态为 Cancelled 的买家实付合计。
|
||||
* 两表按 o_id / as_id 唯一(无跨代重复行),子查询保持扁平以避免 MariaDB 对 FROM 派生表引用外层的限制。
|
||||
*
|
||||
* @return array{guard:string, refund_sum:string, refund_max:string, cancelled_sum:string}
|
||||
*/
|
||||
private static function receiptRefundEvidenceSql(): array
|
||||
{
|
||||
$guard = "platform = '抖音' AND COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0)) < -0.005";
|
||||
$refundWhere = "o.so_id = store_receipt_order_match_rows.online_order_no
|
||||
AND rf.refund > 0 AND rf.shop_status LIKE '%SUCCESS%' AND COALESCE(rf.status, '') NOT LIKE '%Split%'";
|
||||
|
||||
return [
|
||||
'guard' => $guard,
|
||||
'refund_sum' => "(SELECT COALESCE(SUM(rf.refund), 0)
|
||||
FROM ops_jst_orders o JOIN ops_jst_return_refund_info rf ON rf.o_id = o.o_id
|
||||
WHERE {$refundWhere})",
|
||||
'refund_max' => "(SELECT COALESCE(MAX(rf.refund), 0)
|
||||
FROM ops_jst_orders o JOIN ops_jst_return_refund_info rf ON rf.o_id = o.o_id
|
||||
WHERE {$refundWhere})",
|
||||
'cancelled_sum' => "(SELECT COALESCE(SUM(o.buyer_paid_amount), 0) FROM ops_jst_orders o
|
||||
WHERE o.so_id = store_receipt_order_match_rows.online_order_no AND o.status = 'Cancelled')",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 「差额异常备注」原因(不落库):说明差额为什么产生,一行最多一个,按顺序取第一条命中。
|
||||
* 未匹配行 → 订单实付未匹配(细分原因见「未匹配原因」列);已匹配但基准金额=0 → 订单实付取数为0;
|
||||
@ -175,6 +204,16 @@ class Pages extends Controller
|
||||
$rules[$label . '未减优惠和冲减'] = "match_status = '已匹配' AND ABS(COALESCE($column, 0) - COALESCE(income_amount, 0)) < 0.005";
|
||||
$effective = 'COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0))';
|
||||
|
||||
// 抖音「实付含已退款部分」:负差额能在聚水潭退款单/取消子单金额里对上(≈差额)才标注。
|
||||
$refundEvidence = self::receiptRefundEvidenceSql();
|
||||
$differenceAbs = 'ABS(' . $effective . ')';
|
||||
$refundHit = static fn (string $amount): string => 'CASE WHEN ' . $amount . ' > 0.005 THEN ABS(' . $amount . ' - ' . $differenceAbs . ') < 0.02 ELSE 0 END';
|
||||
$rules['实付含已退款部分'] = 'CASE WHEN (' . $refundEvidence['guard'] . ') THEN ('
|
||||
. $refundHit($refundEvidence['refund_sum'])
|
||||
. ' OR ' . $refundHit($refundEvidence['refund_max'])
|
||||
. ' OR ' . $refundHit($refundEvidence['cancelled_sum'])
|
||||
. ') ELSE 0 END = 1';
|
||||
|
||||
$conditions = [];
|
||||
$seen = [];
|
||||
foreach ($rules as $label => $condition) {
|
||||
@ -223,6 +262,16 @@ class Pages extends Controller
|
||||
return $label . '未减优惠和冲减';
|
||||
}
|
||||
|
||||
// 抖音负差额:实付多出来的部分能在聚水潭退款单/取消子单金额里对上(≈差额)→「实付含已退款部分」。
|
||||
if (($row->platform ?? '') === '抖音' && $difference < 0) {
|
||||
$refunds = [$row->order_refund_sum ?? null, $row->order_refund_max ?? null, $row->order_cancelled_sum ?? null];
|
||||
foreach ($refunds as $refund) {
|
||||
if ($refund !== null && (float) $refund > 0.005 && abs((float) $refund - abs($difference)) < 0.02) {
|
||||
return '实付含已退款部分';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -869,7 +918,12 @@ class Pages extends Controller
|
||||
|
||||
$itemsQuery = $base();
|
||||
$applyFilters($itemsQuery);
|
||||
$refundEvidence = self::receiptRefundEvidenceSql();
|
||||
$items = $itemsQuery
|
||||
->selectRaw('*')
|
||||
->selectRaw('CASE WHEN (' . $refundEvidence['guard'] . ') THEN ' . $refundEvidence['refund_sum'] . ' END AS order_refund_sum')
|
||||
->selectRaw('CASE WHEN (' . $refundEvidence['guard'] . ') THEN ' . $refundEvidence['refund_max'] . ' END AS order_refund_max')
|
||||
->selectRaw('CASE WHEN (' . $refundEvidence['guard'] . ') THEN ' . $refundEvidence['cancelled_sum'] . ' END AS order_cancelled_sum')
|
||||
->orderBy('occurred_date')
|
||||
->orderBy('store_name')
|
||||
->orderBy('online_order_no')
|
||||
@ -1241,6 +1295,14 @@ class Pages extends Controller
|
||||
$this->applyReceiptRemarkFilter($query, $remarkValues);
|
||||
}
|
||||
|
||||
// 「实付含已退款部分」判定所需证据列(与页面同一口径;仅抖音负差额行会真正计算子查询)。
|
||||
$refundEvidence = self::receiptRefundEvidenceSql();
|
||||
$query
|
||||
->selectRaw('*')
|
||||
->selectRaw('CASE WHEN (' . $refundEvidence['guard'] . ') THEN ' . $refundEvidence['refund_sum'] . ' END AS order_refund_sum')
|
||||
->selectRaw('CASE WHEN (' . $refundEvidence['guard'] . ') THEN ' . $refundEvidence['refund_max'] . ' END AS order_refund_max')
|
||||
->selectRaw('CASE WHEN (' . $refundEvidence['guard'] . ') THEN ' . $refundEvidence['cancelled_sum'] . ' END AS order_cancelled_sum');
|
||||
|
||||
$selected = array_values(array_intersect(
|
||||
array_filter(explode(',', (string) $request->query('columns', ''))),
|
||||
array_keys($map),
|
||||
|
||||
@ -807,7 +807,7 @@ $navigation = [
|
||||
'directory' => [
|
||||
'icon' => 'receipt_long',
|
||||
'status' => '共享镜像',
|
||||
'description' => '覆盖店铺收款账户账单各平台页签(总账备注=订单收入),按「店铺 + 订单号」匹配订单侧商品金额与订单实付金额;一行 = 一个店铺的一个订单,商品金额只挂一次。「商品金额」只取主单(拆单子单不参与,整单没有主单时退化为取全部行),并排除虚拟条码(X0000x:信誉订单 / 虚拟订单)明细行;「订单实付金额」取订单级实付(拆单取主单)再减去虚拟条码行实付。「优惠金额」「冲减金额」另取总账备注=优惠收入 / 冲减收入的账单金额,不计入收入金额;「退款金额」另取总账备注=退款的账单金额,只单独列示,不计入收入金额、也不参与差额;「种菜金额」是订单号在种菜明细表或聚水潭订单标签明细(是否种菜订单=是)任意一边出现过时,该订单的收入金额(两个条件是或的关系),只是收入金额里的一部分,不参与差额;差额=(收入金额+优惠金额+冲减金额)−订单实付金额,匹配状态与差额异常备注同样按订单实付金额判定,未匹配到订单实付金额的行按订单实付金额=0 计入差额,只反映真正对不上的部分。挂不到订单行的优惠/冲减会补成一行(收入/商品留空)。「差额异常备注」只说明差额为什么产生,按顺序自动判定:订单实付未匹配(未匹配到订单实付金额,具体原因看「未匹配原因」列);订单实付取数为0(种菜)(订单实付=0 且是种菜单)、订单实付取数为0(订单实付=0 但不是种菜单)、订单实付未减冲减(订单实付=收入+优惠 → 差额=冲减金额)、订单实付未减优惠(订单实付=收入+冲减 → 差额=优惠金额)、订单实付未减优惠和冲减(订单实付=收入 → 差额=优惠+冲减);都不满足则留空。「未匹配原因」单独一列,取值:账单无单号 / 单号格式异常 / 订单表无此单 / 订单无实付金额 / 无收款账单。',
|
||||
'description' => '覆盖店铺收款账户账单各平台页签(总账备注=订单收入),按「店铺 + 订单号」匹配订单侧商品金额与订单实付金额;一行 = 一个店铺的一个订单,商品金额只挂一次。「商品金额」只取主单(拆单子单不参与,整单没有主单时退化为取全部行),并排除虚拟条码(X0000x:信誉订单 / 虚拟订单)明细行;「订单实付金额」取订单级实付(拆单取主单)再减去虚拟条码行实付。「优惠金额」「冲减金额」另取总账备注=优惠收入 / 冲减收入的账单金额,不计入收入金额;「退款金额」另取总账备注=退款的账单金额,只单独列示,不计入收入金额、也不参与差额;「种菜金额」是订单号在种菜明细表或聚水潭订单标签明细(是否种菜订单=是)任意一边出现过时,该订单的收入金额(两个条件是或的关系),只是收入金额里的一部分,不参与差额;差额=(收入金额+优惠金额+冲减金额)−订单实付金额,匹配状态与差额异常备注同样按订单实付金额判定,未匹配到订单实付金额的行按订单实付金额=0 计入差额,只反映真正对不上的部分。挂不到订单行的优惠/冲减会补成一行(收入/商品留空)。「差额异常备注」只说明差额为什么产生,按顺序自动判定:订单实付未匹配(未匹配到订单实付金额,具体原因看「未匹配原因」列);订单实付取数为0(种菜)(订单实付=0 且是种菜单)、订单实付取数为0(订单实付=0 但不是种菜单)、订单实付未减冲减(订单实付=收入+优惠 → 差额=冲减金额)、订单实付未减优惠(订单实付=收入+冲减 → 差额=优惠金额)、订单实付未减优惠和冲减(订单实付=收入 → 差额=优惠+冲减)、实付含已退款部分(仅抖音负差额:聚水潭退款单/取消子单金额≈差额对上才标注);都不满足则留空。「未匹配原因」单独一列,取值:账单无单号 / 单号格式异常 / 订单表无此单 / 订单无实付金额 / 无收款账单。',
|
||||
'empty' => '店铺收款匹配订单明细尚未同步,请先执行 store-receipt:order-match:sync。',
|
||||
'fields' => [
|
||||
['name' => 'platform', 'label' => '平台'],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user