SHJ-4 SHJ-5改修
All checks were successful
Deploy api / deploy (push) Successful in 23s

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-02-06 10:42:35 +09:00
parent e3a60540be
commit 8499e0a01c
2 changed files with 49 additions and 37 deletions

View File

@ -234,6 +234,8 @@ class ShjFourCService
'T1.zone_standard as zone_standard',
'T1.zone_tolerance as zone_tolerance',
'T1.zone_sort',
'T1.zone_pplace_start', // 車室番号開始NULLの場合は1
'T1.zone_pplace_end', // 車室番号終了NULLの場合は許容台数まで
'T2.update_grace_period_start_date',
'T2.update_grace_period_end_date'
])
@ -270,10 +272,18 @@ class ShjFourCService
/**
* 【判断1】割当判定処理
*
* ゾーンIDごとにわか順(インクリメント、内部変数.対象番号とする)に
* ゾーン内標準台数に達するまで、定期契約マスタから該当する車室番号で
* ゾーンIDごとに車室番号開始から順(インクリメント、内部変数.対象番号とする)に
* 車室番号終了に達するまで、定期契約マスタから該当する車室番号で
* 契約済みの情報の有無を確認する
*
* 【パフォーマンス改善】
* 変更前: 各車室番号ごとに1回SQLクエリ最大1200回
* 変更後: ゾーンごとに使用中の車室番号を一括取得1回
*
* 【車室番号範囲対応】
* zone_pplace_start: 開始番号NULLの場合は1
* zone_pplace_end: 終了番号NULLの場合は開始番号+許容台数-1
*
* @param array $zoneInfo ゾーン情報
* @param int $parkId 駐輪場ID
* @param int $ptypeId 駐輪分類ID
@ -284,19 +294,22 @@ class ShjFourCService
{
try {
foreach ($zoneInfo as $zone) {
// ゾーン内標準台数まで車室番号をインクリメントして検索
for ($pplaceNo = 1; $pplaceNo <= $zone->zone_standard; $pplaceNo++) {
// 該当する車室番号で契約済みの情報の有無を確認
$contractInfo = $this->getRegularContractInfo(
$parkId,
$zone->zone_id,
$pplaceNo,
(int) $zone->update_grace_period_start_date,
(int) $zone->update_grace_period_end_date
);
// 【改善】使用中の車室番号を一括取得1回のクエリ
$occupiedNumbers = $this->getOccupiedRoomNumbers(
$parkId,
$zone->zone_id,
(int) $zone->update_grace_period_start_date,
(int) $zone->update_grace_period_end_date
);
// 契約情報が存在しない場合、この車室番号は空き
if ($contractInfo === null) {
// 【車室番号範囲対応】開始・終了番号を取得
$start = $zone->zone_pplace_start ?? 1;
$end = $zone->zone_pplace_end ?? ($start + $zone->zone_tolerance - 1);
// PHP側で空き番号を検索開始番号から終了番号まで
for ($pplaceNo = $start; $pplaceNo <= $end; $pplaceNo++) {
// 使用中でなければ空き
if (!in_array($pplaceNo, $occupiedNumbers, true)) {
Log::info('SHJ-4C 割当OK', [
'zone_id' => $zone->zone_id,
'zone_name' => $zone->zone_name,
@ -342,48 +355,47 @@ class ShjFourCService
}
/**
* 定期契約情報取得
* 使用中の車室番号を一括取得
*
* 設計書のSQLクエリに基づく定期契約マスタ検索
* 特定の車室番号で契約済みの情報の有無を確認する
* 【パフォーマンス改善】
* 1ゾーンあたり1回のSQLクエリで全ての使用中車室番号を取得
*
* @param int $parkId 駐輪場ID
* @param int $zoneId ゾーンID
* @param int $pplaceNo 車室番号(対象番号)
* @param int $updateGracePeriodStartDate 更新期間開始日
* @param int $updateGracePeriodEndDate 更新期間終了日
* @return array|null 定期契約情報存在しない場合はnull
* @return array 使用中の車室番号配列
*/
private function getRegularContractInfo(
private function getOccupiedRoomNumbers(
int $parkId,
int $zoneId,
int $pplaceNo,
int $updateGracePeriodStartDate,
int $updateGracePeriodEndDate
): ?array {
$currentDate = Carbon::now()->format('y.%m.%d');
): array {
$currentDate = Carbon::now()->format('Y-m-d');
$query = DB::table('regular_contract as T1')
->select(['T1.contract_id'])
->select('T1.pplace_no')
->where('T1.park_id', $parkId)
->where('T1.zone_id', $zoneId)
->where('T1.pplace_no', $pplaceNo);
->where('T1.contract_flag', 1)
->whereNotNull('T1.pplace_no');
// 【「JOB1.更新期間開始日」<=「JOB1. 更新期間終了日」の場合】
// パターンA/B の条件(既存ロジックと同じ)
if ($updateGracePeriodStartDate <= $updateGracePeriodEndDate) {
// パターンA: T1.有効期間E >= date_format(now(), '%y.%m.%d')
$query->whereRaw("date_format(T1.contract_periode, '%y.%m.%d') >= ?", [$currentDate]);
// パターンA: 有効期間E >= 現在日付
$query->where('T1.contract_periode', '>=', $currentDate);
} else {
// 【その他の場合】
// パターンB: T1.有効期間E + 「JOB1. 更新期間終了日」>= date_format(now(), '%y.%m.%d')
$query->whereRaw("DATE_ADD(T1.contract_periode, INTERVAL ? DAY) >= ?", [$updateGracePeriodEndDate, $currentDate]);
// パターンB: 有効期間E + 更新期間終了日 >= 現在日付
$query->whereRaw(
"DATE_ADD(T1.contract_periode, INTERVAL ? DAY) >= ?",
[$updateGracePeriodEndDate, $currentDate]
);
}
$query->where('T1.contract_flag', 1);
$result = $query->first();
return $result ? (array) $result : null;
return $query->pluck('pplace_no')->map(function ($val) {
return (int) $val;
})->toArray();
}
/**

View File

@ -12,7 +12,7 @@ class ExampleTest extends TestCase
*/
public function test_the_application_returns_a_successful_response(): void
{
$response = $this->get('/');
$response = $this->get('/up');
$response->assertStatus(200);
}