|  | 
| 4 | 4 | 
 | 
| 5 | 5 | 
 | 
| 6 | 6 | use App\Exceptions\database\ForeignKeyException; | 
|  | 7 | +use App\Exceptions\database\NotUniqueException; | 
| 7 | 8 | use App\Exceptions\database\RowNotFoundException; | 
| 8 | 9 | use App\Http\Controllers\Controller; | 
| 9 | 10 | use App\Http\DTOs\LessonStoreDTO; | 
| @@ -31,19 +32,42 @@ public function store(LessonStoreRequest $request) | 
| 31 | 32 | 
 | 
| 32 | 33 |  $enrollment = Enrollment::getOne($lessonStoreDTO->getCourseId(), $lessonStoreDTO->getStudentId()); | 
| 33 | 34 |  if(!$enrollment){ | 
| 34 |  | - throw new RowNotFoundException("Couldn't find the enrollment. (Course ID : " . $lessonStoreDTO->getCourseId() . ", Student ID : " . $lessonStoreDTO->getStudentId() . ")"); | 
|  | 35 | + // 관리자가 CourseController 에서 Soft Delete 를 했다면 여기로 옴. | 
|  | 36 | + throw new RowNotFoundException("The enrollment is NOT available. (Course ID : " . $lessonStoreDTO->getCourseId() . ", Student ID : " . $lessonStoreDTO->getStudentId() . ")"); | 
| 35 | 37 |  } | 
| 36 | 38 | 
 | 
| 37 |  | - Lesson::create([ | 
| 38 |  | - 'enrollment_id' => $enrollment->id, | 
| 39 |  | - 'status' => $lessonStoreDTO->getStatus(), | 
| 40 |  | - 'result' => $lessonStoreDTO->getResult(), | 
| 41 |  | - 'recording' => $lessonStoreDTO->getRecording() | 
| 42 |  | - ]); | 
|  | 39 | + try { | 
|  | 40 | + | 
|  | 41 | + $lesson = Lesson::query()->where('enrollment_id', $enrollment->id) | 
|  | 42 | + ->where('status', $lessonStoreDTO->getStatus())->first(); | 
|  | 43 | + if($lesson){ | 
|  | 44 | + throw new NotUniqueException("Enrollment ID : " . $enrollment->id . " has already been " . strtolower($lessonStoreDTO->getStatus()) . "ed."); | 
|  | 45 | + } | 
|  | 46 | + | 
|  | 47 | + $lesson = Lesson::query()->create([ | 
|  | 48 | + 'enrollment_id' => $enrollment->id, | 
|  | 49 | + 'status' => $lessonStoreDTO->getStatus(), | 
|  | 50 | + 'result' => $lessonStoreDTO->getResult(), | 
|  | 51 | + 'recording' => $lessonStoreDTO->getRecording() | 
|  | 52 | + ]); | 
|  | 53 | + }catch (\Throwable $e){ | 
|  | 54 | + | 
|  | 55 | + $matches = array(); | 
|  | 56 | + | 
|  | 57 | + // 상기 Lesson::query()->where 문이 진행되는 동안, 다른 Transaction 에서 이미 등록한 경우. | 
|  | 58 | + // SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '3-Start' for key | 
|  | 59 | + // 에서 3은 id / 하이픈 뒤는 Status | 
|  | 60 | + if($e->getCode() == "23000" && preg_match('/Duplicate entry \'[0-9]+?-(Start|End)\'/', $e->getMessage(), $matches)){ | 
|  | 61 | + throw new NotUniqueException("Enrollment ID : " . $enrollment->id . " has already been " . strtolower($matches[1]) . "ed."); | 
|  | 62 | + }else{ | 
|  | 63 | + throw $e; | 
|  | 64 | + } | 
|  | 65 | + | 
|  | 66 | + } | 
| 43 | 67 | 
 | 
| 44 | 68 |  // 이메일 발송의 경우 laravel-queue 를 사용하여 구현. (Dockerfile 에서 supervisor 를 설치하여 이를 관리 (동시에 몇 개를 실행해야 할 지, 실패 시 재시도 횟수 등) 해야 함.) | 
| 45 | 69 | 
 | 
| 46 |  | - return response()->json(null, 201); | 
|  | 70 | + return response()->json($lesson, 201); | 
| 47 | 71 |  } | 
| 48 | 72 | 
 | 
| 49 | 73 | } | 
0 commit comments