业绩明细:新增「退款金额」列,按总账备注=退款取数
- 新增列「退款金额」:店铺收款账户账单里总账备注=退款的金额(收入侧 − 支出侧), 与优惠金额/冲减金额同一口径,单独列示、不参与差额计算;统计卡、导出字段、 字段结构说明同步补充 - 同步命令支持账单表的 expense 列(京东账单/京喜账单/京东网银钱包/抖音用 expense, 淘系/拼多多/得物用 expense_amount),此前只认 expense_amount, 导致这些平台支出侧的退款、扣回金额被当成 0 - 重建后自检改为「本月账单确有优惠/冲减/退款行、但三列一行都没写」才报错, 并把退款金额纳入判定,避免无数据月份误报 - 新增迁移:store_receipt_order_match_rows.refund_amount
This commit is contained in:
parent
153b823ab8
commit
107c883eb2
@ -123,6 +123,11 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
'冲减收入',
|
||||
];
|
||||
|
||||
/** 「退款金额」列口径:账单的总账备注命中以下取值,单独列示,不参与收入金额与差额计算。 */
|
||||
private const REFUND_REMARKS = [
|
||||
'退款',
|
||||
];
|
||||
|
||||
private const TARGET_TABLE = 'store_receipt_order_match_rows';
|
||||
|
||||
private const STATUS_MATCHED = '已匹配';
|
||||
@ -205,11 +210,13 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$baseGroups = $this->ledgerRemarkGroups($platform);
|
||||
$discountGroups = $this->ledgerRemarkGroups($platform, self::DISCOUNT_REMARKS);
|
||||
$offsetGroups = $this->ledgerRemarkGroups($platform, self::OFFSET_REMARKS);
|
||||
$refundGroups = $this->ledgerRemarkGroups($platform, self::REFUND_REMARKS);
|
||||
// 总账备注现在优先取科目映射表的财务备注,因此这两列的候选账单项目
|
||||
// 也要按科目映射表补一遍,否则「优惠收入 / 冲减收入」永远取不到项目。
|
||||
// 也要按科目映射表补一遍,否则「优惠收入 / 冲减收入 / 退款」永远取不到项目。
|
||||
$promoItems = array_values(array_unique(array_merge(
|
||||
$this->accountMappingItems($platform, self::DISCOUNT_REMARKS),
|
||||
$this->accountMappingItems($platform, self::OFFSET_REMARKS),
|
||||
$this->accountMappingItems($platform, self::REFUND_REMARKS),
|
||||
)));
|
||||
// 微信账户页签的账单项目带「wx」前缀(wx限时红包代商家垫付扣回 等),
|
||||
// 科目映射表用的是不带前缀的名字,这里两种写法都带上。
|
||||
@ -220,14 +227,22 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
return self::FAILURE;
|
||||
}
|
||||
$this->info('总账备注命中平台分组:' . count($baseGroups) . ' 组');
|
||||
if ($discountGroups === [] && $offsetGroups === [] && $promoItems === []) {
|
||||
$this->warn('「优惠收入」「冲减收入」在科目映射表与总账备注映射里都没有对应账单项目,两列将全部为空。');
|
||||
if ($discountGroups === [] && $offsetGroups === [] && $refundGroups === [] && $promoItems === []) {
|
||||
$this->warn('「优惠收入」「冲减收入」「退款」在科目映射表与总账备注映射里都没有对应账单项目,三列将全部为空。');
|
||||
}
|
||||
|
||||
$select = ['store_name', 'bill_item', $orderColumn, $timeColumn, $amountColumn];
|
||||
// 「冲减金额」按行金额(收入侧 − 支出侧)取数,账单表有支出列时一并取出。
|
||||
// 淘系/拼多多/得物的支出列叫 expense_amount,京东系列(京东账单/京喜/京东网银钱包)与抖音叫 expense,
|
||||
// 两种写法都要认,否则支出侧的退款/扣回会被当成 0。
|
||||
$expenseColumn = '';
|
||||
if (Schema::connection($connection)->hasColumn($billTable, 'expense_amount')) {
|
||||
$select[] = 'expense_amount';
|
||||
$expenseColumn = 'expense_amount';
|
||||
} elseif (Schema::connection($connection)->hasColumn($billTable, 'expense')) {
|
||||
$expenseColumn = 'expense';
|
||||
}
|
||||
if ($expenseColumn !== '') {
|
||||
$select[] = $expenseColumn;
|
||||
}
|
||||
if ($realStoreColumn !== '') {
|
||||
$select[] = $realStoreColumn;
|
||||
@ -268,10 +283,10 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$billQuery->whereIn('generation', $generations);
|
||||
$this->info('活动代:' . count($generations) . ' 个');
|
||||
}
|
||||
$billQuery->where(function ($group) use ($baseGroups, $discountGroups, $offsetGroups, $promoItems): void {
|
||||
$billQuery->where(function ($group) use ($baseGroups, $discountGroups, $offsetGroups, $refundGroups, $promoItems): void {
|
||||
LedgerRemarkFilter::applyGroups(
|
||||
$group,
|
||||
array_merge($baseGroups, $discountGroups, $offsetGroups),
|
||||
array_merge($baseGroups, $discountGroups, $offsetGroups, $refundGroups),
|
||||
'bill_item',
|
||||
static fn ($sub, string $prefix) => $sub->where('store_name', 'like', $prefix . '%'),
|
||||
static fn ($sub, string $prefix) => $sub->where('store_name', 'not like', $prefix . '%'),
|
||||
@ -298,6 +313,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$incomeTotal = 0.0;
|
||||
$discountTotal = 0.0;
|
||||
$offsetTotal = 0.0;
|
||||
$refundTotal = 0.0;
|
||||
// 种菜订单号:种菜明细表的订单号 ∪ 聚水潭订单标签明细里「是否种菜订单=是」的订单号(或的关系)。
|
||||
$plantingCores = $this->plantingOrderCores();
|
||||
$plantingTotal = 0.0;
|
||||
@ -309,6 +325,9 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$incomeOverlapTotal = 0.0;
|
||||
/** @var array<string,int> $promoRowsByKey 门店+订单 维度的优惠/冲减账单行数(用于统计未挂单行数) */
|
||||
$promoRowsByKey = [];
|
||||
// 本月账单里真正命中「优惠收入 / 冲减收入 / 退款」的行数(重建后自检用:
|
||||
// 只有账单里确实有这些行,却一行都没写进结果表,才算异常)。
|
||||
$moneyRemarkRows = 0;
|
||||
foreach ($bills as $bill) {
|
||||
$storeName = (string) ($bill->store_name ?? '');
|
||||
$billItem = (string) ($bill->bill_item ?? '');
|
||||
@ -324,14 +343,19 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
);
|
||||
$isPromoRemark = in_array($remark, self::DISCOUNT_REMARKS, true)
|
||||
|| in_array($remark, self::OFFSET_REMARKS, true);
|
||||
$isRefundRemark = in_array($remark, self::REFUND_REMARKS, true);
|
||||
$isIncomeRemark = in_array($legacyRemark, self::LEDGER_REMARKS, true);
|
||||
if ($isIncomeRemark && $isPromoRemark) {
|
||||
if ($isPromoRemark || $isRefundRemark) {
|
||||
$moneyRemarkRows++;
|
||||
}
|
||||
if ($isIncomeRemark && ($isPromoRemark || $isRefundRemark)) {
|
||||
// 已经在收入金额里的行:不重复计入优惠/冲减列,单独提示金额。
|
||||
$incomeOverlapRows++;
|
||||
$incomeOverlapTotal += (float) $bill->{$amountColumn};
|
||||
}
|
||||
$bucket = match (true) {
|
||||
$isIncomeRemark => 'income',
|
||||
$isRefundRemark => 'refund',
|
||||
in_array($remark, self::DISCOUNT_REMARKS, true) => 'discount',
|
||||
in_array($remark, self::OFFSET_REMARKS, true) => 'offset',
|
||||
default => null,
|
||||
@ -360,12 +384,15 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
'discount_seen' => false,
|
||||
'offset_amount' => 0.0,
|
||||
'offset_seen' => false,
|
||||
'refund_amount' => 0.0,
|
||||
'refund_seen' => false,
|
||||
];
|
||||
}
|
||||
|
||||
// 三列统一按「行金额=收入侧 − 支出侧」取数(负数表示净扣减)。
|
||||
// 得物/天猫/淘系这类平台把「卖家承担优惠 / 扣回」记在支出侧,只取收入侧会漏掉扣减。
|
||||
$amount = (float) $bill->{$amountColumn} - (float) ($bill->expense_amount ?? 0);
|
||||
$amount = (float) $bill->{$amountColumn}
|
||||
- ($expenseColumn !== '' ? (float) ($bill->{$expenseColumn} ?? 0) : 0.0);
|
||||
if ($bucket === 'income') {
|
||||
$groups[$key]['payment_count']++;
|
||||
$groups[$key]['income_amount'] += $amount;
|
||||
@ -376,6 +403,10 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$groups[$key]['discount_amount'] += $amount;
|
||||
$discountTotal += $amount;
|
||||
$promoRowsByKey[$key] = ($promoRowsByKey[$key] ?? 0) + 1;
|
||||
} elseif ($bucket === 'refund') {
|
||||
$groups[$key]['refund_seen'] = true;
|
||||
$groups[$key]['refund_amount'] += $amount;
|
||||
$refundTotal += $amount;
|
||||
} else {
|
||||
$groups[$key]['offset_seen'] = true;
|
||||
$groups[$key]['offset_amount'] += $amount;
|
||||
@ -417,10 +448,11 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$orderColumn,
|
||||
$timeColumn,
|
||||
$amountColumn,
|
||||
$expenseColumn,
|
||||
$realStoreColumn,
|
||||
);
|
||||
$this->info('账单收款笔数:' . $paymentTotal . ',按「店铺 + 订单号」聚合后:' . count($groups) . ' 行');
|
||||
$this->line(' 优惠金额合计:' . number_format($discountTotal, 2) . ',冲减金额合计:' . number_format($offsetTotal, 2));
|
||||
$this->line(' 优惠金额合计:' . number_format($discountTotal, 2) . ',冲减金额合计:' . number_format($offsetTotal, 2) . ',退款金额合计:' . number_format($refundTotal, 2));
|
||||
foreach ($groups as $group) {
|
||||
if (! empty($group['planting_seen'])) {
|
||||
$plantingRows++;
|
||||
@ -712,6 +744,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
'income_amount' => $income,
|
||||
'discount_amount' => ! empty($group['discount_seen']) ? round((float) $group['discount_amount'], 2) : null,
|
||||
'offset_amount' => ! empty($group['offset_seen']) ? round((float) $group['offset_amount'], 2) : null,
|
||||
'refund_amount' => ! empty($group['refund_seen']) ? round((float) $group['refund_amount'], 2) : null,
|
||||
'planting_amount' => ! empty($group['planting_seen']) ? $income : null,
|
||||
'product_amount' => $productAmount,
|
||||
'paid_amount' => $paidAmount,
|
||||
@ -754,22 +787,25 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$this->line(' 订单侧商品金额合计:' . number_format($goodsTotal, 2));
|
||||
$this->line(' 差额合计:' . number_format($differenceTotal, 2));
|
||||
|
||||
// 重建后自检:映射表里有「优惠收入 / 冲减收入」的账单项目,但重建出来的行两列一行都没写,
|
||||
// 说明这次重建用的代码或参数不对(历史上出现过用旧代码重建、把优惠金额整列写成空),
|
||||
// 这里显式报错,避免静默丢列后没人发现。
|
||||
// 重建后自检:本月账单里确实存在「优惠收入 / 冲减收入 / 退款」的账单行,但重建出来的行
|
||||
// 三列一行都没写,说明这次重建用的代码或参数不对(历史上出现过用旧代码重建、把优惠金额
|
||||
// 整列写成空),这里显式报错,避免静默丢列后没人发现。
|
||||
$promoFilled = (int) DB::connection($connection)->table(self::TARGET_TABLE)
|
||||
->where('report_month', $reportMonth)
|
||||
->where('platform', (string) $source['label'])
|
||||
->where(function ($query): void {
|
||||
$query->whereNotNull('discount_amount')->orWhereNotNull('offset_amount');
|
||||
$query->whereNotNull('discount_amount')
|
||||
->orWhereNotNull('offset_amount')
|
||||
->orWhereNotNull('refund_amount');
|
||||
})
|
||||
->count();
|
||||
if ($promoItems !== [] && $promoFilled === 0) {
|
||||
if ($promoItems !== [] && $promoFilled === 0 && $moneyRemarkRows > 0) {
|
||||
$this->error(sprintf(
|
||||
'重建后自检不通过:%s %s 的「优惠金额 / 冲减金额」两列一行都没写,但科目映射表里有 %d 个相关账单项目。'
|
||||
'重建后自检不通过:%s %s 的「优惠金额 / 冲减金额 / 退款金额」三列一行都没写,但本月账单里有 %d 行命中优惠/冲减/退款(科目映射表里有 %d 个相关账单项目)。'
|
||||
. '请确认使用最新代码(优惠金额逻辑见 c8a035a1)重跑,或补跑 store-receipt:order-match:sync --amounts-only。',
|
||||
$month,
|
||||
(string) $source['label'],
|
||||
$moneyRemarkRows,
|
||||
count($promoItems),
|
||||
));
|
||||
|
||||
@ -849,13 +885,14 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$target()
|
||||
->where('report_month', $reportMonth)
|
||||
->where('platform', $platform)
|
||||
->update(['discount_amount' => null, 'offset_amount' => null, 'planting_amount' => null]);
|
||||
->update(['discount_amount' => null, 'offset_amount' => null, 'refund_amount' => null, 'planting_amount' => null]);
|
||||
|
||||
$discounts = [];
|
||||
$offsets = [];
|
||||
$refunds = [];
|
||||
$plantings = [];
|
||||
foreach ($groups as $group) {
|
||||
if (empty($group['discount_seen']) && empty($group['offset_seen']) && empty($group['planting_seen'])) {
|
||||
if (empty($group['discount_seen']) && empty($group['offset_seen']) && empty($group['refund_seen']) && empty($group['planting_seen'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -870,6 +907,9 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
if (! empty($group['offset_seen'])) {
|
||||
$offsets[$rowKey] = round((float) $group['offset_amount'], 2);
|
||||
}
|
||||
if (! empty($group['refund_seen'])) {
|
||||
$refunds[$rowKey] = round((float) $group['refund_amount'], 2);
|
||||
}
|
||||
if (! empty($group['planting_seen'])) {
|
||||
$plantings[$rowKey] = round((float) $group['income_amount'], 2);
|
||||
}
|
||||
@ -877,6 +917,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'discount_amount', $discounts);
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'offset_amount', $offsets);
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'refund_amount', $refunds);
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'planting_amount', $plantings);
|
||||
|
||||
// A 方案:本月本平台的补行(payment_count=0 的行)整体重建,保证幂等。
|
||||
@ -947,6 +988,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
string $orderColumn,
|
||||
string $timeColumn,
|
||||
string $amountColumn,
|
||||
string $expenseColumn,
|
||||
string $realStoreColumn,
|
||||
): array {
|
||||
$result = [];
|
||||
@ -961,7 +1003,8 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$this->billGoodsName($bill),
|
||||
);
|
||||
$type = in_array($remark, self::DISCOUNT_REMARKS, true) ? 'discount'
|
||||
: (in_array($remark, self::OFFSET_REMARKS, true) ? 'offset' : null);
|
||||
: (in_array($remark, self::OFFSET_REMARKS, true) ? 'offset'
|
||||
: (in_array($remark, self::REFUND_REMARKS, true) ? 'refund' : null));
|
||||
if ($type === null) {
|
||||
continue;
|
||||
}
|
||||
@ -994,14 +1037,20 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
'discount_seen' => false,
|
||||
'offset_amount' => 0.0,
|
||||
'offset_seen' => false,
|
||||
'refund_amount' => 0.0,
|
||||
'refund_seen' => false,
|
||||
];
|
||||
}
|
||||
|
||||
// 与主流程一致:优惠/冲减都按「收入侧 − 支出侧」取数。
|
||||
$amount = (float) $bill->{$amountColumn} - (float) ($bill->expense_amount ?? 0);
|
||||
$amount = (float) $bill->{$amountColumn}
|
||||
- ($expenseColumn !== '' ? (float) ($bill->{$expenseColumn} ?? 0) : 0.0);
|
||||
if ($type === 'discount') {
|
||||
$result[$key]['discount_seen'] = true;
|
||||
$result[$key]['discount_amount'] += $amount;
|
||||
} elseif ($type === 'refund') {
|
||||
$result[$key]['refund_seen'] = true;
|
||||
$result[$key]['refund_amount'] += $amount;
|
||||
} else {
|
||||
$result[$key]['offset_seen'] = true;
|
||||
$result[$key]['offset_amount'] += $amount;
|
||||
@ -1036,6 +1085,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
'income_amount' => 0,
|
||||
'discount_amount' => ! empty($group['discount_seen']) ? round((float) $group['discount_amount'], 2) : null,
|
||||
'offset_amount' => ! empty($group['offset_seen']) ? round((float) $group['offset_amount'], 2) : null,
|
||||
'refund_amount' => ! empty($group['refund_seen']) ? round((float) $group['refund_amount'], 2) : null,
|
||||
// 补行没有订单侧商品金额,种菜金额同样留空;列集合与顺序必须与主行完全一致,批量插入才不会错列。
|
||||
'planting_amount' => null,
|
||||
'product_amount' => null,
|
||||
|
||||
@ -747,6 +747,7 @@ class Pages extends Controller
|
||||
SUM(income_amount) as income_total,
|
||||
SUM(discount_amount) as discount_total,
|
||||
SUM(offset_amount) as offset_total,
|
||||
SUM(refund_amount) as refund_total,
|
||||
SUM(planting_amount) as planting_total,
|
||||
SUM(product_amount) as goods_total,
|
||||
SUM(COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0))) as difference_total,
|
||||
@ -769,6 +770,7 @@ class Pages extends Controller
|
||||
'income_total' => round((float) ($agg->income_total ?? 0), 2),
|
||||
'discount_total' => round((float) ($agg->discount_total ?? 0), 2),
|
||||
'offset_total' => round((float) ($agg->offset_total ?? 0), 2),
|
||||
'refund_total' => round((float) ($agg->refund_total ?? 0), 2),
|
||||
'planting_total' => round((float) ($agg->planting_total ?? 0), 2),
|
||||
'goods_total' => round((float) ($agg->goods_total ?? 0), 2),
|
||||
'difference_total' => round((float) ($agg->difference_total ?? 0), 2),
|
||||
@ -1110,6 +1112,7 @@ class Pages extends Controller
|
||||
'income_amount' => ['income_amount', '收入金额', 'money'],
|
||||
'discount_amount' => ['discount_amount', '优惠金额', 'money'],
|
||||
'offset_amount' => ['offset_amount', '冲减金额', 'money'],
|
||||
'refund_amount' => ['refund_amount', '退款金额', 'money'],
|
||||
'planting_amount' => ['planting_amount', '种菜金额', 'money'],
|
||||
'product_amount' => ['product_amount', '商品金额', 'money'],
|
||||
'paid_amount' => ['paid_amount', '订单实付金额', 'money'],
|
||||
|
||||
@ -791,7 +791,7 @@ $navigation = [
|
||||
'directory' => [
|
||||
'icon' => 'receipt_long',
|
||||
'status' => '共享镜像',
|
||||
'description' => '覆盖店铺收款账户账单各平台页签(总账备注=订单收入),按「店铺 + 订单号」匹配订单侧商品金额;一行 = 一个店铺的一个订单,商品金额只挂一次。「商品金额」只取主单(拆单子单不参与,整单没有主单时退化为取全部行),并排除虚拟条码(X0000x:信誉订单 / 虚拟订单)明细行;「订单实付金额」取订单级实付(拆单取主单)再减去虚拟条码行实付。「优惠金额」「冲减金额」另取总账备注=优惠收入 / 冲减收入的账单金额,不计入收入金额;「种菜金额」是订单号在种菜明细表或聚水潭订单标签明细(是否种菜订单=是)任意一边出现过时,该订单的收入金额(两个条件是或的关系),只是收入金额里的一部分,不参与差额;差额=(收入金额+优惠金额+冲减金额)−商品金额,未匹配到商品金额的行按商品金额=0 计入差额,只反映真正对不上的部分。挂不到订单行的优惠/冲减会补成一行(收入/商品留空)。「差额异常备注」只说明差额为什么产生,按顺序自动判定:商品金额未匹配(账单无单号 / 单号格式异常 / 订单表无此单 / 订单无商品金额 / 无收款账单,未匹配到商品金额);商品金额未加种菜(商品金额=0 且是种菜单)、商品金额取数为0(商品金额=0 但不是种菜单)、商品金额未减冲减(商品金额=收入+优惠 → 差额=冲减金额)、商品金额未减优惠(商品金额=收入+冲减 → 差额=优惠金额)、商品金额未减优惠和冲减(商品金额=收入 → 差额=优惠+冲减);都不满足则留空。',
|
||||
'description' => '覆盖店铺收款账户账单各平台页签(总账备注=订单收入),按「店铺 + 订单号」匹配订单侧商品金额;一行 = 一个店铺的一个订单,商品金额只挂一次。「商品金额」只取主单(拆单子单不参与,整单没有主单时退化为取全部行),并排除虚拟条码(X0000x:信誉订单 / 虚拟订单)明细行;「订单实付金额」取订单级实付(拆单取主单)再减去虚拟条码行实付。「优惠金额」「冲减金额」另取总账备注=优惠收入 / 冲减收入的账单金额,不计入收入金额;「退款金额」另取总账备注=退款的账单金额,只单独列示,不计入收入金额、也不参与差额;「种菜金额」是订单号在种菜明细表或聚水潭订单标签明细(是否种菜订单=是)任意一边出现过时,该订单的收入金额(两个条件是或的关系),只是收入金额里的一部分,不参与差额;差额=(收入金额+优惠金额+冲减金额)−商品金额,未匹配到商品金额的行按商品金额=0 计入差额,只反映真正对不上的部分。挂不到订单行的优惠/冲减会补成一行(收入/商品留空)。「差额异常备注」只说明差额为什么产生,按顺序自动判定:商品金额未匹配(账单无单号 / 单号格式异常 / 订单表无此单 / 订单无商品金额 / 无收款账单,未匹配到商品金额);商品金额未加种菜(商品金额=0 且是种菜单)、商品金额取数为0(商品金额=0 但不是种菜单)、商品金额未减冲减(商品金额=收入+优惠 → 差额=冲减金额)、商品金额未减优惠(商品金额=收入+冲减 → 差额=优惠金额)、商品金额未减优惠和冲减(商品金额=收入 → 差额=优惠+冲减);都不满足则留空。',
|
||||
'empty' => '店铺收款匹配订单明细尚未同步,请先执行 store-receipt:order-match:sync。',
|
||||
'fields' => [
|
||||
['name' => 'platform', 'label' => '平台'],
|
||||
@ -801,6 +801,7 @@ $navigation = [
|
||||
['name' => 'income_amount', 'label' => '收入金额', 'kind' => 'number'],
|
||||
['name' => 'discount_amount', 'label' => '优惠金额', 'kind' => 'number'],
|
||||
['name' => 'offset_amount', 'label' => '冲减金额', 'kind' => 'number'],
|
||||
['name' => 'refund_amount', 'label' => '退款金额', 'kind' => 'number'],
|
||||
['name' => 'planting_amount', 'label' => '种菜金额', 'kind' => 'number'],
|
||||
['name' => 'product_amount', 'label' => '商品金额', 'kind' => 'number'],
|
||||
['name' => 'paid_amount', 'label' => '订单实付金额', 'kind' => 'number'],
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* 业绩明细新增「退款金额」列:账单总账备注=退款的金额(收入侧 − 支出侧),
|
||||
* 与「优惠金额 / 冲减金额」同一套取数口径,单独列示、不参与差额计算。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
private function connection(): string
|
||||
{
|
||||
return (string) config('upstream_mirrors.connection', 'business_mirror');
|
||||
}
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$schema = Schema::connection($this->connection());
|
||||
if (! $schema->hasTable('store_receipt_order_match_rows')
|
||||
|| $schema->hasColumn('store_receipt_order_match_rows', 'refund_amount')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$schema->table('store_receipt_order_match_rows', function (Blueprint $table): void {
|
||||
$table->decimal('refund_amount', 20, 4)->nullable()->after('offset_amount');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$schema = Schema::connection($this->connection());
|
||||
if (! $schema->hasTable('store_receipt_order_match_rows')
|
||||
|| ! $schema->hasColumn('store_receipt_order_match_rows', 'refund_amount')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$schema->table('store_receipt_order_match_rows', function (Blueprint $table): void {
|
||||
$table->dropColumn('refund_amount');
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -1094,6 +1094,7 @@
|
||||
<span class="receipt-match-summary__item"><em>账单收入合计</em><strong>{{ number_format((float) $receiptStats['income_total'], 2) }}</strong></span>
|
||||
<span class="receipt-match-summary__item"><em>优惠金额合计</em><strong>{{ number_format((float) ($receiptStats['discount_total'] ?? 0), 2) }}</strong></span>
|
||||
<span class="receipt-match-summary__item"><em>冲减金额合计</em><strong>{{ number_format((float) ($receiptStats['offset_total'] ?? 0), 2) }}</strong></span>
|
||||
<span class="receipt-match-summary__item"><em>退款金额合计</em><strong>{{ number_format((float) ($receiptStats['refund_total'] ?? 0), 2) }}</strong></span>
|
||||
<span class="receipt-match-summary__item"><em>种菜金额合计</em><strong>{{ number_format((float) ($receiptStats['planting_total'] ?? 0), 2) }}</strong></span>
|
||||
<span class="receipt-match-summary__item"><em>订单商品金额合计</em><strong>{{ number_format((float) $receiptStats['goods_total'], 2) }}</strong></span>
|
||||
<span class="receipt-match-summary__item receipt-match-summary__item--lead"><em>差额合计</em><strong>{{ number_format((float) $receiptStats['difference_total'], 2) }}</strong></span>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user