領収証発行サービス
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
5.6KB

  1. <?php
  2. namespace App\Logic\User;
  3. use App\Codes\UserRole;
  4. use App\Exceptions\AppCommonException;
  5. use App\Features\InstanceAble;
  6. use App\Models\Contract;
  7. use App\Models\Ex\LoginUser;
  8. use App\Models\User;
  9. use Illuminate\Support\Carbon;
  10. use Illuminate\Support\Facades\Hash;
  11. use Illuminate\Support\Facades\Validator;
  12. use LogicException;
  13. abstract class UserManager
  14. {
  15. use InstanceAble;
  16. static public function getManager(User $user): static
  17. {
  18. $loginUser = LoginUser::instance()->user();
  19. if ($user->role === UserRole::SUPER_ADMIN) {
  20. if ($loginUser->role === UserRole::SUPER_ADMIN) {
  21. return AdminUserManager::instance();
  22. }
  23. throw new AppCommonException("認可不良");
  24. }
  25. if ($user->role === UserRole::CONTRACT_ADMIN) {
  26. if (UserRole::CONTRACT_ADMIN->value <= $loginUser->role->value) {
  27. return ContractAdminUserManager::instance();
  28. }
  29. throw new AppCommonException("認可不良");
  30. }
  31. if ($user->role === UserRole::NORMAL_ADMIN) {
  32. if (UserRole::NORMAL_ADMIN->value <= $loginUser->role->value) {
  33. return LoginUserManager::instance();
  34. }
  35. throw new AppCommonException("認可不良");
  36. }
  37. throw new LogicException("未定義ロール");
  38. }
  39. protected bool $initialized = false;
  40. protected ?User $user = null;
  41. protected ?Contract $contract = null;
  42. public function initForCreate(string|Contract $contractId): static
  43. {
  44. $this->setContract($contractId);
  45. $this->setUser(null);
  46. $this->initialized = true;
  47. return $this;
  48. }
  49. public function initForCreateAdmin(): static
  50. {
  51. throw new LogicException("不許可な関数アクセス");
  52. }
  53. public function initForModify(string|Contract $contractId, string|User $userId): static
  54. {
  55. $this->setContract($contractId);
  56. $this->setUser($userId);
  57. $this->initialized = true;
  58. return $this;
  59. }
  60. public function initForModifyAdmin(string|User $userId): static
  61. {
  62. throw new LogicException("不許可な関数アクセス");
  63. }
  64. public function getTimestamp(): Carbon
  65. {
  66. if (!$this->initialized) {
  67. throw new LogicException("初期化不正");
  68. }
  69. if ($this->user === null) {
  70. throw new LogicException("初期化不正");
  71. }
  72. if ($this->contract === null) {
  73. return $this->user->updated_at;
  74. }
  75. return $this->user->updated_at < $this->contract->updated_at ? $this->contract->updated_at : $this->user->updated_at;
  76. }
  77. public function fill(array $attr)
  78. {
  79. if (!$this->initialized) {
  80. throw new LogicException("初期化不正");
  81. }
  82. $this->user->fill($attr);
  83. return $this;
  84. }
  85. public function create(): array
  86. {
  87. $messages = $this->checkParam();
  88. if (count($messages) !== 0) {
  89. return $messages;
  90. }
  91. $this->user->save();
  92. return [];
  93. }
  94. public function update(): array
  95. {
  96. $messages = $this->checkParam();
  97. if (count($messages) !== 0) {
  98. return $messages;
  99. }
  100. $this->user->save();
  101. return [];
  102. }
  103. protected function setContract(string|Contract|null $contractId)
  104. {
  105. if ($contractId instanceof Contract) {
  106. $this->contract = (new Contract())->copy($contractId);
  107. $this->initialized = true;
  108. return;
  109. } else if ($contractId === null) {
  110. $this->initialized = true;
  111. return;
  112. }
  113. $this->contract = Contract::findOrFail($contractId);
  114. $this->initialized = true;
  115. return;
  116. }
  117. protected function setUser(string|User|null $userId)
  118. {
  119. if ($userId instanceof User) {
  120. $this->user = (new User())->copy($userId);
  121. return;
  122. } else if (is_string($userId)) {
  123. $this->user = User::findOrFail($userId);
  124. return;
  125. }
  126. $this->user = new User();
  127. if ($this->contract) {
  128. $this->user->setContract($this->contract);
  129. }
  130. $this->user->role = $this->role();
  131. }
  132. protected function checkParam()
  133. {
  134. $validator = Validator::make($this->user->toArray(), []);
  135. if ($validator->failed()) {
  136. throw new LogicException("バリデートエラー");
  137. }
  138. $messages = [];
  139. $this->checkContract($messages);
  140. $this->checkEmailUnique($messages);
  141. $this->passwordEncrypto($messages);
  142. if ($this->user->isDirty(User::COL_NAME_ROLE)) {
  143. $this->user->role = $this->role();
  144. }
  145. return $messages;
  146. }
  147. protected function checkContract(array &$messages)
  148. {
  149. if ($this->user->role !== UserRole::SUPER_ADMIN && $this->user->contract_id === null) {
  150. throw new LogicException("契約nullエラー");
  151. }
  152. }
  153. protected function passwordEncrypto(array &$messages)
  154. {
  155. if ($this->user->isDirty(User::COL_NAME_PASSWORD)) {
  156. $this->user->password = Hash::make($this->user->password);
  157. }
  158. }
  159. protected function checkEmailUnique(array &$messages)
  160. {
  161. if ($this->user->isDirty(User::COL_NAME_EMAIL)) {
  162. $exists = User::whereEmail($this->user->email)
  163. ->where(User::COL_NAME_ID, '<>', $this->user->id)
  164. ->exists();
  165. if ($exists) {
  166. $messages[User::COL_NAME_EMAIL] = trans('validation.unique');
  167. }
  168. }
  169. }
  170. abstract protected function role(): UserRole;
  171. }