so-manager-dev.com/app/Services/ShjThirteenService.php
Your Name 10a917b556
All checks were successful
Deploy so-manager (auto) / deploy (push) Successful in 24s
【更新】SHJ関連の修正
2025-10-10 19:55:46 +09:00

386 lines
13 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Models\Device;
use Carbon\Carbon;
/**
* SHJ-13 契約台数追加処理サービス
*
* 新規契約時の契約台数を park_number・zone テーブルに反映する処理
* SHJ-4B の副作用処理として実行される
*/
class ShjThirteenService
{
/**
* ShjEightService
*
* @var ShjEightService
*/
protected $shjEightService;
/**
* コンストラクタ
*
* @param ShjEightService $shjEightService
*/
public function __construct(ShjEightService $shjEightService)
{
$this->shjEightService = $shjEightService;
}
/**
* SHJ-13 契約台数追加処理実行
*
* 【処理1】契約台数を反映する - park_number・zone テーブルの契約台数を+1更新
* 【処理2】バッチ処理ログを作成する - SHJ-8共通仕様でログ登録
*
* @param array $contractData 契約データ
* @return array 処理結果
*/
public function execute(array $contractData): array
{
$startTime = now();
Log::info('SHJ-13 契約台数追加処理開始', [
'contract_id' => $contractData['contract_id'] ?? null,
'park_id' => $contractData['park_id'] ?? null,
'psection_id' => $contractData['psection_id'] ?? null,
'ptype_id' => $contractData['ptype_id'] ?? null,
'zone_id' => $contractData['zone_id'] ?? null,
]);
try {
// パラメータ検証
$validationResult = $this->validateParameters($contractData);
if (!$validationResult['valid']) {
return $this->createErrorResult(
1001,
'パラメータエラー: ' . $validationResult['message']
);
}
// 【処理1・2】契約台数反映とバッチログ作成を一体で実行
$processResult = $this->executeProcessWithLogging($contractData);
if (!$processResult['success']) {
return $this->createErrorResult(
$processResult['error_code'],
$processResult['error_message'],
$processResult['stack_trace'] ?? ''
);
}
$statusComment = $processResult['status_comment'];
$endTime = now();
Log::info('SHJ-13 契約台数追加処理完了', [
'contract_id' => $contractData['contract_id'],
'execution_time' => $startTime->diffInSeconds($endTime),
'updated_count' => $processResult['updated_count'],
'status_comment' => $statusComment,
]);
return ['result' => 0];
} catch (\Throwable $e) {
Log::error('SHJ-13 契約台数追加処理例外エラー', [
'contract_data' => $contractData,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
return $this->createErrorResult(
$e->getCode() ?: 1999,
$e->getMessage(),
$e->getTraceAsString()
);
}
}
/**
* パラメータ検証
*
* @param array $contractData
* @return array
*/
private function validateParameters(array $contractData): array
{
$errors = [];
if (empty($contractData['park_id'])) {
$errors[] = '駐輪場IDが設定されていません';
}
if (empty($contractData['psection_id'])) {
$errors[] = '車種区分IDが設定されていません';
}
if (empty($contractData['ptype_id'])) {
$errors[] = '駐輪分類IDが設定されていません';
}
if (empty($contractData['zone_id'])) {
$errors[] = 'ゾーンIDが設定されていません';
}
if (!empty($errors)) {
return [
'valid' => false,
'message' => implode(', ', $errors),
'details' => $errors,
];
}
return ['valid' => true];
}
/**
* 契約台数反映とバッチログ作成の一体処理
*
* park_number・zone テーブルの契約台数を+1更新し、バッチログを作成
* 全てを1つのトランザクション内で実行
*
* @param array $contractData
* @return array
*/
private function executeProcessWithLogging(array $contractData): array
{
try {
return DB::transaction(function() use ($contractData) {
// 各テーブルの名称取得
$names = $this->getTableNames($contractData);
if (!$names['success']) {
throw new \Exception('名称取得エラー: ' . $names['message'], 1002);
}
// park_number テーブル更新
$parkNumberUpdated = DB::table('park_number')
->where('park_id', $contractData['park_id'])
->where('psection_id', $contractData['psection_id'])
->where('ptype_id', $contractData['ptype_id'])
->increment('park_number', 1, [
'updated_at' => now(),
]);
if ($parkNumberUpdated === 0) {
throw new \Exception('park_numberテーブルの対象レコードが存在しません', 1011);
}
// zone テーブル更新
$zoneUpdated = DB::table('zone')
->where('zone_id', $contractData['zone_id'])
->increment('zone_number', 1, [
'updated_at' => now(),
]);
if ($zoneUpdated === 0) {
throw new \Exception('zoneテーブルの対象レコードが存在しません', 1012);
}
// 更新後の契約台数取得
$updatedZone = DB::table('zone')
->where('zone_id', $contractData['zone_id'])
->first(['zone_number']);
// ステータスコメント構築
$statusComment = $this->buildStatusComment($names['names'], $updatedZone->zone_number);
// バッチ処理ログ作成(同一トランザクション内)
// SHJ-8サービスを呼び出し
$device = Device::orderBy('device_id')->first();
$deviceId = $device ? $device->device_id : 1;
$today = now()->format('Y/m/d');
$this->shjEightService->execute(
$deviceId,
'SHJ-13',
'SHJ-13契約台数追加',
'success',
$statusComment,
$today,
$today
);
Log::info('SHJ-13 契約台数更新・ログ作成完了', [
'contract_id' => $contractData['contract_id'],
'park_number_updated' => $parkNumberUpdated,
'zone_updated' => $zoneUpdated,
'updated_count' => $updatedZone->zone_number,
'status_comment' => $statusComment,
]);
return [
'success' => true,
'updated_count' => $updatedZone->zone_number,
'status_comment' => $statusComment,
];
});
} catch (\Throwable $e) {
Log::error('SHJ-13 契約台数更新・ログ作成エラー', [
'contract_data' => $contractData,
'error_code' => $e->getCode(),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
return [
'success' => false,
'error_code' => $e->getCode() ?: 1010,
'error_message' => $e->getMessage(),
'stack_trace' => $e->getTraceAsString(),
];
}
}
/**
* テーブル名称取得
*
* @param array $contractData
* @return array
*/
private function getTableNames(array $contractData): array
{
try {
// 駐輪場名取得
$park = DB::table('park')
->where('park_id', $contractData['park_id'])
->first(['park_name']);
if (!$park) {
return [
'success' => false,
'message' => "駐輪場が見つかりません: park_id={$contractData['park_id']}",
];
}
// 駐輪分類名取得
$ptype = DB::table('ptype')
->where('ptype_id', $contractData['ptype_id'])
->first(['ptype_subject']);
if (!$ptype) {
return [
'success' => false,
'message' => "駐輪分類が見つかりません: ptype_id={$contractData['ptype_id']}",
];
}
// 車種区分名取得
$psection = DB::table('psection')
->where('psection_id', $contractData['psection_id'])
->first(['psection_subject']);
if (!$psection) {
return [
'success' => false,
'message' => "車種区分が見つかりません: psection_id={$contractData['psection_id']}",
];
}
// ゾーン名取得
$zone = DB::table('zone')
->where('zone_id', $contractData['zone_id'])
->first(['zone_name']);
if (!$zone) {
return [
'success' => false,
'message' => "ゾーンが見つかりません: zone_id={$contractData['zone_id']}",
];
}
return [
'success' => true,
'names' => [
'park_name' => $park->park_name,
'ptype_subject' => $ptype->ptype_subject,
'psection_subject' => $psection->psection_subject,
'zone_name' => $zone->zone_name,
],
];
} catch (\Throwable $e) {
return [
'success' => false,
'message' => 'テーブル名称取得エラー: ' . $e->getMessage(),
'details' => $e->getTraceAsString(),
];
}
}
/**
* ステータスコメント構築
*
* 形式:駐輪場名/駐輪分類名/車種区分名/ゾーン名/現在契約台数(更新後):{数値}
*
* @param array $names
* @param int $updatedCount
* @return string
*/
private function buildStatusComment(array $names, int $updatedCount): string
{
return sprintf(
'%s%s%s%s現在契約台数更新後%d',
$names['park_name'],
$names['ptype_subject'],
$names['psection_subject'],
$names['zone_name'],
$updatedCount
);
}
/**
* エラー結果作成SHJ-8ログも作成
*
* @param int $errorCode
* @param string $errorMessage
* @param string $stackTrace
* @return array
*/
private function createErrorResult(int $errorCode, string $errorMessage, string $stackTrace = ''): array
{
// エラー時もSHJ-8でバッチログを作成
try {
$device = Device::orderBy('device_id')->first();
$deviceId = $device ? $device->device_id : 1;
$today = now()->format('Y/m/d');
$statusComment = sprintf(
'エラーコード:%dエラーメッセージ%s',
$errorCode,
$errorMessage
);
$this->shjEightService->execute(
$deviceId,
'SHJ-13',
'SHJ-13契約台数追加',
'success', // 仕様書:エラー時も"success"で記録
$statusComment,
$today,
$today
);
Log::info('SHJ-13 エラー時バッチログ作成完了', [
'error_code' => $errorCode,
'status_comment' => $statusComment
]);
} catch (\Exception $e) {
Log::error('SHJ-13 エラー時バッチログ作成失敗', [
'error' => $e->getMessage()
]);
}
return [
'result' => 1,
'error_code' => $errorCode,
'error_message' => $errorMessage,
'stack_trace' => $stackTrace,
];
}
}