From fff243cc66a533a208699aa474277c3a8af14a74 Mon Sep 17 00:00:00 2001 From: "sosuke.iwabuchi" Date: Fri, 8 Sep 2023 12:20:00 +0900 Subject: [PATCH] =?UTF-8?q?=E5=85=A8=E4=BD=93=E6=95=B4=E5=82=99=E3=80=80?= =?UTF-8?q?=E5=AE=9A=E6=9C=9F=E5=A5=91=E7=B4=84=E5=91=A8=E3=82=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Web/Auth/LoginController.php | 11 ++- .../SeasonTicketContractsController.php | 43 ++++++++++++ .../SeasonTicketContractsParam.php | 15 +++++ app/Kintone/KintoneAccess.php | 47 +++++++++++++ app/Kintone/Models/Customer.php | 10 +-- app/Kintone/Models/KintoneModel.php | 15 ++++- app/Kintone/Models/Paking.php | 23 +++++++ app/Kintone/Models/ParkingRoom.php | 29 ++++++++ app/Kintone/Models/SeasonTicketContract.php | 25 ++++--- .../SeasonTicketContractRepository.php | 57 ++++++++++++++++ .../SeasonTicketContractRepositoryData.php | 23 +++++++ config/kintone.php | 1 + .../2014_10_12_000000_create_users_table.php | 4 ++ routes/api.php | 2 + .../SeasonTicketContractRepositoryTest.php | 16 +++++ tests/Feature/KintoneAccessTest.php | 67 ++++++++----------- 16 files changed, 332 insertions(+), 56 deletions(-) create mode 100644 app/Http/Controllers/Web/SeasonTicketContract/SeasonTicketContractsController.php create mode 100644 app/Http/Controllers/Web/SeasonTicketContract/SeasonTicketContractsParam.php create mode 100644 app/Kintone/Models/Paking.php create mode 100644 app/Kintone/Models/ParkingRoom.php create mode 100644 app/Kintone/Repositories/SeasonTicketContractRepository.php create mode 100644 app/Kintone/Repositories/SeasonTicketContractRepositoryData.php create mode 100644 tests/Feature/Kintone/SeasonTicketContractRepositoryTest.php diff --git a/app/Http/Controllers/Web/Auth/LoginController.php b/app/Http/Controllers/Web/Auth/LoginController.php index bde7113..938e072 100644 --- a/app/Http/Controllers/Web/Auth/LoginController.php +++ b/app/Http/Controllers/Web/Auth/LoginController.php @@ -37,7 +37,7 @@ class LoginController extends WebController $access = Customer::getAccess(); $query = Customer::getQuery()->where(Customer::FIELD_EMAIL, $param->email); - $customer = $access->all($query); + $customer = $access->some($query); if ($customer->count() !== 1) { return $this->failedResponse(); @@ -55,10 +55,18 @@ class LoginController extends WebController if ($user instanceof User) { // すでにユーザー登録されているケース + + //データ同期 if ($user->email !== $param->email) { $user->email = $param->email; $user->save(); } + if ($user->kintone_customer_code !== $customer->getNumber(Customer::FIELD_CUSTOMER_CODE)) { + $user->kintone_customer_code = $customer->getNumber(Customer::FIELD_CUSTOMER_CODE); + $user->save(); + } + + if (Auth::attempt([ 'email' => $param->email, 'password' => $param->password, @@ -74,6 +82,7 @@ class LoginController extends WebController $user->email = $param->email; $user->kintone_id = $customer->getRecordId(); $user->password = $password; + $user->kintone_customer_code = $customer->getNumber(Customer::FIELD_CUSTOMER_CODE); $user->save(); if (Auth::attempt([ 'email' => $param->email, diff --git a/app/Http/Controllers/Web/SeasonTicketContract/SeasonTicketContractsController.php b/app/Http/Controllers/Web/SeasonTicketContract/SeasonTicketContractsController.php new file mode 100644 index 0000000..9c96fa8 --- /dev/null +++ b/app/Http/Controllers/Web/SeasonTicketContract/SeasonTicketContractsController.php @@ -0,0 +1,43 @@ +middleware('auth:sanctum'); + } + + protected function run(Request $request): JsonResponse + { + $user = Auth::user(); + + $list = SeasonTicketContractRepository::get($user->kintone_customer_code); + + foreach ($list as $ele) { + $result[] = $ele->toArray(); + } + + return $this->successResponse($result); + } +} diff --git a/app/Http/Controllers/Web/SeasonTicketContract/SeasonTicketContractsParam.php b/app/Http/Controllers/Web/SeasonTicketContract/SeasonTicketContractsParam.php new file mode 100644 index 0000000..730267f --- /dev/null +++ b/app/Http/Controllers/Web/SeasonTicketContract/SeasonTicketContractsParam.php @@ -0,0 +1,15 @@ + + */ + public function some(KintoneRecordQuery|null $query = null) + { + + $data = [ + "app" => $this->appId, + 'fields' => $this->fields, + ]; + if ($query !== null) { + $data["query"] = $query->toQuery(); + } + + $response = Http::withHeaders([ + "X-Cybozu-API-Token" => $this->apiToken, + ])->get($this->getRecordsUrl(), $data); + + if ($response->failed()) { + $e = $response->toException(); + if ($e instanceof Exception) { + Log::error($e->getMessage()); + throw $e; + } + } + + $ret = collect(); + + foreach ($response["records"] as $data) { + /** + * @var KintoneModel $model + */ + $model = new $this->appName(); + + $model->setDataFromRecordResponse($data); + $ret->put($model->getRecordId(), $model); + } + + return $ret; + } + /** * @param TValue $model * @return void @@ -340,6 +383,10 @@ class KintoneAccess { return $this->getUrl(self::URL_RECORD); } + private function getRecordsUrl() + { + return $this->getUrl(self::URL_RECORDS); + } private function getCursorUrl() { diff --git a/app/Kintone/Models/Customer.php b/app/Kintone/Models/Customer.php index f72ef20..bc56eb7 100644 --- a/app/Kintone/Models/Customer.php +++ b/app/Kintone/Models/Customer.php @@ -2,15 +2,20 @@ namespace App\Kintone\Models; +/** + * アプリ名 顧客マスタ + */ class Customer extends KintoneModel { const CONFIG_KEY = "KINTONE_APP_CUSTOMER"; + const FIELD_CUSTOMER_CODE = "CustomerCode"; const FIELD_CUSTOMER_NAME = "CustomerName"; const FIELD_EMAIL = "メールアドレス"; protected const FIELDS = [ ...parent::FIELDS, + self::FIELD_CUSTOMER_CODE => FieldType::NUMBER, self::FIELD_CUSTOMER_NAME => FieldType::SINGLE_LINE_TEXT, self::FIELD_EMAIL => FieldType::LINK, ]; @@ -20,9 +25,4 @@ class Customer extends KintoneModel self::FIELD_CUSTOMER_NAME => 'customer_name', self::FIELD_EMAIL => 'email', ]; - - protected function setDataCustom(array $data): bool - { - return true; - } } diff --git a/app/Kintone/Models/KintoneModel.php b/app/Kintone/Models/KintoneModel.php index 81e6731..0e8c836 100644 --- a/app/Kintone/Models/KintoneModel.php +++ b/app/Kintone/Models/KintoneModel.php @@ -162,7 +162,7 @@ abstract class KintoneModel $type = FieldType::tryFrom($type); if ($type === null) continue; - if ($type === FieldType::DATETIME) { + if (in_array($type, [FieldType::DATETIME, FieldType::DATE])) { if ($value) { data_set($this->data, $fieldCode, DateUtil::parse($value)); } else { @@ -302,7 +302,10 @@ abstract class KintoneModel $type = data_get(static::FIELDS, $fieldCode); - $columnName = data_get(static::FIELD_NAMES, $fieldCode, $fieldCode); + $columnName = data_get(static::FIELD_NAMES, $fieldCode, null); + if ($columnName === null) { + continue; + } if ($type === null) { $ret[$columnName] = $value; @@ -317,6 +320,14 @@ abstract class KintoneModel } continue; } + if ($type === FieldType::DATE) { + if ($value instanceof Carbon) { + $ret[$columnName] = $value->format('Y/m/d'); + } else { + $ret[$columnName] = $value; + } + continue; + } $ret[$columnName] = $value; diff --git a/app/Kintone/Models/Paking.php b/app/Kintone/Models/Paking.php new file mode 100644 index 0000000..03fc016 --- /dev/null +++ b/app/Kintone/Models/Paking.php @@ -0,0 +1,23 @@ + FieldType::SINGLE_LINE_TEXT, + ]; + + protected const FIELD_NAMES = [ + ...parent::FIELD_NAMES, + self::FIELD_PARKING_NAME => 'parking_name', + ]; +} diff --git a/app/Kintone/Models/ParkingRoom.php b/app/Kintone/Models/ParkingRoom.php new file mode 100644 index 0000000..5f24223 --- /dev/null +++ b/app/Kintone/Models/ParkingRoom.php @@ -0,0 +1,29 @@ + FieldType::SINGLE_LINE_TEXT, + self::FIELD_ROOM_NO => FieldType::SINGLE_LINE_TEXT, + self::FIELD_SEASON_TICKET_CONTRACT_RECORD_NO => FieldType::NUMBER, + ]; + + protected const FIELD_NAMES = [ + ...parent::FIELD_NAMES, + self::FIELD_PARKING_NAME => 'parking_name', + self::FIELD_ROOM_NO => 'room_no', + self::FIELD_SEASON_TICKET_CONTRACT_RECORD_NO => 'season_ticekt_contract_record_no', + ]; +} diff --git a/app/Kintone/Models/SeasonTicketContract.php b/app/Kintone/Models/SeasonTicketContract.php index 5c896d3..44659c2 100644 --- a/app/Kintone/Models/SeasonTicketContract.php +++ b/app/Kintone/Models/SeasonTicketContract.php @@ -2,24 +2,33 @@ namespace App\Kintone\Models; +/** + * アプリ名 車室情報管理 + */ class SeasonTicketContract extends KintoneModel { const CONFIG_KEY = "KINTONE_APP_SEASON_TICKET_CONTRACT"; - const FIELD_CUSTOMER_NAME = "顧客名"; + const FIELD_CUSTOMER_CODE = "顧客コード"; + const FIELD_SEASON_TICKET_SEQ_NO = "定期券番号_0"; + const FIELD_VEHICLE_NO = "車両番号"; + const FIELD_CONTRACT_START_DATE = "契約日"; + const FIELD_CONTRACT_END_DATE = "解約日"; protected const FIELDS = [ ...parent::FIELDS, - self::FIELD_CUSTOMER_NAME => FieldType::SINGLE_LINE_TEXT, + self::FIELD_CUSTOMER_CODE => FieldType::NUMBER, + self::FIELD_SEASON_TICKET_SEQ_NO => FieldType::SINGLE_LINE_TEXT, + self::FIELD_VEHICLE_NO => FieldType::SINGLE_LINE_TEXT, + self::FIELD_CONTRACT_START_DATE => FieldType::DATE, + self::FIELD_CONTRACT_END_DATE => FieldType::DATE, ]; protected const FIELD_NAMES = [ ...parent::FIELD_NAMES, - self::FIELD_CUSTOMER_NAME => 'customer_name', + self::FIELD_SEASON_TICKET_SEQ_NO => 'season_ticket_seq_no', + self::FIELD_VEHICLE_NO => 'vehicle_no', + self::FIELD_CONTRACT_START_DATE => 'contract_start_date', + self::FIELD_CONTRACT_END_DATE => 'contract_end_date', ]; - - protected function setDataCustom(array $data): bool - { - return true; - } } diff --git a/app/Kintone/Repositories/SeasonTicketContractRepository.php b/app/Kintone/Repositories/SeasonTicketContractRepository.php new file mode 100644 index 0000000..3c36487 --- /dev/null +++ b/app/Kintone/Repositories/SeasonTicketContractRepository.php @@ -0,0 +1,57 @@ + + */ + static function get(string $customerCode): Collection + { + $ret = collect(); + + $query = SeasonTicketContract::getQuery() + ->where(SeasonTicketContract::FIELD_CUSTOMER_CODE, $customerCode); + $seasonTicketContracts = SeasonTicketContract::getAccess() + ->some($query); + + + $recordIds = []; + foreach ($seasonTicketContracts as $seasonTicketContract) { + $recordIds[] = $seasonTicketContract->getRecordId(); + } + $query = ParkingRoom::getQuery() + ->whereIn(ParkingRoom::FIELD_SEASON_TICKET_CONTRACT_RECORD_NO, $recordIds); + $parkings = ParkingRoom::getAccess() + ->some($query); + + + /** + * @var Collection + */ + $parkingsBySeasonTicketContractRecordId = collect(); + + foreach ($parkings as $parking) { + $parkingsBySeasonTicketContractRecordId->put($parking->getNumber(ParkingRoom::FIELD_SEASON_TICKET_CONTRACT_RECORD_NO), $parking); + } + + /** + * @var SeasonTicketContract $seasonTicketContract + */ + foreach ($seasonTicketContracts as $seasonTicketContract) { + $parking = null; + $parking = $parkingsBySeasonTicketContractRecordId->get($seasonTicketContract->getRecordId(), null); + + $ret->put($seasonTicketContract->getRecordId(), new SeasonTicketContractRepositoryData($seasonTicketContract, $parking)); + } + + return $ret; + } +} diff --git a/app/Kintone/Repositories/SeasonTicketContractRepositoryData.php b/app/Kintone/Repositories/SeasonTicketContractRepositoryData.php new file mode 100644 index 0000000..384efe9 --- /dev/null +++ b/app/Kintone/Repositories/SeasonTicketContractRepositoryData.php @@ -0,0 +1,23 @@ +parkingRoom !== null ? $this->parkingRoom->toArray() : [], + ...$this->seasonTicketContract->toArray(), + ]; + } +} diff --git a/config/kintone.php b/config/kintone.php index 04ab04e..318a81e 100644 --- a/config/kintone.php +++ b/config/kintone.php @@ -27,6 +27,7 @@ return [ 'applications' => [ ...App\Kintone\Models\Customer::setConfig(), + ...App\Kintone\Models\ParkingRoom::setConfig(), ...App\Kintone\Models\SeasonTicketContract::setConfig(), ], diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 6856d34..cfc308d 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -18,9 +18,11 @@ return new class extends Migration $table->string('email')->unique()->comment('Email'); $table->string('password')->comment('ログインパスワード'); $table->string('kintone_id')->comment('KintoneID'); + $table->string('kintone_customer_code')->comment('顧客コード'); $helper->index(1, ['email']); $helper->index(2, ['kintone_id']); + $helper->index(3, ['kintone_customer_code']); }); Schema::create('user_histories', function (Blueprint $table) { $helper = new MigrationHelper($table, true); @@ -29,9 +31,11 @@ return new class extends Migration $table->string('email')->comment('Email'); $table->string('password')->comment('ログインパスワード'); $table->string('kintone_id')->comment('KintoneID'); + $table->string('kintone_customer_code')->comment('顧客コード'); $helper->index(1, ['email']); $helper->index(2, ['kintone_id']); + $helper->index(3, ['kintone_customer_code']); }); } diff --git a/routes/api.php b/routes/api.php index 00e6310..e0e4090 100644 --- a/routes/api.php +++ b/routes/api.php @@ -17,3 +17,5 @@ use App\Util\RouteHelper; RouteHelper::post('/login', App\Http\Controllers\Web\Auth\LoginController::class); RouteHelper::get('/logout', App\Http\Controllers\Web\Auth\LogoutController::class); RouteHelper::get('/me', App\Http\Controllers\Web\Auth\MeController::class); + +RouteHelper::get('/season-ticket-contracts', App\Http\Controllers\Web\SeasonTicketContract\SeasonTicketContractsController::class); diff --git a/tests/Feature/Kintone/SeasonTicketContractRepositoryTest.php b/tests/Feature/Kintone/SeasonTicketContractRepositoryTest.php new file mode 100644 index 0000000..1198029 --- /dev/null +++ b/tests/Feature/Kintone/SeasonTicketContractRepositoryTest.php @@ -0,0 +1,16 @@ +assertCount(1, $list); + } +} diff --git a/tests/Feature/KintoneAccessTest.php b/tests/Feature/KintoneAccessTest.php index 92d78c6..5aabec1 100644 --- a/tests/Feature/KintoneAccessTest.php +++ b/tests/Feature/KintoneAccessTest.php @@ -4,68 +4,55 @@ namespace Tests\Feature; use App\Kintone\Models\Customer; use App\Kintone\Models\SeasonTicketContract; +use Illuminate\Support\Carbon; use Tests\TestCase; class KintoneAccessTest extends TestCase { - public function test_find(): void - { - $access = SeasonTicketContract::getAccess(); - - /** - * @var SeasonTicketContract - */ - $model = $access->find(505); - - $this->assertEquals("塩山兼司", $model->getStr(SeasonTicketContract::FIELD_CUSTOMER_NAME)); - } public function test_all(): void { - $model = new SeasonTicketContract(); - - $access = SeasonTicketContract::getAccess(); - $query = SeasonTicketContract::getQuery(); - $query->where(SeasonTicketContract::FIELD_CUSTOMER_NAME, "井出侑加"); - $ret = $access->all($query); + $access = Customer::getAccess(); + $query = Customer::getQuery(); + $query->where(Customer::FIELD_CUSTOMER_NAME, "岩渕奏亮(テスト)"); - $this->assertEquals(1, $ret->count()); + $list = $access->all($query); + $this->assertEquals(1, $list->count()); - /** - * @var SeasonTicketContract - */ - $model = $ret[0]; + $model = $list->firstOrFail(); - $this->assertEquals("井出侑加", $model->getStr(SeasonTicketContract::FIELD_CUSTOMER_NAME)); + $this->assertEquals("岩渕奏亮(テスト)", $model->getStr(Customer::FIELD_CUSTOMER_NAME)); + $this->assertEquals("test@aa.com", $model->getStr(Customer::FIELD_EMAIL)); - $array = $model->toArray(); - $this->assertEquals("井出侑加", $array['customer_name']); + $array = $model->toArray([Customer::FIELD_CUSTOMER_NAME, Customer::FIELD_EMAIL]); + $this->assertEquals("岩渕奏亮(テスト)", $array['customer_name']); + $this->assertEquals("test@aa.com", $array['email']); } - - public function test_customer(): void + public function test_some(): void { - $access = Customer::getAccess(); - $query = Customer::getQuery(); - $query->where(Customer::FIELD_CUSTOMER_NAME, "山下千晶"); + $access = SeasonTicketContract::getAccess(); + $query = SeasonTicketContract::getQuery(); + $query->where(SeasonTicketContract::FIELD_CUSTOMER_CODE, "9362"); - $list = $access->all($query); + $list = $access->some($query); $this->assertEquals(1, $list->count()); - /** - * @var Customer - */ - $model = $list[0]; + $model = $list->firstOrFail(); - $this->assertEquals("山下千晶", $model->getStr(Customer::FIELD_CUSTOMER_NAME)); - $this->assertEquals("shi.yy16@gmail.com", $model->getStr(Customer::FIELD_EMAIL)); + $this->assertEquals("", $model->getStr(SeasonTicketContract::FIELD_SEASON_TICKET_SEQ_NO)); + $this->assertEquals("交野市 て 1095", $model->getStr(SeasonTicketContract::FIELD_VEHICLE_NO)); + $this->assertEquals(new Carbon("2023-05-01"), $model->getDate(SeasonTicketContract::FIELD_CONTRACT_START_DATE)); + $this->assertEquals(new Carbon("2121-12-31"), $model->getDate(SeasonTicketContract::FIELD_CONTRACT_END_DATE)); - $array = $model->toArray([Customer::FIELD_CUSTOMER_NAME, Customer::FIELD_EMAIL]); - $this->assertEquals("山下千晶", $array['customer_name']); - $this->assertEquals("shi.yy16@gmail.com", $array['email']); + $array = $model->toArray(); + $this->assertEquals("", $array['season_ticket_seq_no']); + $this->assertEquals("交野市 て 1095", $array['vehicle_no']); + $this->assertEquals("2023/05/01", $array['contract_start_date']); + $this->assertEquals("2121/12/31", $array['contract_end_date']); } }