insertBalance($connection, [ 'source_scope' => 'all', 'data_source' => JushuitanShopBalanceRepository::DATA_SOURCE_JUSHUITAN, 'source_platform' => '京东', 'store_name' => '京东-同店测试', 'balance' => 100, ]); $this->insertBalance($connection, [ 'source_scope' => 'pinduoduo', 'data_source' => JushuitanShopBalanceRepository::DATA_SOURCE_JUSHUITAN, 'source_platform' => '拼多多', 'store_name' => '拼多多-补录测试店', 'balance' => 200, ]); $this->insertBalance($connection, [ 'source_scope' => StoreReceivingBillBalanceSnapshotSynchronizer::SOURCE_SCOPE, 'data_source' => StoreReceivingBillBalanceSnapshotSynchronizer::DATA_SOURCE_RECEIVING_BILL, 'source_platform' => '京东', 'store_name' => '京东-旧快照', 'balance' => 999, ]); $billBalances = Mockery::mock(FinanceBillBalanceRepository::class); $billBalances->shouldReceive('latestBalances') ->once() ->with(FinanceBillBalanceRepository::SCOPE_TAOBAO, '2026-10-26') ->andReturn([[ 'source_scope' => FinanceBillBalanceRepository::SCOPE_TAOBAO, 'source_platform' => '天猫', 'store_name' => '天猫-账单余额店', 'normalized_store_name' => JushuitanShopBalanceRepository::normalizeStoreName('天猫-账单余额店'), 'platform_account_id' => 'ALI-1', 'balance' => 300.25, 'occurred_at' => '2026-10-26 23:58:00', 'source_row_key' => 'taobao-row', 'source_file_name' => '财务系统/店铺收款账户账单/淘系支付宝', ]]); $billBalances->shouldReceive('latestBalances') ->once() ->with(FinanceBillBalanceRepository::SCOPE_JD_WALLET, '2026-10-26') ->andReturn([[ 'source_scope' => FinanceBillBalanceRepository::SCOPE_JD_WALLET, 'source_platform' => '京东', 'store_name' => '京东-同店测试', 'normalized_store_name' => JushuitanShopBalanceRepository::normalizeStoreName('京东-同店测试'), 'platform_account_id' => 'JD-1', 'balance' => 400.50, 'occurred_at' => '2026-10-26 23:59:59', 'source_row_key' => 'jd-row', 'source_file_name' => '财务系统/店铺收款账户账单/京东钱包', ]]); $this->app->instance(FinanceBillBalanceRepository::class, $billBalances); $result = app(StoreReceivingBillBalanceSnapshotSynchronizer::class)->sync('2026-10-26'); $this->assertSame(3, $result['total']); $this->assertSame(2, $result['receiving_bill']); $this->assertSame(1, $result['jushuitan']); $this->assertSame(1, $result['replaced']); $this->assertDatabaseMissing('jushuitan_shop_balance_snapshots', [ 'balance_date' => '2026-10-26', 'source_scope' => StoreReceivingBillBalanceSnapshotSynchronizer::SOURCE_SCOPE, 'store_name' => '京东-旧快照', ], 'business_mirror'); $this->assertDatabaseHas('jushuitan_shop_balance_snapshots', [ 'balance_date' => '2026-10-26', 'source_scope' => StoreReceivingBillBalanceSnapshotSynchronizer::SOURCE_SCOPE, 'data_source' => StoreReceivingBillBalanceSnapshotSynchronizer::DATA_SOURCE_RECEIVING_BILL, 'store_name' => '京东-同店测试', 'balance' => 400.50, ], 'business_mirror'); $this->assertDatabaseHas('jushuitan_shop_balance_snapshots', [ 'balance_date' => '2026-10-26', 'source_scope' => StoreReceivingBillBalanceSnapshotSynchronizer::SOURCE_SCOPE, 'data_source' => JushuitanShopBalanceRepository::DATA_SOURCE_JUSHUITAN, 'store_name' => '拼多多-补录测试店', 'balance' => 200, ], 'business_mirror'); } private function insertBalance($connection, array $values): void { $date = '2026-10-26'; $storeName = (string) $values['store_name']; $connection->table(JushuitanShopBalanceRepository::TABLE)->insert([ 'balance_date' => $date, 'source_scope' => $values['source_scope'], 'data_source' => $values['data_source'], 'source_platform' => $values['source_platform'], 'store_name' => $storeName, 'normalized_store_name' => JushuitanShopBalanceRepository::normalizeStoreName($storeName), 'platform_account_id' => null, 'balance' => $values['balance'], 'source_row_key' => hash('sha256', $values['source_scope'] . '|' . $storeName), 'source_file_name' => 'fixture', 'source_sha256' => hash('sha256', $date . '|' . $storeName), 'imported_at' => now(), 'created_at' => now(), 'updated_at' => now(), ]); } }