feat: 业绩明细种菜报销与未报销合并为标签
This commit is contained in:
parent
1ad248dda6
commit
1192cb63f9
@ -37,8 +37,8 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
{--company=1 : 公司 ID(种菜订单号取自该公司的种菜明细表与聚水潭订单标签明细)}
|
||||
{--chunk=1200 : 单次向上游查询的订单号数量}
|
||||
{--limit=0 : 仅处理前 N 笔账单(调试用,0 表示全量)}
|
||||
{--amounts-only : 只回填「优惠金额 / 冲减金额 / 种菜金额」三列,不重跑订单侧匹配}
|
||||
{--planting-only : 只回填「种菜金额」一列(不读账单,直接按该月已有明细行的订单号刷,一次覆盖全平台)}
|
||||
{--amounts-only : 只回填「优惠金额 / 冲减金额 / 种菜金额 / 标签」,不重跑订单侧匹配}
|
||||
{--planting-only : 只回填「种菜金额 / 标签」(不读账单,直接按该月已有明细行的订单号刷,一次覆盖全平台)}
|
||||
{--dry-run : 只计算并打印统计,不写库(用于评估口径调整的影响)}';
|
||||
|
||||
protected $description = '按店铺收款账户账单匹配订单侧商品金额,生成「业绩明细」核对镜像';
|
||||
@ -142,6 +142,10 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
|
||||
private const STATUS_UNMATCHED = '未匹配';
|
||||
|
||||
private const PLANTING_LABEL_REIMBURSED = '种菜报销';
|
||||
|
||||
private const PLANTING_LABEL_UNREIMBURSED = '种菜未报销';
|
||||
|
||||
/**
|
||||
* 异常标注取值(页面「匹配状态」筛选与导出共用)。
|
||||
*
|
||||
@ -401,8 +405,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
if (! empty($group['planting_reimbursement_seen'])) {
|
||||
$plantingReimbursementRows++;
|
||||
$plantingReimbursementTotal += (float) $group['income_amount'];
|
||||
}
|
||||
if (! empty($group['planting_unreimbursed_seen'])) {
|
||||
} elseif (! empty($group['planting_unreimbursed_seen'])) {
|
||||
$plantingUnreimbursedRows++;
|
||||
$plantingUnreimbursedTotal += (float) $group['income_amount'];
|
||||
}
|
||||
@ -414,12 +417,12 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
number_format($plantingTotal, 2),
|
||||
));
|
||||
$this->line(sprintf(
|
||||
' 种菜报销:%d 行(按种菜明细表订单号),合计 %s',
|
||||
' 标签「种菜报销」:%d 行(按种菜明细表订单号),收入合计 %s',
|
||||
$plantingReimbursementRows,
|
||||
number_format($plantingReimbursementTotal, 2),
|
||||
));
|
||||
$this->line(sprintf(
|
||||
' 种菜未报销:%d 行(按聚水潭种菜标签),合计 %s',
|
||||
' 标签「种菜未报销」:%d 行(按聚水潭种菜标签),收入合计 %s',
|
||||
$plantingUnreimbursedRows,
|
||||
number_format($plantingUnreimbursedTotal, 2),
|
||||
));
|
||||
@ -796,8 +799,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
'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,
|
||||
'planting_reimbursement_amount' => ! empty($group['planting_reimbursement_seen']) ? $income : null,
|
||||
'planting_unreimbursed_amount' => ! empty($group['planting_unreimbursed_seen']) ? $income : null,
|
||||
'planting_label' => self::plantingLabel($group),
|
||||
'product_amount' => $productAmount,
|
||||
'paid_amount' => $paidAmount,
|
||||
'difference' => $difference,
|
||||
@ -912,9 +914,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 只回填「种菜金额 / 种菜报销 / 种菜未报销」:不读账单,直接按订单号判断,是就写入收入金额。
|
||||
*/
|
||||
/** 只回填「种菜金额 / 标签」:按种菜明细表与聚水潭种菜标签的并集判断。 */
|
||||
private function backfillPlantingAmounts(string $reportMonth): int
|
||||
{
|
||||
if ((bool) $this->option('dry-run')) {
|
||||
@ -926,7 +926,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$reimbursementCores = $this->plantingReimbursementCores();
|
||||
$unreimbursedCores = $this->plantingUnreimbursedCores();
|
||||
if ($cores === []) {
|
||||
$this->warn('没有识别到任何种菜订单号(种菜明细表与聚水潭订单标签明细的交集为空),本列将全部为空。');
|
||||
$this->warn('没有识别到任何种菜订单号(种菜明细表与聚水潭订单标签明细的并集为空),本列将全部为空。');
|
||||
}
|
||||
|
||||
$target = static fn () => DB::connection($connection)->table(self::TARGET_TABLE)
|
||||
@ -935,16 +935,14 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$rows = $target()->get(['row_key', 'order_core_no', 'income_amount']);
|
||||
$target()->update([
|
||||
'planting_amount' => null,
|
||||
'planting_reimbursement_amount' => null,
|
||||
'planting_unreimbursed_amount' => null,
|
||||
'planting_label' => null,
|
||||
]);
|
||||
|
||||
$values = [];
|
||||
$labels = [];
|
||||
$total = 0.0;
|
||||
$reimbursementValues = [];
|
||||
$reimbursementTotal = 0.0;
|
||||
$unreimbursedValues = [];
|
||||
$unreimbursedTotal = 0.0;
|
||||
$reimbursementRows = 0;
|
||||
$unreimbursedRows = 0;
|
||||
foreach ($rows as $row) {
|
||||
$core = self::orderCoreNo((string) $row->order_core_no);
|
||||
if ($core === '') {
|
||||
@ -957,31 +955,27 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$total += $amount;
|
||||
}
|
||||
if (isset($reimbursementCores[$core])) {
|
||||
$reimbursementValues[(string) $row->row_key] = $amount;
|
||||
$reimbursementTotal += $amount;
|
||||
}
|
||||
if (isset($unreimbursedCores[$core])) {
|
||||
$unreimbursedValues[(string) $row->row_key] = $amount;
|
||||
$unreimbursedTotal += $amount;
|
||||
$labels[(string) $row->row_key] = self::PLANTING_LABEL_REIMBURSED;
|
||||
$reimbursementRows++;
|
||||
} elseif (isset($unreimbursedCores[$core])) {
|
||||
$labels[(string) $row->row_key] = self::PLANTING_LABEL_UNREIMBURSED;
|
||||
$unreimbursedRows++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'planting_amount', $values);
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'planting_reimbursement_amount', $reimbursementValues);
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'planting_unreimbursed_amount', $unreimbursedValues);
|
||||
$this->updateColumnValues($connection, $reportMonth, 'planting_amount', $values);
|
||||
$this->updateColumnValues($connection, $reportMonth, 'planting_label', $labels);
|
||||
|
||||
$this->info(sprintf(
|
||||
'已回填 %s:种菜金额 %d / %d 行,合计 %s(识别 %d 个种菜订单号);种菜报销 %d 行,合计 %s(识别 %d 个种菜明细订单号);种菜未报销 %d 行,合计 %s(识别 %d 个聚水潭种菜标签订单号)。',
|
||||
'已回填 %s:种菜金额 %d / %d 行,合计 %s(识别 %d 个种菜订单号);标签「种菜报销」%d 行(识别 %d 个种菜明细订单号);标签「种菜未报销」%d 行(识别 %d 个聚水潭种菜标签订单号)。',
|
||||
$reportMonth,
|
||||
count($values),
|
||||
count($rows),
|
||||
number_format($total, 2),
|
||||
count($cores),
|
||||
count($reimbursementValues),
|
||||
number_format($reimbursementTotal, 2),
|
||||
$reimbursementRows,
|
||||
count($reimbursementCores),
|
||||
count($unreimbursedValues),
|
||||
number_format($unreimbursedTotal, 2),
|
||||
$unreimbursedRows,
|
||||
count($unreimbursedCores),
|
||||
));
|
||||
|
||||
@ -1022,16 +1016,14 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
'offset_amount' => null,
|
||||
'refund_amount' => null,
|
||||
'planting_amount' => null,
|
||||
'planting_reimbursement_amount' => null,
|
||||
'planting_unreimbursed_amount' => null,
|
||||
'planting_label' => null,
|
||||
]);
|
||||
|
||||
$discounts = [];
|
||||
$offsets = [];
|
||||
$refunds = [];
|
||||
$plantings = [];
|
||||
$plantingReimbursements = [];
|
||||
$plantingUnreimbursed = [];
|
||||
$plantingLabels = [];
|
||||
foreach ($groups as $group) {
|
||||
if (empty($group['discount_seen'])
|
||||
&& empty($group['offset_seen'])
|
||||
@ -1065,19 +1057,17 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$plantings[$rowKey] = round((float) $group['income_amount'], 2);
|
||||
}
|
||||
if (! empty($group['planting_reimbursement_seen'])) {
|
||||
$plantingReimbursements[$rowKey] = round((float) $group['income_amount'], 2);
|
||||
}
|
||||
if (! empty($group['planting_unreimbursed_seen'])) {
|
||||
$plantingUnreimbursed[$rowKey] = round((float) $group['income_amount'], 2);
|
||||
$plantingLabels[$rowKey] = self::PLANTING_LABEL_REIMBURSED;
|
||||
} elseif (! empty($group['planting_unreimbursed_seen'])) {
|
||||
$plantingLabels[$rowKey] = self::PLANTING_LABEL_UNREIMBURSED;
|
||||
}
|
||||
}
|
||||
|
||||
$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);
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'planting_reimbursement_amount', $plantingReimbursements);
|
||||
$this->updateAmountColumn($connection, $reportMonth, 'planting_unreimbursed_amount', $plantingUnreimbursed);
|
||||
$this->updateColumnValues($connection, $reportMonth, 'discount_amount', $discounts);
|
||||
$this->updateColumnValues($connection, $reportMonth, 'offset_amount', $offsets);
|
||||
$this->updateColumnValues($connection, $reportMonth, 'refund_amount', $refunds);
|
||||
$this->updateColumnValues($connection, $reportMonth, 'planting_amount', $plantings);
|
||||
$this->updateColumnValues($connection, $reportMonth, 'planting_label', $plantingLabels);
|
||||
|
||||
// A 方案:本月本平台的补行(payment_count=0 的行)整体重建,保证幂等。
|
||||
$target()
|
||||
@ -1114,7 +1104,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
]);
|
||||
|
||||
$this->info(sprintf(
|
||||
'已回填 %s %s:优惠 %d 行(%s)/ 冲减 %d 行(%s)/ 补「无收款账单/无单号」优惠冲减行 %d 行 / 种菜 %d 行(%s)/ 种菜报销 %d 行(%s)/ 种菜未报销 %d 行(%s),镜像原有 %d 行,未重建业绩明细。',
|
||||
'已回填 %s %s:优惠 %d 行(%s)/ 冲减 %d 行(%s)/ 补「无收款账单/无单号」优惠冲减行 %d 行 / 种菜 %d 行(%s)/ 标签「种菜报销」%d 行 / 标签「种菜未报销」%d 行,镜像原有 %d 行,未重建业绩明细。',
|
||||
$month,
|
||||
$platform,
|
||||
count($discounts),
|
||||
@ -1124,10 +1114,8 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
$promoRows,
|
||||
count($plantings),
|
||||
number_format(array_sum($plantings), 2),
|
||||
count($plantingReimbursements),
|
||||
number_format(array_sum($plantingReimbursements), 2),
|
||||
count($plantingUnreimbursed),
|
||||
number_format(array_sum($plantingUnreimbursed), 2),
|
||||
count(array_filter($plantingLabels, static fn (string $label): bool => $label === self::PLANTING_LABEL_REIMBURSED)),
|
||||
count(array_filter($plantingLabels, static fn (string $label): bool => $label === self::PLANTING_LABEL_UNREIMBURSED)),
|
||||
count($existing),
|
||||
));
|
||||
|
||||
@ -1377,8 +1365,7 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
'refund_amount' => ! empty($group['refund_seen']) ? round((float) $group['refund_amount'], 2) : null,
|
||||
// 补行没有订单侧商品金额,种菜金额同样留空;列集合与顺序必须与主行完全一致,批量插入才不会错列。
|
||||
'planting_amount' => null,
|
||||
'planting_reimbursement_amount' => null,
|
||||
'planting_unreimbursed_amount' => null,
|
||||
'planting_label' => null,
|
||||
'product_amount' => null,
|
||||
'paid_amount' => null,
|
||||
'difference' => null,
|
||||
@ -1390,12 +1377,25 @@ class SyncStoreReceiptOrderMatches extends Command
|
||||
];
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $group */
|
||||
private static function plantingLabel(array $group): ?string
|
||||
{
|
||||
if (! empty($group['planting_reimbursement_seen'])) {
|
||||
return self::PLANTING_LABEL_REIMBURSED;
|
||||
}
|
||||
if (! empty($group['planting_unreimbursed_seen'])) {
|
||||
return self::PLANTING_LABEL_UNREIMBURSED;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按 row_key 批量更新一列金额:只更新镜像里已有的行,不做插入。
|
||||
* 按 row_key 批量更新一列字段值:只更新镜像里已有的行,不做插入。
|
||||
*
|
||||
* @param array<string,float> $values row_key => 金额
|
||||
* @param array<string,float|string> $values row_key => 金额或文本
|
||||
*/
|
||||
private function updateAmountColumn(string $connection, string $reportMonth, string $column, array $values): void
|
||||
private function updateColumnValues(string $connection, string $reportMonth, string $column, array $values): void
|
||||
{
|
||||
if ($values === []) {
|
||||
return;
|
||||
|
||||
@ -2082,8 +2082,7 @@ class Pages extends Controller
|
||||
'offset_amount' => ['offset_amount', '冲减金额', 'money'],
|
||||
'refund_amount' => ['refund_amount', '退款金额', 'money'],
|
||||
'planting_amount' => ['planting_amount', '种菜金额', 'money'],
|
||||
'planting_reimbursement_amount' => ['planting_reimbursement_amount', '种菜报销', 'money'],
|
||||
'planting_unreimbursed_amount' => ['planting_unreimbursed_amount', '种菜未报销', 'money'],
|
||||
'planting_label' => ['planting_label', '标签', 'text'],
|
||||
'product_amount' => ['product_amount', '商品金额', 'money'],
|
||||
'paid_amount' => ['paid_amount', '订单实付金额', 'money'],
|
||||
'difference' => ['difference', '差额', 'money'],
|
||||
|
||||
@ -834,8 +834,7 @@ $navigation = [
|
||||
['name' => 'offset_amount', 'label' => '冲减金额', 'kind' => 'number'],
|
||||
['name' => 'refund_amount', 'label' => '退款金额', 'kind' => 'number'],
|
||||
['name' => 'planting_amount', 'label' => '种菜金额', 'kind' => 'number'],
|
||||
['name' => 'planting_reimbursement_amount', 'label' => '种菜报销', 'kind' => 'number'],
|
||||
['name' => 'planting_unreimbursed_amount', 'label' => '种菜未报销', 'kind' => 'number'],
|
||||
['name' => 'planting_label', 'label' => '标签'],
|
||||
['name' => 'product_amount', 'label' => '商品金额', 'kind' => 'number'],
|
||||
['name' => 'paid_amount', 'label' => '订单实付/实收金额', 'kind' => 'number'],
|
||||
['name' => 'difference', 'label' => '差额', 'kind' => 'number'],
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
<?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')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $schema->hasColumn('store_receipt_order_match_rows', 'planting_label')) {
|
||||
$schema->table('store_receipt_order_match_rows', function (Blueprint $table): void {
|
||||
$table->string('planting_label', 32)
|
||||
->nullable()
|
||||
->after('planting_amount')
|
||||
->comment('种菜标签:种菜报销 / 种菜未报销');
|
||||
});
|
||||
}
|
||||
|
||||
$oldColumns = array_values(array_filter(
|
||||
['planting_reimbursement_amount', 'planting_unreimbursed_amount'],
|
||||
static fn (string $column): bool => $schema->hasColumn('store_receipt_order_match_rows', $column),
|
||||
));
|
||||
if ($oldColumns !== []) {
|
||||
$schema->table('store_receipt_order_match_rows', function (Blueprint $table) use ($oldColumns): void {
|
||||
$table->dropColumn($oldColumns);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$schema = Schema::connection($this->connection());
|
||||
if (! $schema->hasTable('store_receipt_order_match_rows')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hasReimbursement = $schema->hasColumn('store_receipt_order_match_rows', 'planting_reimbursement_amount');
|
||||
$hasUnreimbursed = $schema->hasColumn('store_receipt_order_match_rows', 'planting_unreimbursed_amount');
|
||||
$hasLabel = $schema->hasColumn('store_receipt_order_match_rows', 'planting_label');
|
||||
|
||||
if (! $hasReimbursement) {
|
||||
$schema->table('store_receipt_order_match_rows', function (Blueprint $table): void {
|
||||
$table->decimal('planting_reimbursement_amount', 20, 4)
|
||||
->nullable()
|
||||
->after('planting_amount');
|
||||
});
|
||||
}
|
||||
if (! $hasUnreimbursed) {
|
||||
$schema->table('store_receipt_order_match_rows', function (Blueprint $table): void {
|
||||
$table->decimal('planting_unreimbursed_amount', 20, 4)
|
||||
->nullable()
|
||||
->after('planting_reimbursement_amount');
|
||||
});
|
||||
}
|
||||
if ($hasLabel) {
|
||||
$schema->table('store_receipt_order_match_rows', function (Blueprint $table): void {
|
||||
$table->dropColumn('planting_label');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1256,6 +1256,7 @@
|
||||
<li>优惠/冲减:分别取优惠收入、冲减收入,不计入收入</li>
|
||||
<li>退款:单独列示,不参与收入和差额</li>
|
||||
<li>种菜:种菜订单的收入子集,不参与差额</li>
|
||||
<li>标签:种菜明细表命中为“种菜报销”,其余聚水潭种菜标签命中为“种菜未报销”</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="receipt-method-guide__section">
|
||||
|
||||
@ -99,16 +99,20 @@ class NavigationTest extends FeatureTestCase
|
||||
->assertSee('data-column-key="discount_amount"', false)
|
||||
->assertSee('data-column-key="offset_amount"', false)
|
||||
->assertSee('data-column-key="planting_amount"', false)
|
||||
->assertSee('data-column-key="planting_label"', false)
|
||||
->assertSee('data-column-key="product_amount"', false)
|
||||
->assertSee('data-column-key="difference"', false)
|
||||
->assertSee('data-column-key="match_status"', false)
|
||||
->assertSee('data-column-key="remark"', false)
|
||||
->assertSeeText('标签:种菜明细表命中为“种菜报销”,其余聚水潭种菜标签命中为“种菜未报销”')
|
||||
// 子订单号已按业务要求移除。
|
||||
->assertDontSeeText('子订单号')
|
||||
// 展示粒度=一笔账单收款,不再展开发货明细列。
|
||||
->assertDontSee('data-column-key="warehouse"', false)
|
||||
->assertDontSee('data-column-key="product_code"', false)
|
||||
->assertDontSee('data-column-key="quantity"', false)
|
||||
->assertDontSee('data-column-key="planting_reimbursement_amount"', false)
|
||||
->assertDontSee('data-column-key="planting_unreimbursed_amount"', false)
|
||||
// 筛选栏:月份选择器 + 店铺名称 + 线上单号 + 匹配状态。
|
||||
->assertSee('data-inventory-month-picker', false)
|
||||
->assertSee('name="store_name"', false)
|
||||
|
||||
@ -21,7 +21,13 @@ class StoreReceiptMemoryTest extends TestCase
|
||||
], $extra);
|
||||
}
|
||||
|
||||
private function aggregate(iterable $rows, array $planting = [], ?AccountLedgerRemarkMap $map = null): array
|
||||
private function aggregate(
|
||||
iterable $rows,
|
||||
array $planting = [],
|
||||
array $plantingReimbursement = [],
|
||||
array $plantingUnreimbursed = [],
|
||||
?AccountLedgerRemarkMap $map = null,
|
||||
): array
|
||||
{
|
||||
$map ??= new class extends AccountLedgerRemarkMap {
|
||||
public function remark(?string $storeName, ?string $tabPlatform, ?string $billItem, array $businessRemarks = [], string $goodsName = ''): ?string
|
||||
@ -32,7 +38,8 @@ class StoreReceiptMemoryTest extends TestCase
|
||||
|
||||
return (new ReflectionMethod(SyncStoreReceiptOrderMatches::class, 'aggregateBills'))->invoke(
|
||||
new SyncStoreReceiptOrderMatches(), $rows, ['label' => '淘系支付宝'], 'online_order_no', 'occurred_at',
|
||||
'income_amount', 'expense_amount', 'online_real_store', $planting, [], [], $map, '淘宝',
|
||||
'income_amount', 'expense_amount', 'online_real_store', $planting,
|
||||
$plantingReimbursement, $plantingUnreimbursed, $map, '淘宝',
|
||||
);
|
||||
}
|
||||
|
||||
@ -156,13 +163,27 @@ class StoreReceiptMemoryTest extends TestCase
|
||||
)->willReturn('优惠收入');
|
||||
$result = $this->aggregate([$this->bill('动态项目', '', 1.5, 0, [
|
||||
'custom_remark' => '活动优惠', 'second_remark' => '活动优惠', 'goods_name' => '商品关键词',
|
||||
])], [], $map);
|
||||
])], [], [], [], $map);
|
||||
$this->assertSame(1.5, $result['discountTotal']);
|
||||
$this->assertSame([], $result['groups']);
|
||||
$this->assertCount(1, $result['promoOnlyGroups']);
|
||||
$this->assertSame(0, $this->aggregate([])['billCount']);
|
||||
}
|
||||
|
||||
public function test_planting_label_prefers_reimbursed_and_uses_unreimbursed_fallback(): void
|
||||
{
|
||||
$method = new ReflectionMethod(SyncStoreReceiptOrderMatches::class, 'plantingLabel');
|
||||
$this->assertSame('种菜报销', $method->invoke(null, [
|
||||
'planting_reimbursement_seen' => true,
|
||||
'planting_unreimbursed_seen' => true,
|
||||
]));
|
||||
$this->assertSame('种菜未报销', $method->invoke(null, [
|
||||
'planting_reimbursement_seen' => false,
|
||||
'planting_unreimbursed_seen' => true,
|
||||
]));
|
||||
$this->assertNull($method->invoke(null, []));
|
||||
}
|
||||
|
||||
public function test_stream_uses_bound_filter_and_sql_limit_in_sqlite(): void
|
||||
{
|
||||
$db = DB::connection('business_mirror');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user