From d0c4ac800b8dd95b4ced4bcd800ec6eb216b409e Mon Sep 17 00:00:00 2001 From: qiuxiang <394405259@qq.com> Date: Tue, 10 Nov 2026 14:51:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=9D=E7=95=99=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=AE=9D=E5=BA=97=E9=93=BA=E6=9C=9F=E5=88=9D=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E5=B9=B6=E5=90=88=E5=B9=B6=E9=87=8D=E5=A4=8D=E5=BA=97=E9=93=BA?= =?UTF-8?q?=20(#1043)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TaobaoAlipaySettlementBillRepository.php | 2 ++ .../StoreReceivingBalanceOverviewService.php | 34 ++++++++++++++---- ...oreReceivingBalanceOverviewServiceTest.php | 36 +++++++++++++++++++ 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/modules/EcommerceFinance/Repositories/TaobaoAlipaySettlementBillRepository.php b/modules/EcommerceFinance/Repositories/TaobaoAlipaySettlementBillRepository.php index b02654ea..b05f87a5 100644 --- a/modules/EcommerceFinance/Repositories/TaobaoAlipaySettlementBillRepository.php +++ b/modules/EcommerceFinance/Repositories/TaobaoAlipaySettlementBillRepository.php @@ -262,6 +262,7 @@ class TaobaoAlipaySettlementBillRepository ->where('alipay_account', '<>', '') ->when($store !== '', fn (Builder $query) => $query->where('store_name', $store)) ->select([ + 'store_name', 'alipay_account', 'occurred_at', 'source_row_number', @@ -308,6 +309,7 @@ class TaobaoAlipaySettlementBillRepository ->where('alipay_account', '<>', '') ->when($store !== '', fn (Builder $query) => $query->where('store_name', $store)) ->select([ + 'store_name', 'alipay_account', 'occurred_at', 'source_row_number', diff --git a/modules/EcommerceFinance/Services/StoreReceivingBalanceOverviewService.php b/modules/EcommerceFinance/Services/StoreReceivingBalanceOverviewService.php index 8672a0ba..beef5537 100644 --- a/modules/EcommerceFinance/Services/StoreReceivingBalanceOverviewService.php +++ b/modules/EcommerceFinance/Services/StoreReceivingBalanceOverviewService.php @@ -372,15 +372,37 @@ class StoreReceivingBalanceOverviewService throw new RuntimeException('店铺期末余额明细暂时无法读取,请稍后重试。', 0, $exception); } - $platformRows = []; + $rowsByStore = []; foreach ($rows as $row) { $storeName = trim((string) ($row['store_name'] ?? '')); $storeName = $storeName !== '' ? $storeName : '未标注店铺'; - $opening = is_numeric($row['opening_balance'] ?? null) - ? round((float) $row['opening_balance'], 2) - : null; - $income = round((float) ($row['income'] ?? 0), 2); - $expense = round((float) ($row['expense'] ?? 0), 2); + $rowsByStore[$storeName] ??= [ + 'opening_balance' => null, + 'income' => 0.0, + 'expense' => 0.0, + ]; + if (is_numeric($row['opening_balance'] ?? null)) { + $rowsByStore[$storeName]['opening_balance'] = round( + (float) ($rowsByStore[$storeName]['opening_balance'] ?? 0) + + (float) $row['opening_balance'], + 2, + ); + } + $rowsByStore[$storeName]['income'] = round( + (float) $rowsByStore[$storeName]['income'] + (float) ($row['income'] ?? 0), + 2, + ); + $rowsByStore[$storeName]['expense'] = round( + (float) $rowsByStore[$storeName]['expense'] + (float) ($row['expense'] ?? 0), + 2, + ); + } + + $platformRows = []; + foreach ($rowsByStore as $storeName => $row) { + $opening = $row['opening_balance']; + $income = $row['income']; + $expense = $row['expense']; $amount = $opening === null ? null : round($opening + $income - $expense, 2); diff --git a/tests/Unit/EcommerceFinance/StoreReceivingBalanceOverviewServiceTest.php b/tests/Unit/EcommerceFinance/StoreReceivingBalanceOverviewServiceTest.php index db7f23ea..1d55ae6c 100644 --- a/tests/Unit/EcommerceFinance/StoreReceivingBalanceOverviewServiceTest.php +++ b/tests/Unit/EcommerceFinance/StoreReceivingBalanceOverviewServiceTest.php @@ -284,6 +284,42 @@ class StoreReceivingBalanceOverviewServiceTest extends TestCase $this->assertFalse($unavailable['available']); } + public function test_balance_store_detail_merges_duplicate_store_rows_without_creating_zero_opening(): void + { + $service = new class extends StoreReceivingBalanceOverviewService { + public function __construct() + { + } + + protected function fetchPlatformStoreBalances(string $platform, string $start, string $end): array + { + return [[ + 'store_name' => '重复店铺', + 'opening_balance' => null, + 'income' => 5.0, + 'expense' => 0.0, + ], [ + 'store_name' => '重复店铺', + 'opening_balance' => null, + 'income' => 0.0, + 'expense' => 2.0, + ]]; + } + }; + + $result = $service->balanceStoreDetail('2026-10'); + $rows = array_values(array_filter( + $result['details'], + static fn (array $row): bool => $row['store_name'] === '重复店铺', + )); + + $this->assertCount(1, $rows); + $this->assertNull($rows[0]['opening_balance']); + $this->assertSame(5.0, $rows[0]['income']); + $this->assertSame(2.0, $rows[0]['expense']); + $this->assertNull($rows[0]['amount']); + } + public function test_monthly_closing_returns_july_to_october_for_all_platforms(): void { $monthOrdinal = ['2026-07' => 1, '2026-08' => 2, '2026-09' => 3, '2026-10' => 4];