| @@ -0,0 +1,22 @@ | |||
| <?php | |||
| namespace App\Kintone; | |||
| class File | |||
| { | |||
| public string $contentType; | |||
| public string $fileKey; | |||
| public string $name; | |||
| public int $size; | |||
| public function __construct($param = null) | |||
| { | |||
| if ($param !== null) { | |||
| $this->contentType = data_get($param, "contentType", ""); | |||
| $this->fileKey = data_get($param, "fileKey", ""); | |||
| $this->name = data_get($param, "name", ""); | |||
| $this->size = (int)data_get($param, "size", 0); | |||
| } | |||
| } | |||
| } | |||
| @@ -10,6 +10,9 @@ use Illuminate\Support\Collection; | |||
| use Illuminate\Support\Facades\Http; | |||
| use Log; | |||
| /** | |||
| * @template TValue of KintoneModel | |||
| */ | |||
| class KintoneAccess | |||
| { | |||
| @@ -18,12 +21,21 @@ class KintoneAccess | |||
| private string $apiToken; | |||
| private int $appId; | |||
| private const DEFAULT_FIELDS = [ | |||
| KintoneModel::FIELD_RECORD_NUMBER, | |||
| KintoneModel::FIELD_UPDATED_TIME, | |||
| KintoneModel::FIELD_RECORD_NUMBER, | |||
| ]; | |||
| private array $fields = []; | |||
| private string|null $cursor = null; | |||
| private int $cursorDataCount = 0; | |||
| private bool $hasNext = false; | |||
| private const URL_RECORD = "/k/v1/record.json"; | |||
| private const URL_CURSOL = "/k/v1/records/cursor.json"; | |||
| private const URL_FILE = "/k/v1/file.json"; | |||
| public function __construct(string $appName) | |||
| @@ -53,12 +65,26 @@ class KintoneAccess | |||
| $this->appId = $appId; | |||
| } | |||
| public function setFields(array $fields): static | |||
| { | |||
| $this->fields = [ | |||
| ...$fields, | |||
| ...self::DEFAULT_FIELDS, | |||
| ]; | |||
| return $this; | |||
| } | |||
| public function __destruct() | |||
| { | |||
| $this->deleteCursor(); | |||
| } | |||
| /** | |||
| * @param integer $id | |||
| * @param TValue $result | |||
| * @return Response | |||
| */ | |||
| public function find(int $id, KintoneModel &$result): Response | |||
| { | |||
| @@ -67,11 +93,13 @@ class KintoneAccess | |||
| ])->get($this->getRecordUrl(), [ | |||
| "app" => $this->appId, | |||
| "id" => $id, | |||
| 'fields' => $this->fields, | |||
| ]); | |||
| if ($response->failed()) { | |||
| $e = $response->toException(); | |||
| if ($e instanceof Exception) { | |||
| Log::error($e->getMessage()); | |||
| throw $e; | |||
| } | |||
| } | |||
| @@ -80,6 +108,10 @@ class KintoneAccess | |||
| return $response; | |||
| } | |||
| /** | |||
| * @param TValue $model | |||
| * @return void | |||
| */ | |||
| public function update(KintoneModel &$model) | |||
| { | |||
| $response = Http::withHeaders([ | |||
| @@ -94,6 +126,7 @@ class KintoneAccess | |||
| if ($response->failed()) { | |||
| $e = $response->toException(); | |||
| if ($e instanceof Exception) { | |||
| Log::error($e->getMessage()); | |||
| throw $e; | |||
| } | |||
| } | |||
| @@ -102,6 +135,10 @@ class KintoneAccess | |||
| return $response; | |||
| } | |||
| /** | |||
| * @param TValue $model | |||
| * @return void | |||
| */ | |||
| public function create(KintoneModel &$model) | |||
| { | |||
| $response = Http::withHeaders([ | |||
| @@ -124,17 +161,15 @@ class KintoneAccess | |||
| return $response; | |||
| } | |||
| public function createCursor(KintoneRecordQuery|null $query = null, array|null $fields = null) | |||
| public function createCursor(KintoneRecordQuery|null $query = null) | |||
| { | |||
| $data = [ | |||
| "app" => $this->appId, | |||
| 'fields' => $this->fields, | |||
| ]; | |||
| if ($query !== null) { | |||
| $data["query"] = $query->toQuery(); | |||
| } | |||
| if ($fields !== null) { | |||
| $data["fields"] = $fields; | |||
| } | |||
| $response = Http::withHeaders([ | |||
| "X-Cybozu-API-Token" => $this->apiToken, | |||
| @@ -143,16 +178,23 @@ class KintoneAccess | |||
| if ($response->failed()) { | |||
| $e = $response->toException(); | |||
| if ($e instanceof Exception) { | |||
| Log::error($e->getMessage()); | |||
| Log::error($e->getMessage(), ['data' => $data]); | |||
| throw $e; | |||
| } | |||
| } | |||
| $this->cursor = $response["id"]; | |||
| $this->cursorDataCount = $response["totalCount"]; | |||
| $cursor = $response["id"]; | |||
| $totalCount = $response["totalCount"]; | |||
| if (0 < $this->cursorDataCount) { | |||
| if (0 < $totalCount) { | |||
| $this->hasNext = true; | |||
| $this->cursor = $cursor; | |||
| $this->cursorDataCount = $totalCount; | |||
| } else { | |||
| $this->cursor = null; | |||
| $this->hasNext = false; | |||
| $this->cursorDataCount = 0; | |||
| } | |||
| return $response; | |||
| @@ -160,7 +202,7 @@ class KintoneAccess | |||
| /** | |||
| * @return Collection<KintoneModel> | |||
| * @return Collection<int,TValue> | |||
| */ | |||
| public function next() | |||
| { | |||
| @@ -207,7 +249,7 @@ class KintoneAccess | |||
| } | |||
| /** | |||
| * @return Collection<KintoneModel> | |||
| * @return Collection<int,TValue> | |||
| */ | |||
| public function all(KintoneRecordQuery|null $query = null, array|null $fields = null) | |||
| { | |||
| @@ -257,6 +299,42 @@ class KintoneAccess | |||
| $this->cursorDataCount = 0; | |||
| } | |||
| public function fileGet(string $fileKey) | |||
| { | |||
| $response = Http::withHeaders([ | |||
| "X-Cybozu-API-Token" => $this->apiToken, | |||
| "Content-Type" => "application/json", | |||
| ])->get($this->getCursorUrl(), [ | |||
| "fileKey" => $fileKey, | |||
| ]); | |||
| if ($response->failed()) { | |||
| $e = $response->toException(); | |||
| if ($e instanceof Exception) { | |||
| Log::error($e->getMessage()); | |||
| throw $e; | |||
| } | |||
| } | |||
| return $response; | |||
| } | |||
| public function filePut($file): string | |||
| { | |||
| $response = Http::withHeaders([ | |||
| "X-Cybozu-API-Token" => $this->apiToken, | |||
| "Content-Type" => "multipart/form-data", | |||
| ])->post($this->getCursorUrl(), $file); | |||
| if ($response->failed()) { | |||
| $e = $response->toException(); | |||
| if ($e instanceof Exception) { | |||
| Log::error($e->getMessage()); | |||
| throw $e; | |||
| } | |||
| } | |||
| return $response['']; | |||
| } | |||
| private function getRecordUrl() | |||
| { | |||
| return $this->getUrl(self::URL_RECORD); | |||
| @@ -267,6 +345,11 @@ class KintoneAccess | |||
| return $this->getUrl(self::URL_CURSOL); | |||
| } | |||
| private function getFileUrl() | |||
| { | |||
| return $this->getUrl(self::URL_FILE); | |||
| } | |||
| private function getUrl(string $path) | |||
| { | |||
| return $this->host . $path; | |||
| @@ -1,42 +0,0 @@ | |||
| <?php | |||
| namespace App\Kintone\Models; | |||
| class CarRoom extends KintoneModel | |||
| { | |||
| const FIELD_PARK_NAME = "駐車場名"; | |||
| const FIELD_ROOM_NO = "車室番号"; | |||
| const FIELD_ROOM_NAME = "車室名"; | |||
| const FIELD_FULL = "満空"; | |||
| const FIELD_CAN_USE_VEHICLE_TYPE = "利用可能車種"; | |||
| const FIELD_CAN_DEVIDE_PER_DAY = "日割り"; | |||
| const FIELD_TABLE_FEE = "料金表"; | |||
| const FIELD_TABLE_FEE_VEHICLE_TYPE = "車種"; | |||
| const FIELD_TABLE_FEE_AMOUNT_PER_MONTH = "金額_1ヶ月"; | |||
| protected array $fields = [ | |||
| self::FIELD_PARK_NAME => FieldType::STRING, | |||
| self::FIELD_ROOM_NO => FieldType::STRING, | |||
| self::FIELD_ROOM_NAME => FieldType::STRING, | |||
| self::FIELD_FULL => FieldType::STRING, | |||
| self::FIELD_CAN_USE_VEHICLE_TYPE => FieldType::ARRAY, | |||
| self::FIELD_TABLE_FEE => [ | |||
| self::FIELD_TABLE_FEE_VEHICLE_TYPE => FieldType::STRING, | |||
| self::FIELD_TABLE_FEE_AMOUNT_PER_MONTH => FieldType::STRING, | |||
| ], | |||
| ]; | |||
| protected function setModelData(array $data): bool | |||
| { | |||
| return true; | |||
| } | |||
| protected function toArrayModel(): array | |||
| { | |||
| return []; | |||
| } | |||
| } | |||
| @@ -1,15 +0,0 @@ | |||
| <?php | |||
| namespace App\Kintone\Models; | |||
| class Customer extends KintoneModel | |||
| { | |||
| const FIELD_CUSTOMER_NAME = "顧客名"; | |||
| const FIELD_CUSTOMER_MEMO = "備考"; | |||
| protected array $fields = [ | |||
| self::FIELD_CUSTOMER_NAME => FieldType::STRING, | |||
| self::FIELD_CUSTOMER_MEMO => FieldType::STRING, | |||
| ]; | |||
| } | |||
| @@ -2,11 +2,27 @@ | |||
| namespace App\Kintone\Models; | |||
| enum FieldType | |||
| enum FieldType: string | |||
| { | |||
| case STRING; | |||
| case ARRAY; | |||
| case DATETIME; | |||
| case USERS; | |||
| case TABLE; | |||
| case SINGLE_LINE_TEXT = "SINGLE_LINE_TEXT"; | |||
| case MULTI_LINE_TEXT = "MULTI_LINE_TEXT"; | |||
| case RICH_TEXT = "RICH_TEXT"; | |||
| case NUMBER = "NUMBER"; | |||
| case CALC = "CALC"; | |||
| case CHECK_BOX = "CHECK_BOX"; | |||
| case RADIO_BUTTON = "RADIO_BUTTON"; | |||
| case MULTI_SELECT = "MULTI_SELECT"; | |||
| case DROP_DOWN = "DROP_DOWN"; | |||
| case USER_SELECT = "USER_SELECT"; | |||
| case ORGANIZATION_SELECT = "ORGANIZATION_SELECT"; | |||
| case GROUP_SELECT = "GROUP_SELECT"; | |||
| case DATE = "DATE"; | |||
| case TIME = "TIME"; | |||
| case DATETIME = "DATETIME"; | |||
| case LINK = "LINK"; | |||
| case FILE = "FILE"; | |||
| case SUBTABLE = "SUBTABLE"; | |||
| case CATEGORY = "CATEGORY"; | |||
| case STATUS = "STATUS"; | |||
| case STATUS_ASSIGNEE = "STATUS_ASSIGNEE"; | |||
| } | |||
| @@ -2,19 +2,71 @@ | |||
| namespace App\Kintone\Models; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Exceptions\ConfigException; | |||
| use App\Kintone\File; | |||
| use App\Kintone\KintoneAccess; | |||
| use App\Kintone\KintoneRecordQuery; | |||
| use App\Util\DateUtil; | |||
| use Illuminate\Support\Arr; | |||
| use Illuminate\Support\Carbon; | |||
| use LogicException; | |||
| use stdClass; | |||
| abstract class KintoneModel | |||
| { | |||
| const CONFIG_KEY = ""; | |||
| const FIELD_RECORD_NUMBER = "レコード番号"; | |||
| const FIELD_CREATED_TIME = "作成日時"; | |||
| const FIELD_UPDATED_TIME = "更新日時"; | |||
| static public function configKey(): string | |||
| { | |||
| if (!static::CONFIG_KEY) { | |||
| throw new LogicException(sprintf("Kintone 設定キー 未設定:%s", static::class)); | |||
| } | |||
| return static::CONFIG_KEY; | |||
| } | |||
| static public function setConfig(): array | |||
| { | |||
| $configStr = env(static::configKey()); | |||
| if (!$configStr) { | |||
| throw new ConfigException(static::configKey(), $configStr); | |||
| } | |||
| $params = explode(",", $configStr); | |||
| if (count($params) !== 2) { | |||
| throw new ConfigException(static::configKey(), $configStr); | |||
| } | |||
| [$apiToken, $appId] = $params; | |||
| return [static::class => [ | |||
| 'apiToken' => $apiToken, | |||
| 'appId' => (int)$appId, | |||
| ]]; | |||
| } | |||
| /** | |||
| * @return KintoneAccess<static> | |||
| */ | |||
| static public function getAccess(): KintoneAccess | |||
| { | |||
| $access = new KintoneAccess(static::class); | |||
| $access->setFields(array_keys(static::FIELDS)); | |||
| return $access; | |||
| } | |||
| /** | |||
| * @return KintoneRecordQuery<static> | |||
| */ | |||
| static public function getQuery(): KintoneRecordQuery | |||
| { | |||
| return new KintoneRecordQuery(static::class); | |||
| } | |||
| protected ?int $recordId = null; | |||
| protected ?int $revision = null; | |||
| @@ -26,7 +78,9 @@ abstract class KintoneModel | |||
| protected ?stdClass $dataOrigin = null; | |||
| protected stdClass $data; | |||
| protected array $fields = []; | |||
| protected const FIELDS = []; | |||
| protected const FIELD_NAMES = []; | |||
| private array $changed = []; | |||
| @@ -37,7 +91,7 @@ abstract class KintoneModel | |||
| public function set(string $fieldCode, $value) | |||
| { | |||
| $field = Arr::get($this->fields, $fieldCode); | |||
| $field = Arr::get(static::FIELDS, $fieldCode); | |||
| if ($field instanceof FieldType) { | |||
| $this->setData($fieldCode, $field, $value); | |||
| } else if (is_array($field)) { | |||
| @@ -60,7 +114,7 @@ abstract class KintoneModel | |||
| { | |||
| foreach ($row as $columnFieldCode => $column) { | |||
| $value = $column["value"]; | |||
| $type = $this->fields[$fieldCode][$columnFieldCode]; | |||
| $type = static::FIELDS[$fieldCode][$columnFieldCode]; | |||
| $insertKey = sprintf("%s.%d.%s", $fieldCode, $index, $columnFieldCode); | |||
| $this->setData($insertKey, $type, $value); | |||
| } | |||
| @@ -68,18 +122,22 @@ abstract class KintoneModel | |||
| private function setData(string $path, FieldType $type, $value) | |||
| { | |||
| if ( | |||
| $type === FieldType::STRING || | |||
| $type === FieldType::ARRAY | |||
| ) { | |||
| data_set($this->data, $path, $value); | |||
| // logger([$path, $value]); | |||
| return $this; | |||
| } | |||
| if ($type === FieldType::DATETIME) { | |||
| data_set($this->data, $path, DateUtil::parse($value)); | |||
| return $this; | |||
| } | |||
| return $this; | |||
| // if ( | |||
| // $type === FieldType::STRING || | |||
| // $type === FieldType::ARRAY | |||
| // ) { | |||
| // data_set($this->data, $path, $value); | |||
| // // logger([$path, $value]); | |||
| // return $this; | |||
| // } | |||
| // if ($type === FieldType::DATETIME) { | |||
| // data_set($this->data, $path, DateUtil::parse($value)); | |||
| // return $this; | |||
| // } | |||
| } | |||
| public function setDataFromRecordResponse(array $data): bool | |||
| @@ -105,7 +163,32 @@ abstract class KintoneModel | |||
| continue; | |||
| } | |||
| $this->set($fieldCode, $value); | |||
| $type = FieldType::tryFrom($type); | |||
| if ($type === null) continue; | |||
| if ($type === FieldType::DATETIME) { | |||
| if ($value) { | |||
| data_set($this->data, $fieldCode, DateUtil::parse($value)); | |||
| } else { | |||
| data_set($this->data, $fieldCode, null); | |||
| } | |||
| continue; | |||
| } | |||
| if ($type === FieldType::FILE) { | |||
| $ret = []; | |||
| foreach ($value as $f) { | |||
| $ret[] = new File($f); | |||
| } | |||
| data_set($this->data, $fieldCode, $ret); | |||
| continue; | |||
| } | |||
| if ($type === FieldType::SUBTABLE) { | |||
| continue; | |||
| } | |||
| // 以外はそのまま格納 | |||
| data_set($this->data, $fieldCode, $value); | |||
| } | |||
| $ret = $this->setDataCustom($data); | |||
| @@ -132,7 +215,7 @@ abstract class KintoneModel | |||
| public function getApiLayout(): array | |||
| { | |||
| $ret = []; | |||
| foreach ($this->fields as $fieldCode => $type) { | |||
| foreach (static::FIELDS as $fieldCode => $type) { | |||
| // 変更があった項目のみレイアウトへ出力する | |||
| if (!Arr::has($this->changed, $fieldCode)) { | |||
| @@ -140,18 +223,11 @@ abstract class KintoneModel | |||
| } | |||
| $path = sprintf("%s.value", $fieldCode); | |||
| if ($type === FieldType::STRING) { | |||
| data_set($ret, $path, data_get($this->data, $fieldCode)); | |||
| continue; | |||
| } | |||
| if ($type === FieldType::ARRAY) { | |||
| data_set($ret, $path, data_get($this->data, $fieldCode)); | |||
| continue; | |||
| } | |||
| if ($type === FieldType::DATETIME) { | |||
| data_set($ret, $path, $this->getDate($fieldCode)->toIso8601ZuluString()); | |||
| continue; | |||
| } | |||
| data_set($ret, $path, data_get($this->data, $fieldCode)); | |||
| } | |||
| return array_merge($ret, $this->getApiLayoutCustom()); | |||
| @@ -159,6 +235,7 @@ abstract class KintoneModel | |||
| public function get(string $key) | |||
| { | |||
| $a = json_decode(json_encode($this->data), true); | |||
| return data_get($this->data, $key); | |||
| } | |||
| @@ -210,11 +287,49 @@ abstract class KintoneModel | |||
| return $this->createdAt; | |||
| } | |||
| static public function query() | |||
| public function toArray(): array | |||
| { | |||
| return new KintoneRecordQuery(static::class); | |||
| if ($this->recordId === null) { | |||
| throw new LogicException("保存前モデルのシリアライズ検知"); | |||
| } | |||
| $ret = [ | |||
| 'record_no' => $this->recordId, | |||
| 'revision' => $this->revision, | |||
| ]; | |||
| /** | |||
| * @var string $fieldCode | |||
| */ | |||
| foreach ($this->data as $fieldCode => $value) { | |||
| $type = data_get(static::FIELDS, $fieldCode); | |||
| $columnName = data_get(static::FIELD_NAMES, $fieldCode, $fieldCode); | |||
| if ($type === null) { | |||
| $ret[$columnName] = $value; | |||
| continue; | |||
| } | |||
| if ($type === FieldType::DATETIME) { | |||
| if ($value instanceof Carbon) { | |||
| $ret[$columnName] = $value->format('Y/m/d H:i:s'); | |||
| } else { | |||
| $ret[$columnName] = $value; | |||
| } | |||
| continue; | |||
| } | |||
| $ret[$columnName] = $value; | |||
| } | |||
| return $ret; | |||
| } | |||
| /** | |||
| * オーバーライドを期待 | |||
| * | |||
| @@ -4,12 +4,22 @@ namespace App\Kintone\Models; | |||
| class SeasonTicketContract extends KintoneModel | |||
| { | |||
| const CONFIG_KEY = "KINTONE_APP_SEASON_TICKET_CONTRACT"; | |||
| const FIELD_CUSTOMER_NAME = "顧客名"; | |||
| const FIELD_CUSTOMER_MEMO = "備考"; | |||
| protected array $fields = [ | |||
| self::FIELD_CUSTOMER_NAME => FieldType::STRING, | |||
| self::FIELD_CUSTOMER_MEMO => FieldType::STRING, | |||
| protected const FIELDS = [ | |||
| ...parent::FIELDS, | |||
| self::FIELD_CUSTOMER_NAME => FieldType::SINGLE_LINE_TEXT, | |||
| ]; | |||
| protected const FIELD_NAMES = [ | |||
| ...parent::FIELD_NAMES, | |||
| self::FIELD_CUSTOMER_NAME => 'customer_name', | |||
| ]; | |||
| protected function setDataCustom(array $data): bool | |||
| { | |||
| return true; | |||
| } | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| <?php | |||
| namespace App\Models; | |||
| abstract class ColumnName | |||
| { | |||
| // 共通 | |||
| const ID = 'id'; | |||
| const UPDATED_AT = 'updated_at'; | |||
| const UPDATED_BY = 'updated_by'; | |||
| const CREATED_AT = 'created_at'; | |||
| const CREATED_BY = 'created_by'; | |||
| const DELETED_AT = 'deleted_at'; | |||
| const HISTORY_ID = 'history_id'; | |||
| // 業務 | |||
| const USER_ID = 'user_id'; | |||
| const EMAIL_ID = "email_id"; | |||
| } | |||
| @@ -18,7 +18,7 @@ use Laravel\Sanctum\HasApiTokens; | |||
| class User extends Authenticatable implements IModelFeature | |||
| { | |||
| use HasApiTokens, HasFactory, Notifiable, HasUuids, SoftDeletes, ContractFeature; | |||
| use HasApiTokens, HasFactory, Notifiable, HasUuids, SoftDeletes; | |||
| const COL_NAME_ID = 'id'; | |||
| const COL_NAME_ROLE = 'role'; | |||
| @@ -26,8 +26,6 @@ class User extends Authenticatable implements IModelFeature | |||
| const COL_NAME_NAME = 'name'; | |||
| const COL_NAME_PASSWORD = 'password'; | |||
| const COL_NAME_CONTRACT_ID = ColumnName::CONTRACT_ID; | |||
| const COL_NAME_CREATED_BY = ColumnName::CREATED_BY; | |||
| const COL_NAME_UPDATED_BY = ColumnName::UPDATED_BY; | |||
| const COL_NAME_CREATED_AT = ColumnName::CREATED_AT; | |||
| @@ -123,43 +123,12 @@ class MigrationHelper | |||
| return sprintf("%s_uq_%02d", $this->table->getTable(), $number); | |||
| } | |||
| public function contractId(bool $nullable = false) | |||
| { | |||
| $this->table->uuid(ColumnName::CONTRACT_ID)->comment("契約ID")->nullable($nullable); | |||
| // $this->table->foreign(ColumnName::CONTRACT_ID)->references(ColumnName::ID)->on(Contract::getTableName()); | |||
| return $this; | |||
| } | |||
| public function receiptIssuingOrderId(bool $nullable = false) | |||
| { | |||
| $this->table->uuid(ColumnName::RECEIPT_ISSUING_ORDER_ID)->comment("領収証発行依頼ID")->nullable($nullable); | |||
| // $this->table->foreign(ColumnName::RECEIPT_ISSUING_ORDER_ID)->references(ColumnName::ID)->on(ReceiptIssuingOrder::getTableName()); | |||
| return $this; | |||
| } | |||
| public function smsSendOrderId(bool $nullable = false) | |||
| { | |||
| $this->table->uuid(ColumnName::SMS_SEND_ORDER_ID)->comment("SMS送信依頼ID")->nullable($nullable); | |||
| // $this->table->foreign(ColumnName::SMS_SEND_ORDER_ID)->references(ColumnName::ID)->on(SMSSendOrder::getTableName()); | |||
| return $this; | |||
| } | |||
| public function userId(bool $nullable = false, ?string $columnName = null, ?string $comment = null) | |||
| { | |||
| $columnName = $columnName ?? ColumnName::USER_ID; | |||
| $comment = $comment ?? "ユーザーID"; | |||
| $this->table->uuid($columnName)->comment($comment)->nullable($nullable); | |||
| // $this->table->foreign($columnName)->references(ColumnName::ID)->on(User::getTableName()); | |||
| return $this; | |||
| } | |||
| public function smsProviderId(bool $nullable = false) | |||
| { | |||
| $this->table->uuid(ColumnName::SMS_PROVIDER_ID)->comment("SMSプロバイダーID")->nullable($nullable); | |||
| // $this->table->foreign(ColumnName::SMS_PROVIDER_ID)->references(ColumnName::ID)->on(SMSProvider::getTableName()); | |||
| return $this; | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| <?php | |||
| use App\Kintone\KintoneConfiguration; | |||
| return [ | |||
| @@ -24,18 +26,7 @@ return [ | |||
| */ | |||
| 'applications' => [ | |||
| App\Kintone\Models\Customer::class => [ | |||
| 'apiToken' => (string)explode(",", env("KINTONE_APP_CUSTOMER", ","))[0], | |||
| 'appId' => (int)explode(",", env("KINTONE_APP_CUSTOMER", ","))[1], | |||
| ], | |||
| App\Kintone\Models\CarRoom::class => [ | |||
| 'apiToken' => (string)explode(",", env("KINTONE_APP_CARROOM", ","))[0], | |||
| 'appId' => (int)explode(",", env("KINTONE_APP_CARROOM", ","))[1], | |||
| ], | |||
| App\Kintone\Models\Small::class => [ | |||
| 'apiToken' => (string)explode(",", env("KINTONE_APP_SMALL", ","))[0], | |||
| 'appId' => (int)explode(",", env("KINTONE_APP_SMALL", ","))[1], | |||
| ], | |||
| ...App\Kintone\Models\SeasonTicketContract::setConfig(), | |||
| ], | |||
| ]; | |||
| @@ -0,0 +1,40 @@ | |||
| <?php | |||
| use App\Util\MigrationHelper; | |||
| use Illuminate\Database\Migrations\Migration; | |||
| use Illuminate\Database\Schema\Blueprint; | |||
| use Illuminate\Support\Facades\Schema; | |||
| return new class extends Migration | |||
| { | |||
| /** | |||
| * Run the migrations. | |||
| */ | |||
| public function up(): void | |||
| { | |||
| Schema::create('users', function (Blueprint $table) { | |||
| $helper = new MigrationHelper($table); | |||
| $helper->baseColumn(); | |||
| $table->string('email')->unique()->comment('Email'); | |||
| $table->string('password')->comment('ログインパスワード'); | |||
| $table->string('kintone_id')->comment('KintoneID'); | |||
| }); | |||
| Schema::create('user_histories', function (Blueprint $table) { | |||
| $helper = new MigrationHelper($table, true); | |||
| $helper->baseColumn(); | |||
| $table->string('email')->comment('Email'); | |||
| $table->string('password')->comment('ログインパスワード'); | |||
| $table->string('kintone_id')->comment('KintoneID'); | |||
| }); | |||
| } | |||
| /** | |||
| * Reverse the migrations. | |||
| */ | |||
| public function down(): void | |||
| { | |||
| Schema::dropIfExists('users'); | |||
| Schema::dropIfExists('user_histories'); | |||
| } | |||
| }; | |||
| @@ -0,0 +1,32 @@ | |||
| <?php | |||
| use Illuminate\Database\Migrations\Migration; | |||
| use Illuminate\Database\Schema\Blueprint; | |||
| use Illuminate\Support\Facades\Schema; | |||
| return new class extends Migration | |||
| { | |||
| /** | |||
| * Run the migrations. | |||
| */ | |||
| public function up(): void | |||
| { | |||
| Schema::create('failed_jobs', function (Blueprint $table) { | |||
| $table->id(); | |||
| $table->string('uuid')->unique(); | |||
| $table->text('connection'); | |||
| $table->text('queue'); | |||
| $table->longText('payload'); | |||
| $table->longText('exception'); | |||
| $table->timestamp('failed_at')->useCurrent(); | |||
| }); | |||
| } | |||
| /** | |||
| * Reverse the migrations. | |||
| */ | |||
| public function down(): void | |||
| { | |||
| Schema::dropIfExists('failed_jobs'); | |||
| } | |||
| }; | |||
| @@ -0,0 +1,28 @@ | |||
| #!/bin/bash | |||
| cd $(dirname $0) | |||
| SAIL="" | |||
| COMMANDS=() | |||
| if [ $# -eq 0 ]; then | |||
| SAIL="" | |||
| COMMANDS+=("composer install --optimize-autoloader --no-dev") | |||
| elif [ $# -eq 1 ] && [ $1 == "sail" ]; then | |||
| SAIL="./sail" | |||
| NO_DEV="--no-dev" | |||
| else | |||
| echo "引数不正" | |||
| exit 1 | |||
| fi | |||
| COMMANDS+=("${SAIL} php artisan config:cache") | |||
| COMMANDS+=("${SAIL} php artisan route:cache") | |||
| COMMANDS+=("${SAIL} php artisan view:cache") | |||
| COMMANDS+=("${SAIL} php artisan event:cache") | |||
| COMMANDS+=("${SAIL} php artisan queue:restart") | |||
| for COMMAND in "${COMMANDS[@]}"; do | |||
| echo ${COMMAND} | |||
| ${COMMAND} | |||
| done | |||
| @@ -0,0 +1,23 @@ | |||
| #!/bin/bash | |||
| cd $(dirname $0) | |||
| SAIL="" | |||
| if [ $# -eq 0 ]; then | |||
| SAIL="" | |||
| elif [ $# -eq 1 ] && [ $1 == "sail" ]; then | |||
| SAIL="./sail" | |||
| else | |||
| echo "引数不正" | |||
| exit 1 | |||
| fi | |||
| COMMANDS=() | |||
| # COMMANDS+=("${SAIL} php artisan ide-helper:generate") | |||
| COMMANDS+=("${SAIL} php artisan ide-helper:models -N") | |||
| for COMMAND in "${COMMANDS[@]}"; do | |||
| echo ${COMMAND} | |||
| ${COMMAND} | |||
| done | |||
| @@ -5,116 +5,118 @@ namespace Tests\Feature; | |||
| use App\Kintone\KintoneAccess; | |||
| use App\Kintone\KintoneRecordQuery; | |||
| use App\Kintone\KintoneRecordQueryOperator; | |||
| use App\Kintone\Models\CarRoom; | |||
| use App\Kintone\Models\Customer; | |||
| use App\Kintone\Models\Small; | |||
| use App\Kintone\Models\SeasonTicketContract; | |||
| use App\Middlewares\Now; | |||
| use Illuminate\Support\Collection; | |||
| use Tests\TestCase; | |||
| class KintoneAccessTest extends TestCase | |||
| { | |||
| /** | |||
| * A basic feature test example. | |||
| */ | |||
| public function test_access(): void | |||
| public function test_find(): void | |||
| { | |||
| $model = new Customer(); | |||
| $model = new SeasonTicketContract(); | |||
| $access = new KintoneAccess(Customer::class); | |||
| $access = SeasonTicketContract::getAccess(); | |||
| $access->find(1, $model); | |||
| $access->find(505, $model); | |||
| $this->assertEquals("林田商会", $model->getStr(Customer::FIELD_CUSTOMER_NAME)); | |||
| $memo = Now::get()->format("YmdHis"); | |||
| $model->set(Customer::FIELD_CUSTOMER_MEMO, $memo); | |||
| $beforeRevision = $model->getRevision(); | |||
| $access->update($model); | |||
| $afterRevision = $model->getRevision(); | |||
| $this->assertEquals($beforeRevision + 1, $afterRevision); | |||
| // 再度データを取得して項目が更新されていることを確認 | |||
| $model = new Customer(); | |||
| $access->find(1, $model); | |||
| $this->assertEquals($memo, $model->getStr(Customer::FIELD_CUSTOMER_MEMO)); | |||
| $this->assertEquals("塩山兼司", $model->getStr(SeasonTicketContract::FIELD_CUSTOMER_NAME)); | |||
| } | |||
| public function test_CarRoom(): void | |||
| public function test_all(): void | |||
| { | |||
| $model = new SeasonTicketContract(); | |||
| $model = new CarRoom(); | |||
| $access = SeasonTicketContract::getAccess(); | |||
| $access = new KintoneAccess(CarRoom::class); | |||
| $query = SeasonTicketContract::getQuery(); | |||
| $query->where(SeasonTicketContract::FIELD_CUSTOMER_NAME, "井出侑加"); | |||
| $ret = $access->all($query); | |||
| $access->find(1, $model); | |||
| $this->assertEquals(1, $ret->count()); | |||
| $this->assertEquals("岩渕パーク", $model->getStr(CarRoom::FIELD_PARK_NAME)); | |||
| $this->assertEquals("5000", $model->getTable(CarRoom::FIELD_TABLE_FEE)[0][CarRoom::FIELD_TABLE_FEE_AMOUNT_PER_MONTH]); | |||
| $this->assertEquals("自転車", $model->get(CarRoom::FIELD_CAN_USE_VEHICLE_TYPE)[0]); | |||
| $this->assertEquals("普通自動車", $model->get(CarRoom::FIELD_CAN_USE_VEHICLE_TYPE)[1]); | |||
| } | |||
| public function test_small() | |||
| { | |||
| $model = new Small(); | |||
| $access = new KintoneAccess(Small::class); | |||
| /** | |||
| * @var SeasonTicketContract | |||
| */ | |||
| $model = $ret[0]; | |||
| $model->set(Small::FIELD_NAME, "iwabuchi"); | |||
| $model->set(Small::FIELD_AGE, "32"); | |||
| $this->assertEquals("井出侑加", $model->getStr(SeasonTicketContract::FIELD_CUSTOMER_NAME)); | |||
| $res = $access->create($model); | |||
| $this->assertTrue($res->ok()); | |||
| $array = $model->toArray(); | |||
| $this->assertEquals("井出侑加", $array['customer_name']); | |||
| } | |||
| /** | |||
| * @group cursor | |||
| */ | |||
| public function test_cursor() | |||
| { | |||
| $access = new KintoneAccess(Small::class); | |||
| $now = Now::get(); | |||
| $query = Small::query() | |||
| ->whereIn(Small::FIELD_NAME, ["iwabuchi", "aa"]) | |||
| ->where(Small::FIELD_AGE, 32) | |||
| ->whereDateTime(Small::FIELD_CREATED_TIME, $now, KintoneRecordQueryOperator::LT); | |||
| $access->createCursor($query); | |||
| $ret = $access->next(); | |||
| $this->assertTrue($ret instanceof Collection); | |||
| $this->assertSame(1, $ret->count()); | |||
| $this->assertSame("iwabuchi", $ret->first()->getStr(Small::FIELD_NAME)); | |||
| } | |||
| /** | |||
| * @group cursor | |||
| */ | |||
| public function test_cursor_all() | |||
| { | |||
| $access = new KintoneAccess(Small::class); | |||
| $now = Now::get(); | |||
| $query = Small::query() | |||
| ->orderByAsc(Small::FIELD_NAME); | |||
| $ret = $access->all($query, [ | |||
| Small::FIELD_NAME, | |||
| Small::FIELD_AGE, | |||
| ]); | |||
| $this->assertTrue($ret instanceof Collection); | |||
| $this->assertSame(2, $ret->count()); | |||
| $first = $ret->first(); | |||
| $this->assertInstanceOf(Small::class, $first); | |||
| $this->assertSame("iwabuchi", $ret->first()->getStr(Small::FIELD_NAME)); | |||
| $this->assertSame(32, $ret->first()->getNumber(Small::FIELD_AGE)); | |||
| } | |||
| // public function test_CarRoom(): void | |||
| // { | |||
| // $model = new CarRoom(); | |||
| // $access = new KintoneAccess(CarRoom::class); | |||
| // $access->find(1, $model); | |||
| // $this->assertEquals("岩渕パーク", $model->getStr(CarRoom::FIELD_PARK_NAME)); | |||
| // $this->assertEquals("5000", $model->getTable(CarRoom::FIELD_TABLE_FEE)[0][CarRoom::FIELD_TABLE_FEE_AMOUNT_PER_MONTH]); | |||
| // $this->assertEquals("自転車", $model->get(CarRoom::FIELD_CAN_USE_VEHICLE_TYPE)[0]); | |||
| // $this->assertEquals("普通自動車", $model->get(CarRoom::FIELD_CAN_USE_VEHICLE_TYPE)[1]); | |||
| // } | |||
| // public function test_small() | |||
| // { | |||
| // $model = new Small(); | |||
| // $access = new KintoneAccess(Small::class); | |||
| // $model->set(Small::FIELD_NAME, "iwabuchi"); | |||
| // $model->set(Small::FIELD_AGE, "32"); | |||
| // $res = $access->create($model); | |||
| // $this->assertTrue($res->ok()); | |||
| // } | |||
| // /** | |||
| // * @group cursor | |||
| // */ | |||
| // public function test_cursor() | |||
| // { | |||
| // $access = new KintoneAccess(Small::class); | |||
| // $now = Now::get(); | |||
| // $query = Small::query() | |||
| // ->whereIn(Small::FIELD_NAME, ["iwabuchi", "aa"]) | |||
| // ->where(Small::FIELD_AGE, 32) | |||
| // ->whereDateTime(Small::FIELD_CREATED_TIME, $now, KintoneRecordQueryOperator::LT); | |||
| // $access->createCursor($query); | |||
| // $ret = $access->next(); | |||
| // $this->assertTrue($ret instanceof Collection); | |||
| // $this->assertSame(1, $ret->count()); | |||
| // $this->assertSame("iwabuchi", $ret->first()->getStr(Small::FIELD_NAME)); | |||
| // } | |||
| // /** | |||
| // * @group cursor | |||
| // */ | |||
| // public function test_cursor_all() | |||
| // { | |||
| // $access = new KintoneAccess(Small::class); | |||
| // $now = Now::get(); | |||
| // $query = Small::query() | |||
| // ->orderByAsc(Small::FIELD_NAME); | |||
| // $ret = $access->all($query, [ | |||
| // Small::FIELD_NAME, | |||
| // Small::FIELD_AGE, | |||
| // ]); | |||
| // $this->assertTrue($ret instanceof Collection); | |||
| // $this->assertSame(2, $ret->count()); | |||
| // $first = $ret->first(); | |||
| // $this->assertInstanceOf(Small::class, $first); | |||
| // $this->assertSame("iwabuchi", $ret->first()->getStr(Small::FIELD_NAME)); | |||
| // $this->assertSame(32, $ret->first()->getNumber(Small::FIELD_AGE)); | |||
| // } | |||
| } | |||