'店铺A', 'company_name' => '原主体'], ['erp_store_name' => '店铺B', 'company_name' => '原主体'], ]; $reportStores = array_map( static fn (array $store): array => $store + ['system_company_name' => $store['company_name']], $stores, ); $businessInformation = Mockery::mock(BusinessInformationMirrorRepository::class); $businessInformation->shouldReceive('receivingAccountStores')->once()->andReturn($stores); $storeReports = Mockery::mock(StoreReportRepository::class); $storeReports->shouldReceive('rows') ->once() ->with($reportStores, 2026, []) ->andReturn([ ['entity' => '示例甲有限公司', 'income_10' => 1000000], ['entity' => '示例甲有限公司', 'income_10' => 250000.5], ['entity' => '示例乙有限公司', 'income_10' => 0], ['entity' => '示例丙有限公司', 'income_10' => null], ['entity' => '', 'income_10' => 999999], ]); $projection = new InternalFlowProjection($businessInformation, $storeReports); $result = $projection->forMonth(CarbonImmutable::create(2026, 11, 9, 10, 0, 0, 'Asia/Shanghai')); $this->assertSame('2026-11', $result['forecast_month']); $this->assertSame('11月', $result['forecast_month_label']); $this->assertSame('2026-10', $result['source_month']); $this->assertSame('10月', $result['source_month_label']); $this->assertEqualsWithDelta(1250000.5, $result['sales_by_company']['示例甲有限公司'], 0.000001); $this->assertSame(0.0, $result['sales_by_company']['示例乙有限公司']); $this->assertNull($result['sales_by_company']['示例丙有限公司']); $this->assertArrayNotHasKey('', $result['sales_by_company']); } public function testJanuaryForecastReadsDecemberOfPreviousYear(): void { $stores = [['erp_store_name' => '店铺A', 'company_name' => '示例甲有限公司']]; $reportStores = [ $stores[0] + ['system_company_name' => $stores[0]['company_name']], ]; $businessInformation = Mockery::mock(BusinessInformationMirrorRepository::class); $businessInformation->shouldReceive('receivingAccountStores')->once()->andReturn($stores); $storeReports = Mockery::mock(StoreReportRepository::class); $storeReports->shouldReceive('rows') ->once() ->with($reportStores, 2025, []) ->andReturn([['entity' => '示例甲有限公司', 'income_12' => 880000]]); $projection = new InternalFlowProjection($businessInformation, $storeReports); $result = $projection->forMonth(CarbonImmutable::create(2026, 1, 5, 12, 0, 0, 'Asia/Shanghai')); $this->assertSame('2026-01', $result['forecast_month']); $this->assertSame('2025-12', $result['source_month']); $this->assertEqualsWithDelta(880000.0, $result['sales_by_company']['示例甲有限公司'], 0.000001); } }