支持进销存报表七月数据 #248
@ -60,6 +60,9 @@ class ThirdPartyWarehouseStorageMirrorRepository
|
||||
|
||||
public const START_DATE = '2026-08-01';
|
||||
|
||||
/** Historical monthly report range can start one month before the flow page. */
|
||||
private const INVENTORY_REPORT_START_DATE = '2026-07-01';
|
||||
|
||||
/** @var array<string,string> */
|
||||
private const MOVEMENT_COLUMNS = [
|
||||
'processing_in' => '加工进仓',
|
||||
@ -299,10 +302,7 @@ class ThirdPartyWarehouseStorageMirrorRepository
|
||||
}
|
||||
$page = max($page, 1);
|
||||
$perPage = min(max($perPage, 1), 5000);
|
||||
$period = $this->period([
|
||||
'dimension' => 'month',
|
||||
'period' => $filters['month'] ?? '',
|
||||
]);
|
||||
$period = $this->inventoryReportPeriod((string) ($filters['month'] ?? ''));
|
||||
$authoritative = $this->monthlyInventoryAuthoritativeQuery($period, $filters);
|
||||
if ($authoritative !== null) {
|
||||
$total = $includeTotal ? (clone $authoritative)->count() : 0;
|
||||
@ -1316,6 +1316,31 @@ class ThirdPartyWarehouseStorageMirrorRepository
|
||||
];
|
||||
}
|
||||
|
||||
/** @return array{dimension:string,value:string,start:string,end:string,days:int} */
|
||||
private function inventoryReportPeriod(string $month): array
|
||||
{
|
||||
try {
|
||||
$start = preg_match('/^\d{4}-\d{2}$/', trim($month)) === 1
|
||||
? Carbon::createFromFormat('!Y-m', trim($month))->startOfMonth()
|
||||
: now()->startOfMonth();
|
||||
} catch (Throwable) {
|
||||
$start = now()->startOfMonth();
|
||||
}
|
||||
|
||||
$minimum = Carbon::parse(self::INVENTORY_REPORT_START_DATE)->startOfMonth();
|
||||
if ($start->lt($minimum)) {
|
||||
$start = $minimum;
|
||||
}
|
||||
|
||||
return [
|
||||
'dimension' => 'month',
|
||||
'value' => $start->format('Y-m'),
|
||||
'start' => $start->format('Y-m-d 00:00:00'),
|
||||
'end' => $start->copy()->addMonth()->format('Y-m-d 00:00:00'),
|
||||
'days' => $start->daysInMonth,
|
||||
];
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $state */
|
||||
private function stateAnchor(array $state): string
|
||||
{
|
||||
|
||||
@ -12,7 +12,7 @@ class ThirdPartyWarehouseStorageUpstreamRepository
|
||||
/** 三方仓页面仍固定读取该仓;共享流水镜像覆盖全部仓库。 */
|
||||
public const WAREHOUSE_ID = 15045364;
|
||||
|
||||
public const START_DATE = '2026-08-01';
|
||||
public const START_DATE = '2026-07-01';
|
||||
|
||||
private ?UpstreamReadOnlyQuery $query = null;
|
||||
|
||||
|
||||
@ -400,22 +400,30 @@ class ThirdPartyWarehouseStorageMirrorRepositoryTest extends TestCase
|
||||
$this->assertFalse($this->repository->allWarehousesReady());
|
||||
}
|
||||
|
||||
public function test_periods_before_the_supported_start_date_are_clamped(): void
|
||||
public function test_monthly_inventory_report_supports_july_without_changing_flow_page_cutoff(): void
|
||||
{
|
||||
$this->markReady();
|
||||
$this->insertProduct('SKU-CUTOFF');
|
||||
$this->insertInventory('SKU-CUTOFF', 2, '2026-08-02 00:00:00');
|
||||
$this->insertInventory('SKU-CUTOFF', 10, '2026-08-01 00:00:00');
|
||||
$this->insertMovement('SKU-CUTOFF', '采购进仓', 2, 1, '2026-07-15 12:00:00');
|
||||
$this->insertMovement('SKU-CUTOFF', '采购进仓', 2, 1, '2026-08-01 12:00:00');
|
||||
|
||||
$day = $this->repository->paginate($this->filters([
|
||||
'dimension' => 'day',
|
||||
'period' => '2026-07-01',
|
||||
]), 1, 25)['data'][0];
|
||||
$month = $this->repository->paginate($this->filters(['period' => '2026-07']), 1, 100)['data'];
|
||||
$inventoryReport = $this->repository->paginateMonthlyInventoryReport([
|
||||
'month' => '2026-07',
|
||||
'product_code' => 'SKU-CUTOFF',
|
||||
'warehouse_provider' => '',
|
||||
'category' => '',
|
||||
], 1, 25);
|
||||
|
||||
$this->assertSame('2026-08-01', $day['date']);
|
||||
$this->assertSame('2026-08-01', $month[0]['date']);
|
||||
$this->assertSame('2026-08-31', $month[30]['date']);
|
||||
$this->assertSame(1, $inventoryReport['total']);
|
||||
$this->assertSame('2026-07-01', $inventoryReport['data'][0]->month);
|
||||
$this->assertSame(8.0, (float) $inventoryReport['data'][0]->opening_quantity);
|
||||
$this->assertSame(10.0, (float) $inventoryReport['data'][0]->closing_quantity);
|
||||
}
|
||||
|
||||
public function test_product_catalog_must_finish_initial_sync_before_product_fields_are_exposed(): void
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user