From 06dfbed09167a79e2b8a26a5f66cf188a58e5ed6 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Tue, 17 Oct 2023 01:22:44 +0900 Subject: [PATCH 001/109] =?UTF-8?q?init:=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EC=B4=88=EA=B8=B0=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 37 +++ build.gradle | 25 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 249 ++++++++++++++++++ gradlew.bat | 92 +++++++ settings.gradle | 1 + .../VouchermanagerApplication.java | 13 + .../VouchermanagerApplicationTests.java | 13 + 9 files changed, 437 insertions(+) create mode 100644 .gitignore create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle create mode 100644 src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java create mode 100644 src/test/java/com/prgms/vouchermanager/VouchermanagerApplicationTests.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..c2065bc262 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..0a2e20d77c --- /dev/null +++ b/build.gradle @@ -0,0 +1,25 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.1.4' + id 'io.spring.dependency-management' version '1.1.3' +} + +group = 'com.prgms' +version = '0.0.1-SNAPSHOT' + +java { + sourceCompatibility = '17' +} + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..ac72c34e8a --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000..0adc8e1a53 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..6689b85bee --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000000..fcbc3bb79c --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'vouchermanager' diff --git a/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java b/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java new file mode 100644 index 0000000000..4c6e63af2a --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java @@ -0,0 +1,13 @@ +package com.prgms.vouchermanager; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class VouchermanagerApplication { + + public static void main(String[] args) { + SpringApplication.run(VouchermanagerApplication.class, args); + } + +} diff --git a/src/test/java/com/prgms/vouchermanager/VouchermanagerApplicationTests.java b/src/test/java/com/prgms/vouchermanager/VouchermanagerApplicationTests.java new file mode 100644 index 0000000000..6f0459d0a9 --- /dev/null +++ b/src/test/java/com/prgms/vouchermanager/VouchermanagerApplicationTests.java @@ -0,0 +1,13 @@ +package com.prgms.vouchermanager; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class VouchermanagerApplicationTests { + + @Test + void contextLoads() { + } + +} From d08904e3ea16f5aeda9760a7b344516d9d009d3d Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:19:03 +0900 Subject: [PATCH 002/109] =?UTF-8?q?feat:=20=EC=95=A0=ED=94=8C=EB=A6=AC?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EC=85=98=20=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/VouchermanagerApplication.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java b/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java index 4c6e63af2a..f9da90cb50 100644 --- a/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java +++ b/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java @@ -1,13 +1,19 @@ package com.prgms.vouchermanager; +import com.prgms.vouchermanager.contorller.front.FrontController; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; @SpringBootApplication public class VouchermanagerApplication { - public static void main(String[] args) { - SpringApplication.run(VouchermanagerApplication.class, args); - } + public static void main(String[] args) { + + ApplicationContext ac = SpringApplication.run(VouchermanagerApplication.class, args); + FrontController frontController = ac.getBean(FrontController.class); + frontController.run(); + + } } From e0c05c6e533b6a8fe8281d7af39b5d8ad10a6688 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:20:27 +0900 Subject: [PATCH 003/109] =?UTF-8?q?feat:=20=EC=B5=9C=EC=83=81=EB=8B=A8=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/front/FrontController.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java new file mode 100644 index 0000000000..dfd0b3884c --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java @@ -0,0 +1,58 @@ +package com.prgms.vouchermanager.contorller.front; + + +import com.prgms.vouchermanager.contorller.customer.CustomerController; +import com.prgms.vouchermanager.contorller.voucher.VoucherController; +import com.prgms.vouchermanager.util.io.ConsoleInput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +import static com.prgms.vouchermanager.contorller.front.FrontMenuType.*; + + +@Controller +public class FrontController { + + private final ConsoleInput consoleInput; + + private final VoucherController voucherController; + + private final CustomerController customerController; + + private final static Logger logger = LoggerFactory.getLogger(FrontController.class); + + public FrontController(ConsoleInput consoleInput, VoucherController voucherController, CustomerController customerController) { + + this.consoleInput = consoleInput; + this.voucherController = voucherController; + this.customerController = customerController; + + } + + public void run() { + + boolean end = false; + int menu; + + while (!end) { + + try { + menu = consoleInput.inputFrontMenu(); + } catch (RuntimeException e) { + System.out.println(e.getMessage()); + logger.warn(e.getMessage()); + continue; + } + + if (menu == VOUCHER.getNumber()) { + voucherController.run(); + } else if (menu == CUSTOMER.getNumber()) { + customerController.run(); + } else { + end = true; + } + + } + } +} From 6d78a88cc9e67829af85e7f83f6d4547d543a655 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:20:47 +0900 Subject: [PATCH 004/109] =?UTF-8?q?feat:=20=EC=B5=9C=EC=83=81=EB=8B=A8=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=ED=83=80=EC=9E=85=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/front/FrontMenuType.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/front/FrontMenuType.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontMenuType.java new file mode 100644 index 0000000000..0fb96067d1 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontMenuType.java @@ -0,0 +1,14 @@ +package com.prgms.vouchermanager.contorller.front; + +public enum FrontMenuType { + VOUCHER(1),CUSTOMER(2),END(3); + + private final int number; + FrontMenuType(int number) { + this.number = number; + } + + public int getNumber() { + return number; + } +} From 07a68804328a72694879085cfdc162db4bf39db7 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:21:30 +0900 Subject: [PATCH 005/109] =?UTF-8?q?feat:=20=EB=B0=94=EC=9A=B0=EC=B2=98=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/voucher/VoucherController.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java new file mode 100644 index 0000000000..8f2cf0a12c --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java @@ -0,0 +1,56 @@ +package com.prgms.vouchermanager.contorller.voucher; + +import com.prgms.vouchermanager.contorller.front.FrontController; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.service.voucher.VoucherService; +import com.prgms.vouchermanager.util.io.ConsoleInput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +import java.util.List; + +import static com.prgms.vouchermanager.contorller.voucher.VoucherMenuType.*; + +@Controller +public class VoucherController { + + private final VoucherService voucherService; + + private final ConsoleInput consoleInput; + + private final static Logger logger = LoggerFactory.getLogger(FrontController.class); + + public VoucherController(VoucherService voucherService, ConsoleInput consoleInput) { + this.voucherService = voucherService; + this.consoleInput = consoleInput; + } + + public void run() { + int menu = 0; + try { + menu = consoleInput.inputVoucherMenu(); + } catch (RuntimeException e) { + System.out.println(e.getMessage()); + logger.warn(e.getMessage()); + return; + } + if (menu == CREATE.getNumber()) { + try { + Voucher voucher = consoleInput.inputVoucher(); + voucherService.create(voucher); + } catch (RuntimeException e) { + System.out.println(e.getMessage()); + logger.warn(e.getMessage()); + + } + + } else if (menu == LIST.getNumber()) { + List voucherList = voucherService.getVoucherList(); + + voucherList.stream() + .forEach(voucher -> System.out.println(voucher.toString())); + } + + } +} From 412ab6d4fd9deab4f6f67a4c620225e98e4c557e Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:21:52 +0900 Subject: [PATCH 006/109] =?UTF-8?q?feat:=20=EB=B0=94=EC=9A=B0=EC=B2=98=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=9D=98=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=ED=83=80=EC=9E=85=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/voucher/VoucherMenuType.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java new file mode 100644 index 0000000000..f711bbeff1 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java @@ -0,0 +1,16 @@ +package com.prgms.vouchermanager.contorller.voucher; + +public enum VoucherMenuType { + CREATE(1), LIST(2); + private final int number; + + VoucherMenuType(int number) { + this.number = number; + } + + public int getNumber() { + return number; + } + + +} From 1c15ca8687afd95ec12f618139d7fafc115637de Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:22:06 +0900 Subject: [PATCH 007/109] =?UTF-8?q?feat:=20=EA=B3=A0=EA=B0=9D=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerController.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java new file mode 100644 index 0000000000..8c5d7dfcc5 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java @@ -0,0 +1,40 @@ +package com.prgms.vouchermanager.contorller.customer; + +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.service.customer.CustomerService; +import com.prgms.vouchermanager.util.io.ConsoleInput; +import org.springframework.stereotype.Controller; + +import java.util.List; + +import static com.prgms.vouchermanager.contorller.customer.CustomerMenuType.*; + +@Controller +public class CustomerController { + + private final CustomerService customerService; + private final ConsoleInput consoleInput; + + public CustomerController(CustomerService customerService, ConsoleInput consoleInput) { + this.customerService = customerService; + this.consoleInput = consoleInput; + } + + public void run() { + int menu = 0; + try { + menu = consoleInput.inputCustomerMenu(); + } catch (RuntimeException e) { + System.out.println(e.getMessage()); + return; + } + if (menu == BLACK_LIST.getNumber()) { + + List blackList = customerService .getBlackList(); + + blackList.stream() + .forEach(customer -> System.out.println(customer.toString())); + } + } +} From 5f160c08e21cfcd83eb0ad333a8cd26ce3f0e180 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:22:19 +0900 Subject: [PATCH 008/109] =?UTF-8?q?feat:=20=EA=B3=A0=EA=B0=9D=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=9D=98=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/customer/CustomerMenuType.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java new file mode 100644 index 0000000000..d588a36ac9 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java @@ -0,0 +1,15 @@ +package com.prgms.vouchermanager.contorller.customer; + +public enum CustomerMenuType { + BLACK_LIST(1); + + private final int number; + + CustomerMenuType(int number) { + this.number = number; + } + + public int getNumber() { + return number; + } +} From b0f5eacbb859c8167bc2e94e80bcc2a81fa9ed34 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:23:38 +0900 Subject: [PATCH 009/109] =?UTF-8?q?feat:=20=EB=B0=94=EC=9A=B0=EC=B2=98=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/voucher/FixedAmountVoucher.java | 43 ++++++++++++++++++ .../voucher/PercentDiscountVoucher.java | 44 +++++++++++++++++++ .../domain/voucher/Voucher.java | 14 ++++++ .../domain/voucher/VoucherType.java | 17 +++++++ 4 files changed, 118 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/domain/voucher/FixedAmountVoucher.java create mode 100644 src/main/java/com/prgms/vouchermanager/domain/voucher/PercentDiscountVoucher.java create mode 100644 src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java create mode 100644 src/main/java/com/prgms/vouchermanager/domain/voucher/VoucherType.java diff --git a/src/main/java/com/prgms/vouchermanager/domain/voucher/FixedAmountVoucher.java b/src/main/java/com/prgms/vouchermanager/domain/voucher/FixedAmountVoucher.java new file mode 100644 index 0000000000..9d44867562 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/domain/voucher/FixedAmountVoucher.java @@ -0,0 +1,43 @@ +package com.prgms.vouchermanager.domain.voucher; + +import java.util.UUID; + +public class FixedAmountVoucher implements Voucher{ + + private final UUID id; + + private final long amount; + + private final VoucherType type ; + + public FixedAmountVoucher(UUID id, long amount) { + this.id = id; + this.amount = amount; + type = VoucherType.FIXED_AMOUNT; + } + + + @Override + public UUID getId() { + return id; + } + + @Override + public long getDiscountValue() { + return amount; + } + + @Override + public VoucherType getVoucherType() { + return VoucherType.FIXED_AMOUNT; + } + + @Override + public String toString() { + return "{" + + "id=" + id + + ", amount=" + amount + + ", type=" + type + + '}'; + } +} diff --git a/src/main/java/com/prgms/vouchermanager/domain/voucher/PercentDiscountVoucher.java b/src/main/java/com/prgms/vouchermanager/domain/voucher/PercentDiscountVoucher.java new file mode 100644 index 0000000000..d8bf100cfa --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/domain/voucher/PercentDiscountVoucher.java @@ -0,0 +1,44 @@ +package com.prgms.vouchermanager.domain.voucher; + +import java.util.UUID; + +public class PercentDiscountVoucher implements Voucher { + + private final UUID id; + + private final long percent; + + private final VoucherType type; + + public PercentDiscountVoucher(UUID id, long percent) { + this.id = id; + this.percent = percent; + type = VoucherType.PERCENT_DISCOUNT; + } + + @Override + public UUID getId() { + return id; + } + + @Override + public long getDiscountValue() { + return percent; + } + + @Override + public VoucherType getVoucherType() { + return VoucherType.PERCENT_DISCOUNT; + } + + + + @Override + public String toString() { + return "{" + + "id=" + id + + ", percent=" + percent + + ", type=" + type + + '}'; + } +} diff --git a/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java b/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java new file mode 100644 index 0000000000..5e10e0bbe9 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java @@ -0,0 +1,14 @@ +package com.prgms.vouchermanager.domain.voucher; + +import java.util.UUID; + +public interface Voucher { + UUID getId(); + + long getDiscountValue(); + + VoucherType getVoucherType(); + + + String toString(); +} diff --git a/src/main/java/com/prgms/vouchermanager/domain/voucher/VoucherType.java b/src/main/java/com/prgms/vouchermanager/domain/voucher/VoucherType.java new file mode 100644 index 0000000000..84b0738a47 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/domain/voucher/VoucherType.java @@ -0,0 +1,17 @@ +package com.prgms.vouchermanager.domain.voucher; + +public enum VoucherType { + FIXED_AMOUNT(1), PERCENT_DISCOUNT(2); + + private final int number; + + VoucherType(int number) { + this.number = number; + } + + public int getNumber() { + return number; + } + + +} From 6dc0f9196c6194251fbdfc4e95ecee4fb9eb7a5b Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:24:00 +0900 Subject: [PATCH 010/109] =?UTF-8?q?feat:=20=EA=B3=A0=EA=B0=9D=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/customer/Customer.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java diff --git a/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java b/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java new file mode 100644 index 0000000000..4eb7ac198d --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java @@ -0,0 +1,32 @@ +package com.prgms.vouchermanager.domain.customer; + + +import java.util.UUID; + +public class Customer { + + private final Long id; + + private String name; + + private String email; + + public Customer(Long id, String name, String email) { + this.id = id; + this.name = name; + this.email = email; + } + + public Long getId() { + return id; + } + + @Override + public String toString() { + return "Customer{" + + "id=" + id + + ", name='" + name + '\'' + + ", email='" + email + '\'' + + '}'; + } +} From e1a09e66ad5ebfde4382de6b5b7de1e1a6735423 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:24:21 +0900 Subject: [PATCH 011/109] =?UTF-8?q?feat:=20=EB=B0=94=EC=9A=B0=EC=B2=98=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/voucher/VoucherService.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java diff --git a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java new file mode 100644 index 0000000000..217df2b63d --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java @@ -0,0 +1,26 @@ +package com.prgms.vouchermanager.service.voucher; + + +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.repository.voucher.VoucherRepository; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class VoucherService { + + private final VoucherRepository voucherRepository; + + public VoucherService(VoucherRepository voucherRepository) { + this.voucherRepository = voucherRepository; + } + + public void create(Voucher voucher) { + voucherRepository.create(voucher); + } + + public List getVoucherList() { + return voucherRepository.getAllVouchers(); + } +} From dcda92b3d541b416f725479a5de1cfb6444a9dcf Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:24:32 +0900 Subject: [PATCH 012/109] =?UTF-8?q?feat:=20=EA=B3=A0=EA=B0=9D=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/customer/CustomerService.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java diff --git a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java new file mode 100644 index 0000000000..4a940de87d --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java @@ -0,0 +1,21 @@ +package com.prgms.vouchermanager.service.customer; + +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.repository.customer.CustomerRepository; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class CustomerService { + + private final CustomerRepository customerRepository; + + public CustomerService(CustomerRepository customerRepository) { + this.customerRepository = customerRepository; + } + + public List getBl성ackList() { + return customerRepository.getBlackList(); + } +} From 079cfb219c4545199040acd805bf548ae4bc4377 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:24:46 +0900 Subject: [PATCH 013/109] =?UTF-8?q?feat:=20=EB=B0=94=EC=9A=B0=EC=B2=98=20?= =?UTF-8?q?=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/FileVoucherRepository.java | 43 +++++++++++++++++++ .../voucher/MemoryVoucherRepository.java | 29 +++++++++++++ .../repository/voucher/VoucherRepository.java | 12 ++++++ 3 files changed, 84 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java create mode 100644 src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java create mode 100644 src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java new file mode 100644 index 0000000000..96a33b22c2 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java @@ -0,0 +1,43 @@ +package com.prgms.vouchermanager.repository.voucher; + + +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.util.file.FileManager; +import jakarta.annotation.PreDestroy; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Repository +@Profile("file") +public class FileVoucherRepository implements VoucherRepository{ + private final FileManager fileManager; + + private Mapvouchers ; + + public FileVoucherRepository(FileManager fileManager) { + this.fileManager = fileManager; + vouchers = fileManager.readVoucherCsv(); + + + } + + @Override + public void create(Voucher voucher) { + vouchers.put(voucher.getId(), voucher); + } + + @Override + public List getAllVouchers() { + return new ArrayList<>(vouchers.values()); + } + + @PreDestroy + public void saveRepository() { + fileManager.saveVoucherFile(vouchers); + } +} diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java new file mode 100644 index 0000000000..253ed8fbcf --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java @@ -0,0 +1,29 @@ +package com.prgms.vouchermanager.repository.voucher; + +import com.prgms.vouchermanager.domain.voucher.Voucher; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +@Repository +@Profile("memory") +public class MemoryVoucherRepository implements VoucherRepository{ + + private Mapvouchers; + + public MemoryVoucherRepository() { + this.vouchers = new ConcurrentHashMap<>(); + } + + @Override + public void create(Voucher voucher) { + vouchers.put(voucher.getId(), voucher); + } + @Override + public List getAllVouchers() { + List voucherList = new ArrayList<>(vouchers.values()); + return voucherList; + } +} diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java new file mode 100644 index 0000000000..f1a97e15ea --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java @@ -0,0 +1,12 @@ +package com.prgms.vouchermanager.repository.voucher; + +import com.prgms.vouchermanager.domain.voucher.Voucher; + +import java.util.List; + +public interface VoucherRepository { + + void create(Voucher voucher); + + List getAllVouchers(); +} From a17ddf46a8f5df343db270c772a169410b2ca7b9 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:25:02 +0900 Subject: [PATCH 014/109] =?UTF-8?q?feat:=20=EA=B3=A0=EA=B0=9D=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerRepository.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java new file mode 100644 index 0000000000..358ed3f7d5 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java @@ -0,0 +1,29 @@ +package com.prgms.vouchermanager.repository.customer; + +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.util.file.FileManager; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +@Repository +public class CustomerRepository { + + private final FileManager fileManager; + private Map blackList; + + public CustomerRepository(FileManager fileManager) { + + this.fileManager = fileManager; + blackList = fileManager.readBlackListCsv(); + } + + public List getBlackList() { + ListcustomerList= new ArrayList<>(blackList.values()); + return customerList; + } + +} From b39bfadae13a46162e2c17072b74a327df486352 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:25:38 +0900 Subject: [PATCH 015/109] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/ExceptionType.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/exception/ExceptionType.java diff --git a/src/main/java/com/prgms/vouchermanager/exception/ExceptionType.java b/src/main/java/com/prgms/vouchermanager/exception/ExceptionType.java new file mode 100644 index 0000000000..16c18b751a --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/exception/ExceptionType.java @@ -0,0 +1,26 @@ +package com.prgms.vouchermanager.exception; + +public enum ExceptionType { + INVALID_FRONT_MENU("초기 메뉴 번호를 잘못 입력하셨습니다."), + INVALID_VOUCHER_MENU("바우처 메뉴 번호를 잘못 입력하셨습니다."), + INVALID_CUSTOMER_MENU("고객 메뉴 번호를 잘못 입력하셨습니다."), + + INVALID_VOUCHER_PERCENT("할인율은 최대 100%입니다."), + INVALID_VOUCHER_INFO("쿠폰 정보를 잘못 입력하셨습니다."), + + INVALID_VOUCHER_TYPE("쿠폰 타입을 잘못 입력하셨습니다."), + + INVALID_READ_FILE("파일을 읽을 수 없습니다."), + + INVALID_WRITE_FILE("파일에 저장할 수 없습니다."); + + private final String message; + + ExceptionType(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} From 2136d6f75d7309c67233541d7cc4a78d382bd8b5 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:25:54 +0900 Subject: [PATCH 016/109] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=EA=B0=92=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=EA=B8=B0=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/InputValidation.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/validation/InputValidation.java diff --git a/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java b/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java new file mode 100644 index 0000000000..015a17124a --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java @@ -0,0 +1,38 @@ +package com.prgms.vouchermanager.validation; + +public class InputValidation { + + + public boolean validFrontMenu(int menu) { + if (menu == 1 || menu == 2||menu==3) { + return true; + }return false; + } + + + public boolean validVoucherMenu(int menu) { + if (menu == 1 || menu == 2) { + return true; + }return false; + } + + public boolean validCustomerMenu(int menu) { + if (menu == 1) { + return true; + } + return false; + } + + public boolean validVoucherType(int number) { + if (number==1||number==2) { + return true; + }else return false; + } + + public boolean validPercent(long discountValue) { + if (discountValue > 100) { + return false; + } + return true; + } +} From db26de7b4173d0c2d3bd314ab786d74eb3de5bb5 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:26:08 +0900 Subject: [PATCH 017/109] =?UTF-8?q?feat:=20=ED=8C=8C=EC=9D=BC=20=EC=9E=85?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EB=A7=A4=EB=8B=88=EC=A0=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/util/file/FileManager.java | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/util/file/FileManager.java diff --git a/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java b/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java new file mode 100644 index 0000000000..14e67a6746 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java @@ -0,0 +1,105 @@ +package com.prgms.vouchermanager.util.file; + +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; +import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.voucher.VoucherType; +import com.prgms.vouchermanager.exception.ExceptionType; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.*; +import java.util.ArrayList; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import static com.prgms.vouchermanager.domain.voucher.VoucherType.valueOf; +import static com.prgms.vouchermanager.exception.ExceptionType.*; + +/** + * + * 1. 바우처 FIle을 Repo에 return하기 + * 2. Repo를 바우처 File에 저장하기 + * + * 3. BlackList File을 Repo에 return하기 + * + */ +@Component +public class FileManager { + + private final String voucherListPath; + private final String blackListPath; + + + public FileManager( + @Value("${file.path.voucher}") String voucherListPath, + @Value("${file.path.blacklist}") String blackListPath ) { + this.voucherListPath = voucherListPath; + this.blackListPath = blackListPath; + + } + + public Map readVoucherCsv() { + Map voucherMap = new ConcurrentHashMap<>(); + + try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(voucherListPath)))) { + String line = ""; + br.readLine(); + while ((line = br.readLine()) != null) { + String[] split = line.split(", "); + + UUID id = UUID.fromString(split[0]); + Long value = Long.parseLong(split[1]); + VoucherType voucherType = valueOf(split[2]); + + if (voucherType == VoucherType.FIXED_AMOUNT) { + voucherMap.put(id, new FixedAmountVoucher(id,value)); + } else if (voucherType == VoucherType.PERCENT_DISCOUNT) { + voucherMap.put(id, new PercentDiscountVoucher(id, value)); + } + } + } catch (IOException e) { + throw new RuntimeException(INVALID_READ_FILE.getMessage()); + } + return voucherMap; + } + + + public Map readBlackListCsv() { + + Map customerMap = new ConcurrentHashMap<>(); + + try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(blackListPath)))) { + String line = ""; + br.readLine(); + while ((line = br.readLine()) != null) { + String[] split = line.split(", "); + + Long id = Long.parseLong(split[0]); + String name = split[1]; + String email = split[2]; + + customerMap.put(id, new Customer(id, name, email)); + } + } catch (IOException e) { + throw new RuntimeException(INVALID_READ_FILE.getMessage()); + } + return customerMap; + } + + public void saveVoucherFile(MapvoucherMap) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(voucherListPath))) { + bw.write("id, discount value, voucher type"); + bw.newLine(); + for (Voucher voucher : new ArrayList<>(voucherMap.values())) { + bw.write(voucher.getId() + ", " + voucher.getDiscountValue()+", "+voucher.getVoucherType()); + bw.newLine(); + } + } catch (IOException e) { + throw new RuntimeException(INVALID_WRITE_FILE.getMessage()); + } + } + +} From 8c2ae7f129760f601f93bd23007728b20d92e614 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:26:28 +0900 Subject: [PATCH 018/109] =?UTF-8?q?feat:=20=EC=BD=98=EC=86=94=20=EC=9E=85?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EB=A7=A4=EB=8B=88=EC=A0=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/util/io/ConsoleInput.java | 158 ++++++++++++++++++ .../vouchermanager/util/io/ConsoleOutput.java | 64 +++++++ 2 files changed, 222 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java create mode 100644 src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java new file mode 100644 index 0000000000..499b3f9a13 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java @@ -0,0 +1,158 @@ +package com.prgms.vouchermanager.util.io; + + +import com.prgms.vouchermanager.contorller.front.FrontController; +import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; +import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.validation.InputValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.Scanner; +import java.util.UUID; + +import static com.prgms.vouchermanager.domain.voucher.VoucherType.*; +import static com.prgms.vouchermanager.exception.ExceptionType.*; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_INFO; + +@Component +public class ConsoleInput { + private final Scanner scanner; + private final InputValidation inputValidation; + private final ConsoleOutput consoleOutput; + + private final static Logger logger = LoggerFactory.getLogger(FrontController.class); + + + public ConsoleInput() { + this.inputValidation = new InputValidation(); + this.consoleOutput = new ConsoleOutput(); + scanner = new Scanner(System.in); + } + + public int inputFrontMenu() { + + consoleOutput.printFrontMenu(); + + int menu ; + + try { + menu = Integer.parseInt(scanner.next()); + } catch (RuntimeException e) { + logger.warn(e.getMessage()); + throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); + } + + if (!inputValidation.validFrontMenu(menu)) { + logger.warn(INVALID_FRONT_MENU.getMessage()); + throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); + } + return menu; + } + + public int inputVoucherMenu() { + + consoleOutput.printVoucherMenu(); + + int menu ; + + try { + menu = Integer.parseInt(scanner.next()); + } catch (RuntimeException e) { + logger.warn(e.getMessage()); + throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); + } + + + if (!inputValidation.validVoucherMenu(menu)) { + logger.warn(INVALID_VOUCHER_MENU.getMessage()); + throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); + } + return menu; + + } + + public int inputCustomerMenu() { + + consoleOutput.printCustomerMenu(); + + int menu ; + + try { + menu = Integer.parseInt(scanner.next()); + } catch (RuntimeException e) { + logger.warn(e.getMessage()); + throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); + } + + if (!inputValidation.validCustomerMenu(menu)) { + logger.warn(INVALID_CUSTOMER_MENU.getMessage()); + throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); + } + return menu; + + } + + public Voucher inputVoucher() { + int voucherType = 0; + + Voucher voucher = null; + try { + voucherType = inputVoucherType(); + } catch (RuntimeException e) { + logger.warn(e.getMessage()); + throw new RuntimeException(e.getMessage()); + } + + + try { + if (voucherType == FIXED_AMOUNT.getNumber()) { + + consoleOutput.printVoucherAmount(); + + long amount = Integer.parseInt(scanner.next()); + + voucher = new FixedAmountVoucher(UUID.randomUUID(), amount); + + } else { + + consoleOutput.printVoucherPercent(); + + long percent = Integer.parseInt(scanner.next()); + + voucher = new PercentDiscountVoucher(UUID.randomUUID(), percent); + } + } catch (RuntimeException e) { + logger.warn(e.getMessage()); + throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); + } + + return voucher; + } + + private int inputVoucherType() { + + consoleOutput.printVoucherType(); + + int type ; + + try { + type = Integer.parseInt(scanner.next()); + } catch (RuntimeException e) { + logger.warn(e.getMessage()); + throw new RuntimeException(INVALID_VOUCHER_TYPE.getMessage()); + } + + + if (inputValidation.validVoucherType(type)) { + return type; + } else { + logger.warn(INVALID_VOUCHER_TYPE.getMessage()); + throw new RuntimeException(INVALID_VOUCHER_TYPE.getMessage()); + } + } + + +} diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java new file mode 100644 index 0000000000..b815e73ee1 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java @@ -0,0 +1,64 @@ +package com.prgms.vouchermanager.util.io; + +public class ConsoleOutput { + + + public ConsoleOutput() { + } + public void printFrontMenu() { + System.out.println(""" + + 사용할 메뉴를 선택해주세요. + + 1. Voucher + + 2. Customer + + 3. EXIT + """); + } + + public void printVoucherMenu() { + System.out.println(""" + === Voucher Program === + + 이용할 바우처 메뉴를 선택해주세요 + + 1. create + + 2. list + + """); + } + + + public void printVoucherType() { + System.out.println(""" + + 이용하실 쿠폰의 타입 번호를 입력해주세요 + + 1. FixedAmount + + 2. PercentDiscount + + """); + } + + public void printCustomerMenu() { + System.out.println(""" + + 이용하실 고객 메뉴를 입력해주세요 + + 1. black list + + """); + } + + + public void printVoucherAmount() { + System.out.println("쿠폰의 할인 금액을 입력해주세요"); + } + public void printVoucherPercent() { + System.out.println("쿠폰의 할인률을 입력해주세요"); + } +} From 38ee6685d14fe8af2f41691a3a7f2bfbb39da031 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 03:28:08 +0900 Subject: [PATCH 019/109] =?UTF-8?q?chore:=20=ED=95=84=EC=9A=94=20resource?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yaml | 8 +++++ src/main/resources/customer_blackList.csv | 6 ++++ src/main/resources/logback.xml | 37 +++++++++++++++++++++++ src/main/resources/voucher_list.csv | 4 +++ 4 files changed, 55 insertions(+) create mode 100644 src/main/resources/application.yaml create mode 100644 src/main/resources/customer_blackList.csv create mode 100644 src/main/resources/logback.xml create mode 100644 src/main/resources/voucher_list.csv diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 0000000000..1e0fa59c34 --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,8 @@ +spring: + profiles: + active: file + +file: + path: + voucher: src/main/resources/voucher_list.csv + blacklist: src/main/resources/customer_blackList.csv diff --git a/src/main/resources/customer_blackList.csv b/src/main/resources/customer_blackList.csv new file mode 100644 index 0000000000..8b553c5cd4 --- /dev/null +++ b/src/main/resources/customer_blackList.csv @@ -0,0 +1,6 @@ +id, name, email +1, kim, kim@naver.com +2, lee, lee@naver.com +3, park, park@naver.com +4, hong, hong@naver.com +5, kang, kang@naver.com diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000000..243ad25b70 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,37 @@ + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + logs/access.log + + logs/access-%d{yyyy-MM-dd}.log + + + + ${FILE_LOG_PATTERN} + + + + + + + + + + + + + + diff --git a/src/main/resources/voucher_list.csv b/src/main/resources/voucher_list.csv new file mode 100644 index 0000000000..9c4001d695 --- /dev/null +++ b/src/main/resources/voucher_list.csv @@ -0,0 +1,4 @@ +id, discount value, voucher type +96d02c0a-1a58-4191-93d4-2cee987886f1, 6, PERCENT_DISCOUNT +df5dbaa0-d748-4d04-9138-89a9fa911450, 10000, FIXED_AMOUNT +63feab9e-36ed-474a-92f8-1ade4ffb7788, 30, PERCENT_DISCOUNT From 063c0896dcfa3fdcbd5edfcf731639cbed8348a0 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 14:44:27 +0900 Subject: [PATCH 020/109] =?UTF-8?q?refactor:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgms/vouchermanager/service/customer/CustomerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java index 4a940de87d..e47d718d17 100644 --- a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java +++ b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java @@ -15,7 +15,7 @@ public CustomerService(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } - public List getBl성ackList() { + public List getBlackList() { return customerRepository.getBlackList(); } } From 23393d28250f500d82f3981c4c9d16f1fa73511b Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 14:48:09 +0900 Subject: [PATCH 021/109] =?UTF-8?q?refactor:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgms/vouchermanager/service/customer/CustomerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java index 4a940de87d..e47d718d17 100644 --- a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java +++ b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java @@ -15,7 +15,7 @@ public CustomerService(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } - public List getBl성ackList() { + public List getBlackList() { return customerRepository.getBlackList(); } } From 84127ecc8ad0bc5877e661fd2aee09d24b3fcf06 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 19 Oct 2023 16:01:38 +0900 Subject: [PATCH 022/109] =?UTF-8?q?refactor:=20=EB=B0=94=EC=9A=B0=EC=B2=98?= =?UTF-8?q?=EC=9D=98=20percent=20=EC=9E=85=EB=A0=A5=EA=B0=92=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/prgms/vouchermanager/util/io/ConsoleInput.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java index 499b3f9a13..c2595c1b82 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java @@ -122,6 +122,10 @@ public Voucher inputVoucher() { long percent = Integer.parseInt(scanner.next()); + if (!inputValidation.validPercent(percent)) { + throw new RuntimeException(); + } + voucher = new PercentDiscountVoucher(UUID.randomUUID(), percent); } } catch (RuntimeException e) { From 6946738f4bcaf7e0cae55b11c033c40dbb573994 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 17:40:12 +0900 Subject: [PATCH 023/109] =?UTF-8?q?refactor:=20CustomerRepository=20?= =?UTF-8?q?=EB=82=B4=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/customer/CustomerRepository.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java index 358ed3f7d5..2065030fd5 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java @@ -4,26 +4,22 @@ import com.prgms.vouchermanager.util.file.FileManager; import org.springframework.stereotype.Repository; -import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Map; @Repository public class CustomerRepository { - - private final FileManager fileManager; private Map blackList; public CustomerRepository(FileManager fileManager) { - this.fileManager = fileManager; blackList = fileManager.readBlackListCsv(); } public List getBlackList() { - ListcustomerList= new ArrayList<>(blackList.values()); - return customerList; + + return blackList.values() + .stream().toList(); } } From 27ee088a2baf0f7313c31bae64872ddca8510f53 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 17:42:51 +0900 Subject: [PATCH 024/109] =?UTF-8?q?refactor:=20stream.forEach->=20forEach?= =?UTF-8?q?=20=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/customer/CustomerController.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java index 8c5d7dfcc5..adff5feac3 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java @@ -1,7 +1,6 @@ package com.prgms.vouchermanager.contorller.customer; import com.prgms.vouchermanager.domain.customer.Customer; -import com.prgms.vouchermanager.domain.voucher.Voucher; import com.prgms.vouchermanager.service.customer.CustomerService; import com.prgms.vouchermanager.util.io.ConsoleInput; import org.springframework.stereotype.Controller; @@ -33,8 +32,8 @@ public void run() { List blackList = customerService .getBlackList(); - blackList.stream() - .forEach(customer -> System.out.println(customer.toString())); + blackList. + forEach(customer -> System.out.println(customer.toString())); } } } From 978183ba6017f0c880647574b991ce25a6bd6333 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 17:45:49 +0900 Subject: [PATCH 025/109] =?UTF-8?q?refactor:=20scanner.nextInt()=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgms/vouchermanager/util/io/ConsoleInput.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java index c2595c1b82..a8342fcdc8 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java @@ -39,7 +39,7 @@ public int inputFrontMenu() { int menu ; try { - menu = Integer.parseInt(scanner.next()); + menu = scanner.nextInt(); } catch (RuntimeException e) { logger.warn(e.getMessage()); throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); @@ -59,7 +59,7 @@ public int inputVoucherMenu() { int menu ; try { - menu = Integer.parseInt(scanner.next()); + menu = scanner.nextInt(); } catch (RuntimeException e) { logger.warn(e.getMessage()); throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); @@ -81,7 +81,7 @@ public int inputCustomerMenu() { int menu ; try { - menu = Integer.parseInt(scanner.next()); + menu = scanner.nextInt(); } catch (RuntimeException e) { logger.warn(e.getMessage()); throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); @@ -112,7 +112,7 @@ public Voucher inputVoucher() { consoleOutput.printVoucherAmount(); - long amount = Integer.parseInt(scanner.next()); + long amount = scanner.nextLong(); voucher = new FixedAmountVoucher(UUID.randomUUID(), amount); @@ -120,7 +120,7 @@ public Voucher inputVoucher() { consoleOutput.printVoucherPercent(); - long percent = Integer.parseInt(scanner.next()); + long percent = scanner.nextLong(); if (!inputValidation.validPercent(percent)) { throw new RuntimeException(); @@ -143,7 +143,7 @@ private int inputVoucherType() { int type ; try { - type = Integer.parseInt(scanner.next()); + type = scanner.nextInt(); } catch (RuntimeException e) { logger.warn(e.getMessage()); throw new RuntimeException(INVALID_VOUCHER_TYPE.getMessage()); From b08ab1f0ec8fc0a99711858b0331752c319e4cb3 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 17:48:50 +0900 Subject: [PATCH 026/109] =?UTF-8?q?refactor:=20private=20static=20final=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/contorller/front/FrontController.java | 3 ++- .../vouchermanager/contorller/voucher/VoucherController.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java index dfd0b3884c..6a5bc95e12 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java @@ -14,13 +14,14 @@ @Controller public class FrontController { + private final static Logger logger = LoggerFactory.getLogger(FrontController.class); + private final ConsoleInput consoleInput; private final VoucherController voucherController; private final CustomerController customerController; - private final static Logger logger = LoggerFactory.getLogger(FrontController.class); public FrontController(ConsoleInput consoleInput, VoucherController voucherController, CustomerController customerController) { diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java index 8f2cf0a12c..7fc0842c38 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java @@ -15,11 +15,12 @@ @Controller public class VoucherController { + private final static Logger logger = LoggerFactory.getLogger(FrontController.class); + private final VoucherService voucherService; private final ConsoleInput consoleInput; - private final static Logger logger = LoggerFactory.getLogger(FrontController.class); public VoucherController(VoucherService voucherService, ConsoleInput consoleInput) { this.voucherService = voucherService; @@ -42,7 +43,6 @@ public void run() { } catch (RuntimeException e) { System.out.println(e.getMessage()); logger.warn(e.getMessage()); - } } else if (menu == LIST.getNumber()) { From cc0e5bed97c61b56ecf05ae8a9a2d9424596553b Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 17:50:04 +0900 Subject: [PATCH 027/109] =?UTF-8?q?refactor:=20Customer=EC=9D=98=20final?= =?UTF-8?q?=20=ED=82=A4=EC=9B=8C=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgms/vouchermanager/domain/customer/Customer.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java b/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java index 4eb7ac198d..1374839017 100644 --- a/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java +++ b/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java @@ -1,15 +1,13 @@ package com.prgms.vouchermanager.domain.customer; -import java.util.UUID; - public class Customer { private final Long id; - private String name; + private final String name; - private String email; + private final String email; public Customer(Long id, String name, String email) { this.id = id; @@ -17,10 +15,6 @@ public Customer(Long id, String name, String email) { this.email = email; } - public Long getId() { - return id; - } - @Override public String toString() { return "Customer{" + From e7268703a121a2253bbedf9718caef5f529d63ba Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 17:55:04 +0900 Subject: [PATCH 028/109] =?UTF-8?q?refactor:=20Voucher=EC=9D=98=20?= =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/prgms/vouchermanager/domain/voucher/Voucher.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java b/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java index 5e10e0bbe9..32889a7c62 100644 --- a/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java +++ b/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java @@ -9,6 +9,4 @@ public interface Voucher { VoucherType getVoucherType(); - - String toString(); } From b90360cec207857ce21e9c4645ad52a9253997b2 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 18:03:41 +0900 Subject: [PATCH 029/109] =?UTF-8?q?refactor:=20vouchers=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=EC=97=90=20final=20=ED=82=A4=EC=9B=8C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/voucher/FileVoucherRepository.java | 2 +- .../repository/voucher/MemoryVoucherRepository.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java index 96a33b22c2..698b71af5d 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java @@ -17,7 +17,7 @@ public class FileVoucherRepository implements VoucherRepository{ private final FileManager fileManager; - private Mapvouchers ; + private final Mapvouchers ; public FileVoucherRepository(FileManager fileManager) { this.fileManager = fileManager; diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java index 253ed8fbcf..6de6408f10 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java @@ -11,7 +11,7 @@ @Profile("memory") public class MemoryVoucherRepository implements VoucherRepository{ - private Mapvouchers; + private final Mapvouchers; public MemoryVoucherRepository() { this.vouchers = new ConcurrentHashMap<>(); From 7dee6d98198a4d323de5239efbe13271d70733dc Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 18:08:27 +0900 Subject: [PATCH 030/109] =?UTF-8?q?refactor:=20validation=20=EB=82=B4=20?= =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/InputValidation.java | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java b/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java index 015a17124a..b2e5938e89 100644 --- a/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java +++ b/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java @@ -4,35 +4,23 @@ public class InputValidation { public boolean validFrontMenu(int menu) { - if (menu == 1 || menu == 2||menu==3) { - return true; - }return false; + return menu == 1 || menu == 2||menu==3; } public boolean validVoucherMenu(int menu) { - if (menu == 1 || menu == 2) { - return true; - }return false; + return menu == 1 || menu == 2; } public boolean validCustomerMenu(int menu) { - if (menu == 1) { - return true; - } - return false; + return menu == 1; } public boolean validVoucherType(int number) { - if (number==1||number==2) { - return true; - }else return false; + return number==1||number==2; } public boolean validPercent(long discountValue) { - if (discountValue > 100) { - return false; - } - return true; + return discountValue <= 100; } } From e573671873f68704309eadc10b1ceefd48425dd0 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 20:22:46 +0900 Subject: [PATCH 031/109] =?UTF-8?q?feat:=20Voucher=20create=20dto=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/dto/CreateVoucherDto.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/dto/CreateVoucherDto.java diff --git a/src/main/java/com/prgms/vouchermanager/dto/CreateVoucherDto.java b/src/main/java/com/prgms/vouchermanager/dto/CreateVoucherDto.java new file mode 100644 index 0000000000..238c95f82a --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/dto/CreateVoucherDto.java @@ -0,0 +1,20 @@ +package com.prgms.vouchermanager.dto; + +public class CreateVoucherDto { + + private final long value; + private final int VoucherType; + + public CreateVoucherDto(long value, int voucherType) { + this.value = value; + this.VoucherType = voucherType; + } + + public long getValue() { + return value; + } + + public int getVoucherType() { + return VoucherType; + } +} From 16e2d1f11bbe0da2c84c2a7fdad539728fdb142a Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 20:36:16 +0900 Subject: [PATCH 032/109] =?UTF-8?q?refactor:=20ConsoleInput=EC=9D=B4=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EB=B0=9B=EA=B8=B0=EC=99=80=20=EA=B0=92?= =?UTF-8?q?=EC=9D=98=20=ED=8F=AC=EB=A7=B7=20=EA=B2=80=EC=A6=9D=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=EB=A7=8C=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/util/io/ConsoleInput.java | 105 ++---------------- 1 file changed, 11 insertions(+), 94 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java index a8342fcdc8..90f5e1476b 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java @@ -2,60 +2,39 @@ import com.prgms.vouchermanager.contorller.front.FrontController; -import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; -import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; -import com.prgms.vouchermanager.domain.voucher.Voucher; -import com.prgms.vouchermanager.validation.InputValidation; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.Scanner; -import java.util.UUID; -import static com.prgms.vouchermanager.domain.voucher.VoucherType.*; import static com.prgms.vouchermanager.exception.ExceptionType.*; import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_INFO; @Component public class ConsoleInput { - private final Scanner scanner; - private final InputValidation inputValidation; - private final ConsoleOutput consoleOutput; private final static Logger logger = LoggerFactory.getLogger(FrontController.class); + private final Scanner scanner; public ConsoleInput() { - this.inputValidation = new InputValidation(); - this.consoleOutput = new ConsoleOutput(); scanner = new Scanner(System.in); } public int inputFrontMenu() { - - consoleOutput.printFrontMenu(); - - int menu ; - try { - menu = scanner.nextInt(); + return scanner.nextInt(); } catch (RuntimeException e) { logger.warn(e.getMessage()); + scanner.next(); throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); } - - if (!inputValidation.validFrontMenu(menu)) { - logger.warn(INVALID_FRONT_MENU.getMessage()); - throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); - } - return menu; } public int inputVoucherMenu() { - consoleOutput.printVoucherMenu(); - int menu ; try { @@ -64,21 +43,13 @@ public int inputVoucherMenu() { logger.warn(e.getMessage()); throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); } - - - if (!inputValidation.validVoucherMenu(menu)) { - logger.warn(INVALID_VOUCHER_MENU.getMessage()); - throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); - } return menu; } public int inputCustomerMenu() { - consoleOutput.printCustomerMenu(); - - int menu ; + int menu; try { menu = scanner.nextInt(); @@ -87,76 +58,22 @@ public int inputCustomerMenu() { throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); } - if (!inputValidation.validCustomerMenu(menu)) { - logger.warn(INVALID_CUSTOMER_MENU.getMessage()); - throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); - } return menu; - } - public Voucher inputVoucher() { - int voucherType = 0; - - Voucher voucher = null; + public int inputVoucherType() { try { - voucherType = inputVoucherType(); + return scanner.nextInt(); } catch (RuntimeException e) { - logger.warn(e.getMessage()); - throw new RuntimeException(e.getMessage()); - } - - - try { - if (voucherType == FIXED_AMOUNT.getNumber()) { - - consoleOutput.printVoucherAmount(); - - long amount = scanner.nextLong(); - - voucher = new FixedAmountVoucher(UUID.randomUUID(), amount); - - } else { - - consoleOutput.printVoucherPercent(); - - long percent = scanner.nextLong(); - - if (!inputValidation.validPercent(percent)) { - throw new RuntimeException(); - } - - voucher = new PercentDiscountVoucher(UUID.randomUUID(), percent); - } - } catch (RuntimeException e) { - logger.warn(e.getMessage()); - throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); + throw new RuntimeException(INVALID_VOUCHER_TYPE.getMessage()); } - - return voucher; } - private int inputVoucherType() { - - consoleOutput.printVoucherType(); - - int type ; - + public long inputVoucherValue() { try { - type = scanner.nextInt(); + return scanner.nextLong(); } catch (RuntimeException e) { - logger.warn(e.getMessage()); - throw new RuntimeException(INVALID_VOUCHER_TYPE.getMessage()); - } - - - if (inputValidation.validVoucherType(type)) { - return type; - } else { - logger.warn(INVALID_VOUCHER_TYPE.getMessage()); - throw new RuntimeException(INVALID_VOUCHER_TYPE.getMessage()); + throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); } } - - } From c319e0577511be43ed31da347fcc7339ec5752d0 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 20:37:13 +0900 Subject: [PATCH 033/109] =?UTF-8?q?refactor:=20ConsoleOutput=EC=9D=98=20Be?= =?UTF-8?q?an=EB=93=B1=EB=A1=9D=EA=B3=BC=20=EA=B8=B0=EB=8A=A5=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/prgms/vouchermanager/util/io/ConsoleOutput.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java index b815e73ee1..5ceda3c843 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java @@ -1,5 +1,8 @@ package com.prgms.vouchermanager.util.io; +import org.springframework.stereotype.Component; + +@Component public class ConsoleOutput { @@ -56,9 +59,6 @@ public void printCustomerMenu() { public void printVoucherAmount() { - System.out.println("쿠폰의 할인 금액을 입력해주세요"); - } - public void printVoucherPercent() { - System.out.println("쿠폰의 할인률을 입력해주세요"); + System.out.println("쿠폰의 할인값을 입력해주세요"); } } From 12e4038159579e02f421ea4483ce4fe7406af318 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 20:37:56 +0900 Subject: [PATCH 034/109] =?UTF-8?q?refactor:=20InputValidation=EC=9D=98=20?= =?UTF-8?q?Bean=EB=93=B1=EB=A1=9D=EA=B3=BC=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/validation/InputValidation.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java b/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java index b2e5938e89..a4bdd8dfff 100644 --- a/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java +++ b/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java @@ -1,5 +1,8 @@ package com.prgms.vouchermanager.validation; +import org.springframework.stereotype.Component; + +@Component public class InputValidation { @@ -16,11 +19,7 @@ public boolean validCustomerMenu(int menu) { return menu == 1; } - public boolean validVoucherType(int number) { - return number==1||number==2; - } - - public boolean validPercent(long discountValue) { - return discountValue <= 100; + public boolean validVoucherPercent(long percent) { + return percent<=100 ; } } From d0bb01919d71a948b17ff385b8002c9855705db9 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 20:38:52 +0900 Subject: [PATCH 035/109] =?UTF-8?q?refactor:=20FrontController=EC=97=90?= =?UTF-8?q?=EC=84=9C=20Voucher=EB=A9=94=EB=89=B4=EC=99=80=20Customer?= =?UTF-8?q?=EB=A9=94=EB=89=B4=EB=A5=BC=20=EB=AA=A8=EB=91=90=20=EB=8B=B4?= =?UTF-8?q?=EB=8B=B9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/front/FrontController.java | 72 +++++++++++++++++-- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java index 6a5bc95e12..cd6c417f68 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java @@ -4,11 +4,18 @@ import com.prgms.vouchermanager.contorller.customer.CustomerController; import com.prgms.vouchermanager.contorller.voucher.VoucherController; import com.prgms.vouchermanager.util.io.ConsoleInput; +import com.prgms.vouchermanager.util.io.ConsoleOutput; +import com.prgms.vouchermanager.validation.InputValidation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; +import static com.prgms.vouchermanager.contorller.customer.CustomerMenuType.BLACK_LIST; import static com.prgms.vouchermanager.contorller.front.FrontMenuType.*; +import static com.prgms.vouchermanager.contorller.voucher.VoucherMenuType.CREATE; +import static com.prgms.vouchermanager.contorller.voucher.VoucherMenuType.LIST; +import static com.prgms.vouchermanager.exception.ExceptionType.*; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_CUSTOMER_MENU; @Controller @@ -18,14 +25,20 @@ public class FrontController { private final ConsoleInput consoleInput; + private final ConsoleOutput consoleOutput; + + private final InputValidation inputValidation; + private final VoucherController voucherController; private final CustomerController customerController; - public FrontController(ConsoleInput consoleInput, VoucherController voucherController, CustomerController customerController) { + public FrontController(ConsoleInput consoleInput, ConsoleOutput consoleOutput, InputValidation inputValidation, VoucherController voucherController, CustomerController customerController) { this.consoleInput = consoleInput; + this.consoleOutput = consoleOutput; + this.inputValidation = inputValidation; this.voucherController = voucherController; this.customerController = customerController; @@ -34,12 +47,16 @@ public FrontController(ConsoleInput consoleInput, VoucherController voucherContr public void run() { boolean end = false; - int menu; + int menu =0; while (!end) { try { + consoleOutput.printFrontMenu(); menu = consoleInput.inputFrontMenu(); + if (!inputValidation.validFrontMenu(menu)) { + throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); + } } catch (RuntimeException e) { System.out.println(e.getMessage()); logger.warn(e.getMessage()); @@ -47,13 +64,60 @@ public void run() { } if (menu == VOUCHER.getNumber()) { - voucherController.run(); + runVoucherController(); } else if (menu == CUSTOMER.getNumber()) { - customerController.run(); + runCustomerContoller(); } else { end = true; } } } + private void runVoucherController() { + + consoleOutput.printVoucherMenu(); + int menu = 0; + try { + menu = consoleInput.inputVoucherMenu(); + + if (!inputValidation.validVoucherMenu(menu)) { + logger.warn(INVALID_VOUCHER_MENU.getMessage()); + throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); + } + + } catch (RuntimeException e) { + + System.out.println(e.getMessage()); + logger.warn(e.getMessage()); + return; + } + + if (menu == CREATE.getNumber()) { + voucherController.create(); + } else if (menu == LIST.getNumber()) { + voucherController.getList(); + } + } + + private void runCustomerContoller() { + + consoleOutput.printCustomerMenu(); + int menu = 0; + try { + menu = consoleInput.inputCustomerMenu(); + + if (!inputValidation.validCustomerMenu(menu)) { + logger.warn(INVALID_CUSTOMER_MENU.getMessage()); + throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); + } + + } catch (RuntimeException e) { + System.out.println(e.getMessage()); + logger.warn(e.getMessage()); + return; + } + if (menu == BLACK_LIST.getNumber()) { + customerController.getBlackList(); + } + } } From b84387a2e7c07930ed6af69b7449da6d233e2819 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 20:39:37 +0900 Subject: [PATCH 036/109] =?UTF-8?q?refactor:=20VoucherController=EC=9D=80?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=EB=90=9C=20=EB=A9=94=EB=89=B4=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EB=8F=99=EC=9E=91=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/voucher/VoucherController.java | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java index 7fc0842c38..56a3910dfd 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java @@ -2,15 +2,16 @@ import com.prgms.vouchermanager.contorller.front.FrontController; import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.dto.CreateVoucherDto; import com.prgms.vouchermanager.service.voucher.VoucherService; import com.prgms.vouchermanager.util.io.ConsoleInput; +import com.prgms.vouchermanager.util.io.ConsoleOutput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import java.util.List; -import static com.prgms.vouchermanager.contorller.voucher.VoucherMenuType.*; @Controller public class VoucherController { @@ -21,36 +22,32 @@ public class VoucherController { private final ConsoleInput consoleInput; + private final ConsoleOutput consoleOutput; - public VoucherController(VoucherService voucherService, ConsoleInput consoleInput) { + public VoucherController(VoucherService voucherService, ConsoleInput consoleInput, ConsoleOutput consoleOutput) { this.voucherService = voucherService; this.consoleInput = consoleInput; + this.consoleOutput = consoleOutput; } - public void run() { - int menu = 0; - try { - menu = consoleInput.inputVoucherMenu(); + public void create() { + try{ + consoleOutput.printVoucherType(); + int voucherType = consoleInput.inputVoucherType(); + consoleOutput.printVoucherAmount(); + long value = consoleInput.inputVoucherValue(); + voucherService.create(new CreateVoucherDto(value,voucherType)); + } catch (RuntimeException e) { System.out.println(e.getMessage()); logger.warn(e.getMessage()); - return; - } - if (menu == CREATE.getNumber()) { - try { - Voucher voucher = consoleInput.inputVoucher(); - voucherService.create(voucher); - } catch (RuntimeException e) { - System.out.println(e.getMessage()); - logger.warn(e.getMessage()); - } - - } else if (menu == LIST.getNumber()) { - List voucherList = voucherService.getVoucherList(); - - voucherList.stream() - .forEach(voucher -> System.out.println(voucher.toString())); } + } + + public void getList() { + List voucherList = voucherService.getVoucherList(); + + voucherList.forEach(voucher -> System.out.println(voucher.toString())); } } From 05de375a9200a832436d1ed1b9d81fde79c56059 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 20:39:55 +0900 Subject: [PATCH 037/109] =?UTF-8?q?refactor:=20CustomerController=EC=9D=80?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=EB=90=9C=20=EB=A9=94=EB=89=B4=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EB=8F=99=EC=9E=91=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerController.java | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java index adff5feac3..86febc0197 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java @@ -13,27 +13,14 @@ public class CustomerController { private final CustomerService customerService; - private final ConsoleInput consoleInput; - public CustomerController(CustomerService customerService, ConsoleInput consoleInput) { + public CustomerController(CustomerService customerService) { this.customerService = customerService; - this.consoleInput = consoleInput; } + public void getBlackList() { + List blackList = customerService.getBlackList(); - public void run() { - int menu = 0; - try { - menu = consoleInput.inputCustomerMenu(); - } catch (RuntimeException e) { - System.out.println(e.getMessage()); - return; - } - if (menu == BLACK_LIST.getNumber()) { - - List blackList = customerService .getBlackList(); - - blackList. - forEach(customer -> System.out.println(customer.toString())); - } + blackList. + forEach(customer -> System.out.println(customer.toString())); } } From 84d433134ee7957a5379ff4a32af81aec0a84f26 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 20 Oct 2023 20:41:19 +0900 Subject: [PATCH 038/109] =?UTF-8?q?refactor:=20VoucherService=EC=97=90?= =?UTF-8?q?=EC=84=9C=20dto->domain=20=EB=B3=80=ED=99=98=EA=B3=BC=20domain?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EA=B0=92=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=EC=9D=84=20=EC=8B=9C=EB=8F=84=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/voucher/VoucherService.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java index 217df2b63d..004741b1db 100644 --- a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java +++ b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java @@ -1,22 +1,42 @@ package com.prgms.vouchermanager.service.voucher; +import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; +import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.dto.CreateVoucherDto; +import com.prgms.vouchermanager.exception.ExceptionType; import com.prgms.vouchermanager.repository.voucher.VoucherRepository; +import com.prgms.vouchermanager.validation.InputValidation; import org.springframework.stereotype.Service; import java.util.List; +import java.util.UUID; @Service public class VoucherService { + private final InputValidation validation; private final VoucherRepository voucherRepository; - public VoucherService(VoucherRepository voucherRepository) { + public VoucherService(InputValidation validation, VoucherRepository voucherRepository) { + this.validation = validation; this.voucherRepository = voucherRepository; } - public void create(Voucher voucher) { + public void create(CreateVoucherDto dto) { + + Voucher voucher = null; + if (dto.getVoucherType() == 1) { + voucher = new FixedAmountVoucher(UUID.randomUUID(), dto.getValue()); + } else if (dto.getVoucherType() == 2) { + if (!validation.validVoucherPercent(dto.getValue())) { + throw new RuntimeException(ExceptionType.INVALID_VOUCHER_PERCENT.getMessage()); + } + voucher = new PercentDiscountVoucher(UUID.randomUUID(), dto.getValue()); + } else + return; + voucherRepository.create(voucher); } From a1616a960338c595079a9ffc650ff0a2e2fefb41 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 20:55:45 +0900 Subject: [PATCH 039/109] =?UTF-8?q?refactor:=20FrontController=EC=9D=98=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20switch-ca?= =?UTF-8?q?se=EB=AC=B8=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/front/FrontController.java | 102 ++++++++++++------ .../contorller/front/FrontMenuType.java | 12 ++- 2 files changed, 78 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java index cd6c417f68..27eafc11be 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java @@ -2,7 +2,11 @@ import com.prgms.vouchermanager.contorller.customer.CustomerController; +import com.prgms.vouchermanager.contorller.customer.CustomerMenuType; import com.prgms.vouchermanager.contorller.voucher.VoucherController; +import com.prgms.vouchermanager.contorller.voucher.VoucherMenuType; +import com.prgms.vouchermanager.contorller.wallet.WalletController; +import com.prgms.vouchermanager.contorller.wallet.WalletMenuType; import com.prgms.vouchermanager.util.io.ConsoleInput; import com.prgms.vouchermanager.util.io.ConsoleOutput; import com.prgms.vouchermanager.validation.InputValidation; @@ -10,10 +14,6 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; -import static com.prgms.vouchermanager.contorller.customer.CustomerMenuType.BLACK_LIST; -import static com.prgms.vouchermanager.contorller.front.FrontMenuType.*; -import static com.prgms.vouchermanager.contorller.voucher.VoucherMenuType.CREATE; -import static com.prgms.vouchermanager.contorller.voucher.VoucherMenuType.LIST; import static com.prgms.vouchermanager.exception.ExceptionType.*; import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_CUSTOMER_MENU; @@ -24,30 +24,27 @@ public class FrontController { private final static Logger logger = LoggerFactory.getLogger(FrontController.class); private final ConsoleInput consoleInput; - private final ConsoleOutput consoleOutput; - - private final InputValidation inputValidation; - private final VoucherController voucherController; - private final CustomerController customerController; + private final WalletController walletController; + private final InputValidation inputValidation; - public FrontController(ConsoleInput consoleInput, ConsoleOutput consoleOutput, InputValidation inputValidation, VoucherController voucherController, CustomerController customerController) { + public FrontController(ConsoleInput consoleInput, ConsoleOutput consoleOutput, VoucherController voucherController, CustomerController customerController, WalletController walletController, InputValidation inputValidation) { this.consoleInput = consoleInput; this.consoleOutput = consoleOutput; - this.inputValidation = inputValidation; this.voucherController = voucherController; this.customerController = customerController; - + this.walletController = walletController; + this.inputValidation = inputValidation; } public void run() { boolean end = false; - int menu =0; + int menu = 0; while (!end) { @@ -57,46 +54,48 @@ public void run() { if (!inputValidation.validFrontMenu(menu)) { throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); } + switch (FrontMenuType.fromValue(menu)) { + case VOUCHER -> runVoucherController(); + case CUSTOMER -> runCustomerContoller(); + case WALLET -> runWalletController(); + case END -> end = true; + } + } catch (RuntimeException e) { - System.out.println(e.getMessage()); logger.warn(e.getMessage()); continue; } - if (menu == VOUCHER.getNumber()) { - runVoucherController(); - } else if (menu == CUSTOMER.getNumber()) { - runCustomerContoller(); - } else { - end = true; - } - } } + private void runVoucherController() { consoleOutput.printVoucherMenu(); - int menu = 0; + int menu; try { menu = consoleInput.inputVoucherMenu(); if (!inputValidation.validVoucherMenu(menu)) { - logger.warn(INVALID_VOUCHER_MENU.getMessage()); throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); } - } catch (RuntimeException e) { + switch (VoucherMenuType.fromValue(menu)) { + case CREATE -> voucherController.create(); + case UPDATE -> voucherController.update(); + case LIST -> voucherController.getList(); + case ONE -> voucherController.findById(); + case DELETE_ONE -> voucherController.deleteById(); + case DELETE_ALL -> voucherController.deleteAll(); + + } - System.out.println(e.getMessage()); + } catch (RuntimeException e) { logger.warn(e.getMessage()); return; } - if (menu == CREATE.getNumber()) { - voucherController.create(); - } else if (menu == LIST.getNumber()) { - voucherController.getList(); - } + } private void runCustomerContoller() { @@ -107,17 +106,50 @@ private void runCustomerContoller() { menu = consoleInput.inputCustomerMenu(); if (!inputValidation.validCustomerMenu(menu)) { - logger.warn(INVALID_CUSTOMER_MENU.getMessage()); throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); } + switch (CustomerMenuType.fromValue(menu)) { + case CREATE -> customerController.create(); + case UPDATE -> customerController.update(); + case FIND_ALL -> customerController.getList(); + case FIND_ONE -> customerController.findById(); + case DELETE_ONE -> customerController.deleteById(); + case DELETE_ALL -> customerController.deleteAll(); + case BLACK_LIST -> customerController.findBlackList(); + } } catch (RuntimeException e) { - System.out.println(e.getMessage()); logger.warn(e.getMessage()); return; } - if (menu == BLACK_LIST.getNumber()) { - customerController.getBlackList(); + + + } + + private void runWalletController() { + + consoleOutput.printWalletMenu(); + int menu = 0; + try { + menu = consoleInput.inputVoucherMenu(); + + if (!inputValidation.validWalletMenu(menu)) { + throw new RuntimeException(INVALID_WALLET_MENU.getMessage()); + } + + switch (WalletMenuType.fromValue(menu)) { + + case CREATE -> walletController.create(); + case FIND_BY_CUSTOMER_ID -> walletController.findByCustomerId(); + case FIND_BY_VOUCHER_ID -> walletController.findByVoucherId(); + case DELETE_BY_CUSTOMER_ID -> walletController.deleteByCustomerId(); + + } + + } catch (RuntimeException e) { + + logger.warn(e.getMessage()); + return; } } } diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontMenuType.java index 0fb96067d1..ca6ba77508 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontMenuType.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontMenuType.java @@ -1,7 +1,9 @@ package com.prgms.vouchermanager.contorller.front; +import java.util.Arrays; + public enum FrontMenuType { - VOUCHER(1),CUSTOMER(2),END(3); + VOUCHER(1),CUSTOMER(2),WALLET(3),END(4); private final int number; FrontMenuType(int number) { @@ -11,4 +13,12 @@ public enum FrontMenuType { public int getNumber() { return number; } + + public static FrontMenuType fromValue(int menu) { + + return Arrays.stream(FrontMenuType.values()) + .filter(frontMenuType -> frontMenuType.getNumber() == menu) + .findFirst() + .get(); + } } From 5bde0635d60f247281386e03261e944bea8b8e75 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 20:56:25 +0900 Subject: [PATCH 040/109] =?UTF-8?q?refactor:=20CustomerController=EC=9D=98?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=EB=A9=94=EB=89=B4Enum=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerController.java | 99 +++++++++++++++++-- .../contorller/customer/CustomerMenuType.java | 12 ++- 2 files changed, 103 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java index 86febc0197..313474379a 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java @@ -1,26 +1,111 @@ package com.prgms.vouchermanager.contorller.customer; import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.dto.CreateCustomerDto; +import com.prgms.vouchermanager.dto.UpdateCustomerDto; import com.prgms.vouchermanager.service.customer.CustomerService; import com.prgms.vouchermanager.util.io.ConsoleInput; +import com.prgms.vouchermanager.util.io.ConsoleOutput; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import java.util.List; -import static com.prgms.vouchermanager.contorller.customer.CustomerMenuType.*; - @Controller +@Slf4j public class CustomerController { private final CustomerService customerService; + private final ConsoleInput consoleInput; - public CustomerController(CustomerService customerService) { + private final ConsoleOutput consoleOutput; + public CustomerController(CustomerService customerService, ConsoleInput consoleInput, ConsoleOutput consoleOutput) { this.customerService = customerService; + this.consoleInput = consoleInput; + this.consoleOutput = consoleOutput; + } + + public void create() { + Customer customer = null; + try { + + consoleOutput.printCustomerName(); + String name = consoleInput.inputCustomerName(); + consoleOutput.printCustomerEmail(); + String email = consoleInput.inputCustomerEmail(); + consoleOutput.printBlackList(); + int blackList = consoleInput.inputBlackList(); + customer = customerService.create(new CreateCustomerDto(name,email, blackList)); + log.info(customer.toString()); + + } catch (RuntimeException e) { + System.out.println(e.getMessage()); + log.warn(e.getMessage()); + } + + } + + public void update() { + try { + consoleOutput.printCustomerId(); + Long id = consoleInput.inputCustomerId(); + consoleOutput.printCustomerName(); + String name = consoleInput.inputCustomerName(); + consoleOutput.printCustomerEmail(); + String email = consoleInput.inputCustomerEmail(); + consoleOutput.printBlackList(); + int blackList = consoleInput.inputBlackList(); + customerService.update(id,new UpdateCustomerDto(name,email,blackList)); + consoleOutput.printSuccessUpdate(); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + } + + public void getList() { + + List customers = customerService.findAll(); + + customers.forEach(customer -> consoleOutput.printCustomer(customer)); + + } + + public void findById() { + consoleOutput.printCustomerId(); + + try { + Long id = consoleInput.inputCustomerId(); + Customer customer = customerService.findById(id); + log.info(customer.toString()); + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + + } + + public void deleteById() { + consoleOutput.printCustomerId(); + try { + long id = consoleInput.inputCustomerId(); + customerService.deleteById(id); + consoleOutput.printSuccessDelete(); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + + } + + public void deleteAll() { + + customerService.deleteAll(); + consoleOutput.printSuccessDelete(); } - public void getBlackList() { - List blackList = customerService.getBlackList(); + public void findBlackList() { + List blackList = customerService.findBlackList(); - blackList. - forEach(customer -> System.out.println(customer.toString())); + blackList.forEach(customer -> System.out.println(customer.toString())); } } diff --git a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java index d588a36ac9..bd1f45bf20 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java @@ -1,7 +1,9 @@ package com.prgms.vouchermanager.contorller.customer; +import java.util.Arrays; + public enum CustomerMenuType { - BLACK_LIST(1); + CREATE(1), UPDATE(2), FIND_ALL(3), FIND_ONE(4), DELETE_ONE(5), DELETE_ALL(6),BLACK_LIST(7); private final int number; @@ -12,4 +14,12 @@ public enum CustomerMenuType { public int getNumber() { return number; } + + public static CustomerMenuType fromValue(int menu) { + + return Arrays.stream(CustomerMenuType.values()) + .filter(customerMenuType -> customerMenuType.getNumber() == menu) + .findFirst() + .get(); + } } From cc4ec304acdfb1c48fcd439a8c909ad98f917fa7 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 20:56:44 +0900 Subject: [PATCH 041/109] =?UTF-8?q?refactor:=20VoucherController=EC=9D=98?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=EB=A9=94=EB=89=B4Enum=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/voucher/VoucherController.java | 69 ++++++++++++++++--- .../contorller/voucher/VoucherMenuType.java | 11 ++- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java index 56a3910dfd..11b6dcacf8 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java @@ -1,23 +1,22 @@ package com.prgms.vouchermanager.contorller.voucher; -import com.prgms.vouchermanager.contorller.front.FrontController; import com.prgms.vouchermanager.domain.voucher.Voucher; import com.prgms.vouchermanager.dto.CreateVoucherDto; +import com.prgms.vouchermanager.dto.UpdateVoucherDto; import com.prgms.vouchermanager.service.voucher.VoucherService; import com.prgms.vouchermanager.util.io.ConsoleInput; import com.prgms.vouchermanager.util.io.ConsoleOutput; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; + import org.springframework.stereotype.Controller; import java.util.List; +import java.util.UUID; - +@Slf4j @Controller public class VoucherController { - private final static Logger logger = LoggerFactory.getLogger(FrontController.class); - private final VoucherService voucherService; private final ConsoleInput consoleInput; @@ -31,23 +30,71 @@ public VoucherController(VoucherService voucherService, ConsoleInput consoleInpu } public void create() { - try{ + try { consoleOutput.printVoucherType(); int voucherType = consoleInput.inputVoucherType(); consoleOutput.printVoucherAmount(); long value = consoleInput.inputVoucherValue(); - voucherService.create(new CreateVoucherDto(value,voucherType)); + Voucher voucher = voucherService.create(new CreateVoucherDto(value, voucherType)); + log.info(voucher.toString()); } catch (RuntimeException e) { - System.out.println(e.getMessage()); - logger.warn(e.getMessage()); + log.warn(e.getMessage()); + } + + } + + public void update() { + try { + consoleOutput.printVoucherId(); + UUID id = consoleInput.inputVoucherId(); + consoleOutput.printVoucherType(); + int voucherType = consoleInput.inputVoucherType(); + consoleOutput.printVoucherAmount(); + long value = consoleInput.inputVoucherValue(); + voucherService.update(id, new UpdateVoucherDto(value, voucherType)); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); } } public void getList() { - List voucherList = voucherService.getVoucherList(); + + List voucherList = voucherService.findAll(); voucherList.forEach(voucher -> System.out.println(voucher.toString())); } + + public void findById() { + + consoleOutput.printVoucherId(); + + try { + UUID id = consoleInput.inputVoucherId(); + Voucher voucher = voucherService.findById(id); + log.info(voucher.toString()); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + + } + + public void deleteById() { + consoleOutput.printVoucherId(); + try { + UUID id = consoleInput.inputVoucherId(); + voucherService.deleteById(id); + consoleOutput.printSuccessDelete(); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + } + + public void deleteAll() { + voucherService.deleteAll(); + } } diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java index f711bbeff1..e6a769ddf5 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java @@ -1,7 +1,9 @@ package com.prgms.vouchermanager.contorller.voucher; +import java.util.Arrays; + public enum VoucherMenuType { - CREATE(1), LIST(2); + CREATE(1), UPDATE(2), LIST(3), ONE(4), DELETE_ONE(5), DELETE_ALL(6); private final int number; VoucherMenuType(int number) { @@ -12,5 +14,12 @@ public int getNumber() { return number; } + public static VoucherMenuType fromValue(int menu) { + return Arrays.stream(VoucherMenuType.values()) + .filter(voucherMenuType -> voucherMenuType.getNumber() == menu) + .findFirst() + .get(); + } } + From 068363e614ce4a73088980d4314c684c8e8cb2e3 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:02:37 +0900 Subject: [PATCH 042/109] =?UTF-8?q?feat:=20WalletController=EC=97=90=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4Enum=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/wallet/WalletController.java | 88 +++++++++++++++++++ .../contorller/wallet/WalletMenuType.java | 25 ++++++ 2 files changed, 113 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletController.java create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletMenuType.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletController.java b/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletController.java new file mode 100644 index 0000000000..0b971992fc --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletController.java @@ -0,0 +1,88 @@ +package com.prgms.vouchermanager.contorller.wallet; + +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.wallet.Wallet; +import com.prgms.vouchermanager.dto.CreateWalletDto; +import com.prgms.vouchermanager.service.wallet.WalletService; +import com.prgms.vouchermanager.util.io.ConsoleInput; +import com.prgms.vouchermanager.util.io.ConsoleOutput; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; + +import java.util.List; +import java.util.UUID; + +@Slf4j +@Controller +public class WalletController { + + private final WalletService walletService; + private final ConsoleOutput consoleOutput; + private final ConsoleInput consoleInput; + + public WalletController(WalletService walletService, ConsoleOutput consoleOutput, ConsoleInput consoleInput) { + this.walletService = walletService; + this.consoleOutput = consoleOutput; + this.consoleInput = consoleInput; + } + + public void create() { + + try { + consoleOutput.printCustomerId(); + Long customerId = consoleInput.inputCustomerId(); + consoleOutput.printVoucherId(); + UUID voucherId = consoleInput.inputVoucherId(); + Wallet wallet = walletService.save(new CreateWalletDto(customerId, voucherId)); + consoleOutput.printWallet(wallet); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + + } + + public void deleteByCustomerId() { + + try { + consoleOutput.printCustomerId(); + Long customerId = consoleInput.inputCustomerId(); + walletService.deleteByCustomerId(customerId); + consoleOutput.printSuccessDelete(); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + } + + public void findByCustomerId() { + + try { + consoleOutput.printCustomerId(); + Long customerId = consoleInput.inputCustomerId(); + List wallets = walletService.findByCustomerId(customerId); + wallets.forEach(wallet -> consoleOutput.printWallet(wallet)); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + + } + + public void findByVoucherId() { + + try { + + consoleOutput.printVoucherId(); + UUID voucherId = consoleInput.inputVoucherId(); + + Wallet wallet = walletService.findByVoucherId(voucherId); + consoleOutput.printWallet(wallet); + + } catch (RuntimeException e) { + log.warn(e.getMessage()); + } + + } +} diff --git a/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletMenuType.java new file mode 100644 index 0000000000..1ba319d08c --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletMenuType.java @@ -0,0 +1,25 @@ +package com.prgms.vouchermanager.contorller.wallet; + +import java.util.Arrays; + +public enum WalletMenuType { + CREATE(1), FIND_BY_CUSTOMER_ID(2), FIND_BY_VOUCHER_ID(3), DELETE_BY_CUSTOMER_ID(4); + + private final int number; + + WalletMenuType(int number) { + this.number = number; + } + + public int getNumber() { + return number; + } + + public static WalletMenuType fromValue(int menu) { + + return Arrays.stream(WalletMenuType.values()) + .filter(walletMenuType -> walletMenuType.getNumber() == menu) + .findFirst() + .get(); + } +} From fd74e30ed307c5402072c66f948faee1848b0274 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:03:53 +0900 Subject: [PATCH 043/109] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20Customer=EB=82=B4=20=ED=95=84=EC=9A=94=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B0=8F=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/domain/customer/Customer.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java b/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java index 1374839017..c93243c73d 100644 --- a/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java +++ b/src/main/java/com/prgms/vouchermanager/domain/customer/Customer.java @@ -1,18 +1,29 @@ package com.prgms.vouchermanager.domain.customer; +import lombok.Getter; +@Getter public class Customer { - private final Long id; + private Long id; private final String name; private final String email; - public Customer(Long id, String name, String email) { + private final boolean blackList; + + public Customer(Long id, String name, String email, boolean blackList) { + this.id = id; this.name = name; this.email = email; + this.blackList = blackList; + + } + + public void setId(long longValue) { + this.id = longValue; } @Override @@ -21,6 +32,7 @@ public String toString() { "id=" + id + ", name='" + name + '\'' + ", email='" + email + '\'' + + ", blackList=" + blackList + '}'; } } From 79501d0c79e79c72bdaa4ee4b68246086c048365 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:13:17 +0900 Subject: [PATCH 044/109] =?UTF-8?q?feat:=20=EB=8F=84=EB=A9=94=EC=9D=B8=20W?= =?UTF-8?q?allet=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/domain/wallet/Wallet.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/domain/wallet/Wallet.java diff --git a/src/main/java/com/prgms/vouchermanager/domain/wallet/Wallet.java b/src/main/java/com/prgms/vouchermanager/domain/wallet/Wallet.java new file mode 100644 index 0000000000..f5e405c7ef --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/domain/wallet/Wallet.java @@ -0,0 +1,33 @@ +package com.prgms.vouchermanager.domain.wallet; + +import com.prgms.vouchermanager.domain.voucher.Voucher; +import lombok.Getter; + +import java.util.UUID; + +@Getter +public class Wallet { + + private Long id; + private final Long customer_id; + private final UUID voucher_id; + + public Wallet(Long id, Long customer_id, UUID voucher_id) { + this.id = id; + this.customer_id = customer_id; + this.voucher_id = voucher_id; + } + + public void setId(Long id) { + this.id = id; + } + + @Override + public String toString() { + return "Wallet{" + + "id=" + id + + ", customer_id=" + customer_id + + ", voucher_id=" + voucher_id + + '}'; + } +} From 6c56812156b50787a87f92e395a14f42e2615518 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:28:52 +0900 Subject: [PATCH 045/109] =?UTF-8?q?feat:=20Controller=20->=20Service?= =?UTF-8?q?=EB=A1=9C=20=EB=84=98=EA=B2=A8=EC=A3=BC=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20Dto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/dto/CreateCustomerDto.java | 17 ++++++++++++++ .../vouchermanager/dto/CreateWalletDto.java | 17 ++++++++++++++ .../vouchermanager/dto/UpdateCustomerDto.java | 17 ++++++++++++++ .../vouchermanager/dto/UpdateVoucherDto.java | 22 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/dto/CreateCustomerDto.java create mode 100644 src/main/java/com/prgms/vouchermanager/dto/CreateWalletDto.java create mode 100644 src/main/java/com/prgms/vouchermanager/dto/UpdateCustomerDto.java create mode 100644 src/main/java/com/prgms/vouchermanager/dto/UpdateVoucherDto.java diff --git a/src/main/java/com/prgms/vouchermanager/dto/CreateCustomerDto.java b/src/main/java/com/prgms/vouchermanager/dto/CreateCustomerDto.java new file mode 100644 index 0000000000..f06e3c6793 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/dto/CreateCustomerDto.java @@ -0,0 +1,17 @@ +package com.prgms.vouchermanager.dto; + +import lombok.Getter; + +@Getter +public class CreateCustomerDto { + private final String name; + private final String email; + private final int blackList; + + public CreateCustomerDto(String name, String email, int blackList) { + this.name = name; + this.email = email; + + this.blackList = blackList; + } +} diff --git a/src/main/java/com/prgms/vouchermanager/dto/CreateWalletDto.java b/src/main/java/com/prgms/vouchermanager/dto/CreateWalletDto.java new file mode 100644 index 0000000000..af0219f024 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/dto/CreateWalletDto.java @@ -0,0 +1,17 @@ +package com.prgms.vouchermanager.dto; + +import lombok.Getter; + +import java.util.UUID; + +@Getter +public class CreateWalletDto { + private final Long customerId; + private final UUID voucherId; + + public CreateWalletDto(Long customerId, UUID voucherId) { + this.customerId = customerId; + this.voucherId = voucherId; + } + +} diff --git a/src/main/java/com/prgms/vouchermanager/dto/UpdateCustomerDto.java b/src/main/java/com/prgms/vouchermanager/dto/UpdateCustomerDto.java new file mode 100644 index 0000000000..02a3d66464 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/dto/UpdateCustomerDto.java @@ -0,0 +1,17 @@ +package com.prgms.vouchermanager.dto; + +import lombok.Getter; + +@Getter +public class UpdateCustomerDto { + private final String name; + private final String email; + + private final int blackList; + + public UpdateCustomerDto(String name, String email, int blackList) { + this.name = name; + this.email = email; + this.blackList = blackList; + } +} diff --git a/src/main/java/com/prgms/vouchermanager/dto/UpdateVoucherDto.java b/src/main/java/com/prgms/vouchermanager/dto/UpdateVoucherDto.java new file mode 100644 index 0000000000..0929ecf891 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/dto/UpdateVoucherDto.java @@ -0,0 +1,22 @@ +package com.prgms.vouchermanager.dto; + +import lombok.Getter; + +@Getter +public class UpdateVoucherDto { + private final long value; + private final int VoucherType; + + public UpdateVoucherDto(long value, int voucherType) { + this.value = value; + this.VoucherType = voucherType; + } + + public long getValue() { + return value; + } + + public int getVoucherType() { + return VoucherType; + } +} From f605f8f57064009280e82fedbc9e7bd916a1fa55 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:29:21 +0900 Subject: [PATCH 046/109] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20enum?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgms/vouchermanager/exception/ExceptionType.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/exception/ExceptionType.java b/src/main/java/com/prgms/vouchermanager/exception/ExceptionType.java index 16c18b751a..8383d328ea 100644 --- a/src/main/java/com/prgms/vouchermanager/exception/ExceptionType.java +++ b/src/main/java/com/prgms/vouchermanager/exception/ExceptionType.java @@ -12,8 +12,14 @@ public enum ExceptionType { INVALID_READ_FILE("파일을 읽을 수 없습니다."), - INVALID_WRITE_FILE("파일에 저장할 수 없습니다."); - + INVALID_WRITE_FILE("파일에 저장할 수 없습니다."), + + DUPLICATED_KEY("이미 등록된 쿠폰 번호입니다."), + INVALID_VOUCHER_ID("존재하지 않는 쿠폰 ID입니다."), + INVALID_CUSTOMER_INFO("고객정보가 너무 길거나 너무 짧습니다."), + INVALID_CUSTOMER_ID("존재하지 않는 고객 ID입니다."), + INVALID_WALLET_INFO("지갑에 저장할수 없는 정보입니다"), + INVALID_WALLET_MENU("지갑 메뉴를 잘못 입력하셨습니다."); private final String message; ExceptionType(String message) { From 36c18d24f3558fea0523449782200daf0e8453bf Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:30:33 +0900 Subject: [PATCH 047/109] =?UTF-8?q?refactor:=20=EC=9E=85=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/util/io/ConsoleInput.java | 33 ++++++++ .../vouchermanager/util/io/ConsoleOutput.java | 81 ++++++++++++++++++- 2 files changed, 110 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java index 90f5e1476b..e31e6b3aa3 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Component; import java.util.Scanner; +import java.util.UUID; import static com.prgms.vouchermanager.exception.ExceptionType.*; import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_INFO; @@ -76,4 +77,36 @@ public long inputVoucherValue() { throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); } } + + public UUID inputVoucherId() { + try { + return UUID.fromString(scanner.next()); + }catch (RuntimeException e) { + throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); + } + } + + public String inputCustomerName() { + return scanner.next(); + } + + public String inputCustomerEmail() { + return scanner.next(); + } + + public int inputBlackList() { + try { + return scanner.nextInt(); + } catch (RuntimeException e) { + throw new RuntimeException(INVALID_CUSTOMER_INFO.getMessage()); + } + } + + public Long inputCustomerId() { + try { + return scanner.nextLong(); + } catch (RuntimeException e) { + throw new RuntimeException(INVALID_CUSTOMER_INFO.getMessage()); + } + } } diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java index 5ceda3c843..dd9e2f1a0d 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java @@ -1,5 +1,7 @@ package com.prgms.vouchermanager.util.io; +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.domain.wallet.Wallet; import org.springframework.stereotype.Component; @Component @@ -17,7 +19,9 @@ public void printFrontMenu() { 2. Customer - 3. EXIT + 3. Wallet + + 4. EXIT """); } @@ -29,7 +33,15 @@ public void printVoucherMenu() { 1. create - 2. list + 2. update + + 3. list + + 4. find one + + 5. delete one + + 6. delete all """); } @@ -52,13 +64,74 @@ public void printCustomerMenu() { 이용하실 고객 메뉴를 입력해주세요 - 1. black list + 1. CREATE + + 2. UPDATE + + 3. FIND ALL + + 4. FIND ONE + + 5. DELETE ONE + + 6. DELETE ALL + + 7. BLACK LIST """); } - + public void printWalletMenu() { + System.out.println(""" + 이용하실 지갑 메뉴를 입력해주세요 + + 1. CREATE + + 2. FIND BY CUSTOMER ID + + 3. FIND BY VOUCHER ID + + 4. DELETE BY CUSTOMER ID + + """); + } public void printVoucherAmount() { System.out.println("쿠폰의 할인값을 입력해주세요"); } + + public void printVoucherId() { + System.out.println("쿠폰 번호를 입력해주세요."); + } + + public void printSuccessDelete() { + System.out.println("성공적으로 삭제되었습니다."); + } + + public void printCustomerName() { + System.out.println("고객명을 입력해주세요.{"); + } + + public void printCustomerEmail() { + System.out.println("이메일을 입력해주세요."); + } + + public void printBlackList() { + System.out.println("블랙리스트에 등록하시려면 1번, 아니라면 2번을 입력해주세요"); + } + + public void printCustomerId() { + System.out.println("고객 ID를 입력해주세요."); + } + + public void printCustomer(Customer customer) { + System.out.println(customer.toString()); + } + + public void printSuccessUpdate() { + System.out.println("성공적으로 업데이트 되었습니다."); + } + + public void printWallet(Wallet wallet) { + System.out.println(wallet.toString()); + } } From 820b58a39e9daf0e6a6d5524bd6811f7e098ab7f Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:31:18 +0900 Subject: [PATCH 048/109] =?UTF-8?q?refactor:=20=EC=9E=85=EB=A0=A5=EA=B0=92?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EA=B2=80=EC=A6=9D=20=EB=B2=94?= =?UTF-8?q?=EC=9C=84=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/InputValidation.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java b/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java index a4bdd8dfff..0f5446c469 100644 --- a/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java +++ b/src/main/java/com/prgms/vouchermanager/validation/InputValidation.java @@ -7,19 +7,26 @@ public class InputValidation { public boolean validFrontMenu(int menu) { - return menu == 1 || menu == 2||menu==3; + return menu>=1&&menu<=4; } - public boolean validVoucherMenu(int menu) { - return menu == 1 || menu == 2; + return menu>=1 && menu<=6; } public boolean validCustomerMenu(int menu) { - return menu == 1; + return menu>=1 && menu<=7; + } + public boolean validWalletMenu(int menu) { + return menu>=1 && menu<=4; } public boolean validVoucherPercent(long percent) { return percent<=100 ; } + public boolean validCustomerInfo(String name, String email,int blackList) { + return name.length()<=20 + && email.length()<=40 + && blackList>=1 && blackList<=2 ; + } } From a5439440f5341275d1299f33d510779f84878e2b Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:32:29 +0900 Subject: [PATCH 049/109] =?UTF-8?q?refactor:=20FileManager=EB=82=B4=20blac?= =?UTF-8?q?kList=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/prgms/vouchermanager/util/file/FileManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java b/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java index 14e67a6746..38c5b4fb6f 100644 --- a/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java +++ b/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java @@ -80,8 +80,9 @@ public Map readBlackListCsv() { Long id = Long.parseLong(split[0]); String name = split[1]; String email = split[2]; + boolean blackList = split[3].equals("1") ? true : false; - customerMap.put(id, new Customer(id, name, email)); + customerMap.put(id, new Customer(id, name, email,blackList)); } } catch (IOException e) { throw new RuntimeException(INVALID_READ_FILE.getMessage()); From fdafd5d716bf51ed0b4c3496f42883fa7cad6dcc Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:35:18 +0900 Subject: [PATCH 050/109] =?UTF-8?q?refactor:=20yaml=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=97=90=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EC=86=8C=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yaml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 1e0fa59c34..59fb433071 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,8 +1,25 @@ spring: profiles: - active: file + active: jdbc + + datasource: + driverClassName: com.mysql.cj.jdbc.Driver + url : jdbc:mysql://127.0.0.1:3306/voucher?useSSL=false&useUnicode=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul + username : yong + password : 1234 + + sql: + init: + mode: always + + + file: path: voucher: src/main/resources/voucher_list.csv blacklist: src/main/resources/customer_blackList.csv + + + + From d4589a3c3288ad618560662674097498a13420d7 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:36:00 +0900 Subject: [PATCH 051/109] =?UTF-8?q?feat:=20SQL=EC=BF=BC=EB=A6=AC=EB=A1=9C?= =?UTF-8?q?=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=83=9D=EC=84=B1=20=EB=B0=8F?= =?UTF-8?q?=20=EB=A0=88=EC=BD=94=EB=93=9C=20=EC=B4=88=EA=B8=B0=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/data.sql | 10 ++++++++++ src/main/resources/schema.sql | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/main/resources/data.sql create mode 100644 src/main/resources/schema.sql diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000000..7a9e449b02 --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,10 @@ +insert into vouchers values ('bc2e6a9d-1319-4db0-83ba-e07a85fffab8',22,'PERCENT_DISCOUNT'); +insert into vouchers values ('50976229-81af-4dd2-a36d-0f15a58d6f33',10000,'FIXED_AMOUNT'); + + +insert into customers values (1,'kim','won05121@naver.com',0); +insert into customers values (2,'park','park@naver.com',1); +insert into customers values (3,'lee','lee@naver.com',0); + +insert into wallets values (1,2,'bc2e6a9d-1319-4db0-83ba-e07a85fffab8'); +insert into wallets values (2,3,'50976229-81af-4dd2-a36d-0f15a58d6f33'); diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000000..1f7ea0da32 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,27 @@ +DROP TABLE IF EXISTS wallets; +DROP TABLE IF EXISTS vouchers; +DROP TABLE IF EXISTS customers; + +CREATE TABLE vouchers( + id varchar(36) primary key , + discount_value INT, + type varchar(20) +); + + +CREATE TABLE customers( + id BIGINT primary key , + name varchar(10), + email varchar(40), + black_list bool +); + + +CREATE TABLE wallets( + id BIGINT primary key , + customer_id BIGINT, + voucher_id VARCHAR(36), + foreign key (customer_id) REFERENCES customers(id) on delete cascade on update cascade, + foreign key (voucher_id) REFERENCES vouchers(id) on delete cascade on update cascade +); + From 39387bb6fc46651f94c68576fd989e24039a32dd Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:36:53 +0900 Subject: [PATCH 052/109] =?UTF-8?q?refactor:=20csv=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/customer_blackList.csv | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/resources/customer_blackList.csv b/src/main/resources/customer_blackList.csv index 8b553c5cd4..d170b9a86e 100644 --- a/src/main/resources/customer_blackList.csv +++ b/src/main/resources/customer_blackList.csv @@ -1,6 +1,6 @@ -id, name, email -1, kim, kim@naver.com -2, lee, lee@naver.com -3, park, park@naver.com -4, hong, hong@naver.com -5, kang, kang@naver.com +id, name, email , blackList +1, kim, kim@naver.com, 1 +2, lee, lee@naver.com, 1 +3, park, park@naver.com, 2 +4, hong, hong@naver.com, 2 +5, kang, kang@naver.com, 2 From bc15d2b48fc048031cd219d3df13ad30b0291246 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:39:50 +0900 Subject: [PATCH 053/109] =?UTF-8?q?test:=20customerService=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20test=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/customer/CustomerServiceTest.java | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 src/test/java/com/prgms/vouchermanager/service/customer/CustomerServiceTest.java diff --git a/src/test/java/com/prgms/vouchermanager/service/customer/CustomerServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/customer/CustomerServiceTest.java new file mode 100644 index 0000000000..41fc956586 --- /dev/null +++ b/src/test/java/com/prgms/vouchermanager/service/customer/CustomerServiceTest.java @@ -0,0 +1,156 @@ +package com.prgms.vouchermanager.service.customer; + +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.dto.CreateCustomerDto; +import com.prgms.vouchermanager.dto.UpdateCustomerDto; +import com.prgms.vouchermanager.repository.customer.CustomerRepository; +import com.prgms.vouchermanager.validation.InputValidation; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.dao.EmptyResultDataAccessException; + +import java.util.NoSuchElementException; +import java.util.Optional; + +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class CustomerServiceTest { + + @Mock + private CustomerRepository customerRepsotiory; + + @Mock + private InputValidation inputValidation; + + @InjectMocks + CustomerService customerService; + + + @Test + @DisplayName("service의 create()를 통해 repository의 save()를 정상 실행하고, 값을 받아올수 있다.") + void createCusteomerSuccess() { + + //given + CreateCustomerDto dto = new CreateCustomerDto("kim", "won05121@naver.com", 1); + Customer result = new Customer(null, dto.getName(), dto.getEmail(), true); + + when(customerRepsotiory.save(any(Customer.class))).thenReturn(result); + when(inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())).thenReturn(true); + + //when + Customer customer = customerService.create(dto); + + //then + Assertions.assertThat(customer).isEqualTo(result); + verify(customerRepsotiory,atLeastOnce()).save(any(Customer.class)); + + } + + @Test + @DisplayName("service의 create()를 통해 repository의 save()를 실행에 실패한다.") + void createCusteomerFail() { + //given + CreateCustomerDto dto = new CreateCustomerDto("kim", "won05121@naver.com", 1); + when(inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())) + .thenReturn(false); + + //when + //then + Assertions.assertThatThrownBy(() -> customerService.create(dto)). + isInstanceOf(RuntimeException.class); + } + + @Test + @DisplayName("service의 update()를 통해 repository의 update()가 정상적으로 실행된다.") + void updateCustomerSuccess() { + //given + UpdateCustomerDto dto = new UpdateCustomerDto("kim", "won05121@naver.com", 1); + Customer result = new Customer(null, dto.getName(), dto.getEmail(), true); + when(inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())).thenReturn(true); + + //when + customerService.update(1L, dto); + + //then + verify(customerRepsotiory, atLeast(1)).update(any(Customer.class)); + } + + @Test + @DisplayName("service의 update()를 통해 repository의 update()의 실행에 실패한다.") + void updateCustomerFail() { + //given + UpdateCustomerDto dto = new UpdateCustomerDto("kim", "won05121@naver.com", 1); + when(inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())).thenReturn(false); + + //when + customerService.update(1L,dto); + + //then + verify(customerRepsotiory, never()).update(any(Customer.class)); + + } + + @Test + @DisplayName("service의 findById()의 인자값에 상관없이 ,repository의 findById()는 반드시 한번은 실행된다.") + void findByIdCustomerSuccess() { + //given + when(customerRepsotiory.findById(any())) + .thenReturn(Optional.ofNullable(null)); + + Assertions.assertThatThrownBy(() -> customerService.findById(1L)).isInstanceOf(EmptyResultDataAccessException.class); + verify(customerRepsotiory, atLeastOnce()).findById(any()); + + } + + @Test + @DisplayName("service의 findAll()을 통해 repository 의 findAll() 을 실행에 반드시 성공한다.") + void findAll() { + //given + //when + customerService.findAll(); + + //then + verify(customerRepsotiory, atLeastOnce()).findAll(); + + } + + @Test + @DisplayName("service의 deleteById()의 인자와 상관없이, repository의 deleteById()는 반드시 한번은 실행된다.") + void deleteByIdSuccess() { + //given + //when + customerService.deleteById(null); + + //then + verify(customerRepsotiory, atLeastOnce()).deleteById(any()); + } + + @Test + @DisplayName("service의 deleteAll()을 통해 repository 의 deleteAll() 을 반드시 한번은 실행한다.") + void deleteAll() { + //given + //when + customerService.deleteAll(); + + //then + verify(customerRepsotiory, atLeastOnce()).deleteAll(); + } + + @Test + @DisplayName("service의 getBlackList()를 통해 repository의 getBlackList()을 반드시 한번은 실행한다.") + void getBlackList() { + //given + //when + customerService.findBlackList(); + + //then + verify(customerRepsotiory, atLeastOnce()).findBlackList(); + + } +} From 44739fe085ffb55ab9db03419342ba41d61da925 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:42:09 +0900 Subject: [PATCH 054/109] =?UTF-8?q?test:=20VoucherService=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20test=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/voucher/VoucherServiceTest.java | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java diff --git a/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java new file mode 100644 index 0000000000..7fe115dbcf --- /dev/null +++ b/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java @@ -0,0 +1,171 @@ +package com.prgms.vouchermanager.service.voucher; + +import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; +import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.dto.CreateVoucherDto; +import com.prgms.vouchermanager.dto.UpdateVoucherDto; +import com.prgms.vouchermanager.repository.voucher.VoucherRepository; +import com.prgms.vouchermanager.validation.InputValidation; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.dao.EmptyResultDataAccessException; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.UUID; + +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class VoucherServiceTest { + + @Mock + private VoucherRepository voucherRepository; + + @Mock + private InputValidation inputValidation; + + @InjectMocks + VoucherService voucherService; + + + @Test + @DisplayName("service의 create()를 통해 repository의 save()를 정상 실행하고 값을 받아올 수 있다.") + void createVoucherSuccess() { + + //given + CreateVoucherDto dto = new CreateVoucherDto(99, 2); + UUID id = UUID.randomUUID(); + Voucher result = dto.getVoucherType()==1? + new FixedAmountVoucher(id, dto.getValue()): + new PercentDiscountVoucher(id,dto.getValue()); + + when(voucherRepository.save(any(Voucher.class))).thenReturn(result); + when(inputValidation.validVoucherPercent(dto.getValue())).thenReturn(true); + //when + Voucher voucher = voucherService.create(dto); + + //then + Assertions.assertThat(voucher).isEqualTo(result); + verify(voucherRepository,atLeastOnce()).save(any(Voucher.class)); + + } + @Test + @DisplayName("service의 create()에서 repository의 save()를 실행에 실패한다.") + void createVoucherFail() { + //given + CreateVoucherDto dto = new CreateVoucherDto(101, 2); + when(inputValidation.validVoucherPercent(dto.getValue())).thenReturn(false); + //when + //then + Assertions.assertThatThrownBy(() -> voucherService.create(dto)). + isInstanceOf(RuntimeException.class); + } + + @Test + @DisplayName("service의 update()에서 repository의 update()가 정상적으로 실행된다.") + void updateUpdateSuccess() { + //given + UpdateVoucherDto dto = new UpdateVoucherDto(10, 2); + + when(inputValidation.validVoucherPercent(dto.getValue())).thenReturn(true); + + UUID id = UUID.randomUUID(); + //when + voucherService.update(id,dto); + + //then + verify(voucherRepository, atLeastOnce()).update(any(Voucher.class)); + } + + @Test + @DisplayName("service의 update()를 통해 repository의 save()를 실행에 실패한다.") + void updateVoucherFail() { + //given + UpdateVoucherDto dto = new UpdateVoucherDto(10000, 2); + + when(inputValidation.validVoucherPercent(dto.getValue())).thenReturn(false); + + UUID id = UUID.randomUUID(); + //when + //then + Assertions.assertThatThrownBy(() -> voucherService.update((id),dto)). + isInstanceOf(RuntimeException.class); + } + + + @Test + @DisplayName("service의 findById()에 존재하는ID라면 ,repository의 findById()를 통해 정상 반환된다.") + void findByIdVoucherSuccess() { + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 1000); + when(voucherRepository.findById(id)).thenReturn(Optional.ofNullable(voucher)); + + //when + Voucher result = voucherService.findById(id); + + //then + verify(voucherRepository, atLeastOnce()).findById(id); + Assertions.assertThat(id).isEqualTo(result.getId()); + + } + + @Test + @DisplayName("service의 findById()에 존재하지 않는 ID를 넘겨주면 ,repository의 findById()가 반드시 한번은 실행되고 예외가 발생한다.") + void findByIdVoucherFail() { + //given + UUID id = UUID.randomUUID(); + when(voucherRepository.findById(id)).thenReturn(Optional.ofNullable(null)); + + Assertions.assertThatThrownBy(() -> voucherService.findById(id)).isInstanceOf(EmptyResultDataAccessException.class); + verify(voucherRepository, atLeastOnce()).findById(any()); + + } + + @Test + @DisplayName("service의 findAll()을 통해 repository 의 findAll() 실행을 성공한다.") + void findAllSuccess() { + //given + List vouchers = List.of(new FixedAmountVoucher(UUID.randomUUID(), 100),new PercentDiscountVoucher(UUID.randomUUID(),22)); + when(voucherRepository.findAll()).thenReturn(vouchers); + + //when + List findAllVouchers = voucherService.findAll(); + + //then + Assertions.assertThat(findAllVouchers).isEqualTo(vouchers); + verify(voucherRepository, atLeastOnce()).findAll(); + + } + + @Test + @DisplayName("service의 deleteById()의 인자와 상관없이, repository의 deleteById()는 반드시 한번은 실행된다.") + void deleteByIdSuccess() { + + //given + //when + voucherService.deleteById(null); + + //then + verify(voucherRepository, atLeastOnce()).deleteById(any()); + } + + @Test + @DisplayName("service의 deleteAll()으로 repository 의 deleteAll() 을 반드시 한번은 실행한다.") + void deleteAll() { + //given + //when + voucherService.deleteAll(); + + //then + verify(voucherRepository, atLeastOnce()).deleteAll(); + } +} From 7e76418077d24bc2c7e70e34a047a1daf85ee44b Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:42:16 +0900 Subject: [PATCH 055/109] =?UTF-8?q?test:=20WalletService=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20test=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/wallet/WalletServiceTest.java | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java diff --git a/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java new file mode 100644 index 0000000000..e8a2ae2596 --- /dev/null +++ b/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java @@ -0,0 +1,108 @@ +package com.prgms.vouchermanager.service.wallet; + +import com.prgms.vouchermanager.domain.wallet.Wallet; +import com.prgms.vouchermanager.dto.CreateWalletDto; +import com.prgms.vouchermanager.repository.wallet.WalletRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.dao.DataIntegrityViolationException; + +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.UUID; + +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class WalletServiceTest { + + @Mock + private WalletRepository walletRepository; + + @InjectMocks + WalletService walletService; + + + @Test + @DisplayName("service의 create()를 통해 repository의 save()를 정상 실행하고, 값을 받아올 수 있다.") + void createWalletSuccess() { + + //given + UUID voucherId = UUID.randomUUID(); + CreateWalletDto dto = new CreateWalletDto(1L, voucherId); + when(walletRepository.save(any(Wallet.class))).thenReturn(new Wallet(1L,1L,voucherId)); + + //when + Wallet wallet = walletService.save(dto); + + //then + Assertions.assertThat(voucherId).isEqualTo(wallet.getVoucher_id()); + verify(walletRepository,atLeastOnce()).save(any(Wallet.class)); + + } + + @Test + @DisplayName("service의 create()를 통해 존재하지 않는 회원값,UUID쿠폰값을 입력하면 예외를 터트린다. ") + void createWalletFail() { + //given + CreateWalletDto dto = new CreateWalletDto(1L, UUID.randomUUID()); + when(walletRepository.save(any())).thenThrow(DataIntegrityViolationException.class); + + //when + //then + Assertions.assertThatThrownBy(() -> walletService.save(dto)).isInstanceOf(DataIntegrityViolationException.class); + verify(walletRepository, atLeastOnce()).save(any(Wallet.class)); + + } + + @Test + @DisplayName("service의 findByCustomerId()를 통해 repository의 findByCustomerId()가 정상적으로 실행된다.") + void walletfindByCustomerId() { + //given + Long customerId = 1L; + when(walletRepository.findByCustomerId(1L)).thenReturn(any()); + + //when + walletService.findByCustomerId(customerId); + + //then + verify(walletRepository, atLeastOnce()).findByCustomerId(customerId); + } + + @Test + @DisplayName("service의 findByVoucherId()를 통해 repository의 findByVoucherId()가 정상적으로 실행된다.") + void walletFindByVoucherIdSuccess() { + + //given + UUID voucherId = UUID.randomUUID(); + Wallet wallet = new Wallet(1L, 2L, voucherId); + when(walletRepository.findByVoucherId(voucherId)).thenReturn(Optional.of(wallet)); + + //when + walletService.findByVoucherId(voucherId); + + //then + verify(walletRepository, atLeastOnce()).findByVoucherId(voucherId); + + } + + @Test + @DisplayName("service의 deleteByCustomerId()를 통해 repository의 deleteByCustomerId()를 정상적으로 실행한다") + void deleteByCustomerId() { + + //given + Long customerId = 1L; + //when + walletService.deleteByCustomerId(customerId); + + //then + verify(walletRepository, atLeastOnce()).deleteByCustomerId(customerId); + + } + +} From f29b7e802d85b733318f3343a39d9f7fa5cf61a0 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:42:30 +0900 Subject: [PATCH 056/109] =?UTF-8?q?test:=20CustomerRepository=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20test=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerRepositoryTest.java | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/test/java/com/prgms/vouchermanager/repository/customer/CustomerRepositoryTest.java diff --git a/src/test/java/com/prgms/vouchermanager/repository/customer/CustomerRepositoryTest.java b/src/test/java/com/prgms/vouchermanager/repository/customer/CustomerRepositoryTest.java new file mode 100644 index 0000000000..c625e3a19a --- /dev/null +++ b/src/test/java/com/prgms/vouchermanager/repository/customer/CustomerRepositoryTest.java @@ -0,0 +1,138 @@ +package com.prgms.vouchermanager.repository.customer; + +import com.prgms.vouchermanager.domain.customer.Customer; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; + +@SpringBootTest +@Transactional +public class CustomerRepositoryTest { + + @Autowired + private CustomerRepository customerRepository; + + @Test + @DisplayName("save()를 통해 id는 자동 증가하면서, 쿼리가 정상적으로 동작한다. ") + void saveCustomrSuccess() { + + //given + Customer customer1 = new Customer(null, "heo", "heo@naver.com", true); + Customer customer2 = new Customer(null, "koo", "koo@naver.com", false); + Customer customer3 = new Customer(100L, "koo", "koo@naver.com", false); + + //when + customerRepository.save(customer1); + customerRepository.save(customer2); + customerRepository.save(customer3); + + //then + Assertions.assertThat(customer1.getId() + 1).isEqualTo(customer2.getId()); + Assertions.assertThat(customer2.getId() + 1).isEqualTo(customer3.getId()); + } + + @Test + @DisplayName("update()를 이용해 정보수정을 자유롭게 할수 있다.") + void updateCustomerSuccess() { + + //given + Customer customer1 = new Customer(null, "heo", "heo@naver.com", false); + String newEmail = "new@naver.com"; + + //when + Customer savedCustomer = customerRepository.save(customer1); + Customer updateCustomer = new Customer(savedCustomer.getId(), savedCustomer.getName(), newEmail, savedCustomer.isBlackList()); + customerRepository.update(updateCustomer); + Optional findCustomer = customerRepository.findById(savedCustomer.getId()); + + //then + Assertions.assertThat(updateCustomer.getName()).isEqualTo(findCustomer.get().getName()); + Assertions.assertThat(updateCustomer.getEmail()).isEqualTo(findCustomer.get().getEmail()); + Assertions.assertThat(updateCustomer.getId()).isEqualTo(findCustomer.get().getId()); + Assertions.assertThat(updateCustomer.isBlackList()).isEqualTo(findCustomer.get().isBlackList()); + + } + + @Test + @DisplayName("findById() 를 통해 Customer를 찾아올 수 있다.") + void findByIdCustomerSuccess() { + + //given + Customer customer = new Customer(null, "kim", "heo@naver.com", false); + + //when + Customer savedCustomer = customerRepository.save(customer); + Long id = savedCustomer.getId(); + Optional findByIdCustomer = customerRepository.findById(id); + + //then + Assertions.assertThat(customer.getName()).isEqualTo(findByIdCustomer.get().getName()); + Assertions.assertThat(customer.getEmail()).isEqualTo(findByIdCustomer.get().getEmail()); + Assertions.assertThat(customer.getId()).isEqualTo(findByIdCustomer.get().getId()); + Assertions.assertThat(customer.isBlackList()).isEqualTo(findByIdCustomer.get().isBlackList()); + } + + @Test + @DisplayName("findById 를 실행시 없는 ID를 조회하면, 빈 값이 넘어온다.") + void findByIdCustomerFail() { + + //given + Long notExistId = 123456L; + + //when + Optional findById = customerRepository.findById(notExistId); + + //then + Assertions.assertThat(findById).isEmpty(); + + } + + @Test + @DisplayName("findAll()실행시 성공적으로 모든 목록을 조회한다.") + void findAllCustomerSuccess() { + + //given + //when + List all = customerRepository.findAll(); + + //then + Assertions.assertThat(all).isNotNull(); + + } + + @Test + @DisplayName("deleteById()실행 시 customer를 성공적으로 삭제한다.") + void deleteByCustomerSuccess() { + + //given + Long id = 1L; + Customer customer = new Customer(id, "kim", "lee@naver.com", true); + customerRepository.save(customer); + + //when + customerRepository.deleteById(id); + Optional findById = customerRepository.findById(id); + + //then + Assertions.assertThat(findById).isEmpty(); + } + + @Test + @DisplayName("findBlackList()실행시 성공적으로 blackList를 조회한다.") + void findBlackListSuccess() { + + //given + //when + List blackList = customerRepository.findBlackList(); + + //then + Assertions.assertThat(blackList).isNotNull(); + + } +} From d4dbc107a7a3b45684b7f6ad3314af6345c7ff1c Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:42:36 +0900 Subject: [PATCH 057/109] =?UTF-8?q?test:=20VoucherRepository=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20test=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/VoucherRepositoryTest.java | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/test/java/com/prgms/vouchermanager/repository/voucher/VoucherRepositoryTest.java diff --git a/src/test/java/com/prgms/vouchermanager/repository/voucher/VoucherRepositoryTest.java b/src/test/java/com/prgms/vouchermanager/repository/voucher/VoucherRepositoryTest.java new file mode 100644 index 0000000000..ddcf68c41c --- /dev/null +++ b/src/test/java/com/prgms/vouchermanager/repository/voucher/VoucherRepositoryTest.java @@ -0,0 +1,140 @@ +package com.prgms.vouchermanager.repository.voucher; + +import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; +import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@SpringBootTest +@Transactional +public class VoucherRepositoryTest { + + @Autowired + private VoucherRepository voucherRepository; + + @Test + @DisplayName("save()실행시 정상적으로 저장된다. ") + void saveVoucherSuccess() { + + //given + + Voucher voucher = new FixedAmountVoucher(UUID.randomUUID(), 100000); + + //when + Voucher savedVoucher = voucherRepository.save(voucher); + + //then + Assertions.assertThat(voucher).isEqualTo(savedVoucher); + } + + @Test + @DisplayName("save()실행시 ID가 중복될 경우 예외가 발생한다.") + void saveVoucherFail() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher1 = new FixedAmountVoucher(id, 100000); + Voucher voucher2 = new PercentDiscountVoucher(id, 10); + + //when + voucherRepository.save(voucher1); + + //then + Assertions.assertThatThrownBy(() -> voucherRepository.save(voucher2)).isInstanceOf(DuplicateKeyException.class); + + } + + @Test + @DisplayName("update()를 이용해 정보수정을 자유롭게 할수 있다.") + void updateVoucherSuccess() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher savedVoucher = voucherRepository.save(voucher); + Voucher updatedVoucher = new FixedAmountVoucher(savedVoucher.getId(), 9999); + + //when + voucherRepository.update(updatedVoucher); + + Optional findVoucher = voucherRepository.findById(updatedVoucher.getId()); + + //then + Assertions.assertThat(updatedVoucher.getId()).isEqualTo(findVoucher.get().getId()); + Assertions.assertThat(updatedVoucher.getVoucherType()).isEqualTo(findVoucher.get().getVoucherType()); + Assertions.assertThat(updatedVoucher.getDiscountValue()).isEqualTo(findVoucher.get().getDiscountValue()); + + } + + @Test + @DisplayName("findById() 를 통해 Voucher를 찾아올 수 있다.") + void findByIdVoucherSuccess() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + + Voucher savedCustomer = voucherRepository.save(voucher); + + Optional findByIdVoucher = voucherRepository.findById(savedCustomer.getId()); + + //then + Assertions.assertThat(voucher.getId()).isEqualTo(findByIdVoucher.get().getId()); + Assertions.assertThat(voucher.getDiscountValue()).isEqualTo(findByIdVoucher.get().getDiscountValue()); + Assertions.assertThat(voucher.getVoucherType()).isEqualTo(findByIdVoucher.get().getVoucherType()); + } + + @Test + @DisplayName("findById 를 실행시 없는 ID를 조회하면, 빈 값이 넘어온다.") + void findByIdVoucherFail() { + + //given + UUID notExistId = UUID.randomUUID(); + + //when + Optional findById = voucherRepository.findById(notExistId); + + //then + Assertions.assertThat(findById).isEmpty(); + + } + + @Test + @DisplayName("findAll()실행시 성공적으로 모든 목록을 조회한다.") + void findAllVoucherSuccess() { + + //given + //when + List all = voucherRepository.findAll(); + + //then + Assertions.assertThat(all).isNotNull(); + + } + + @Test + @DisplayName("deleteById()실행 시 customer를 성공적으로 삭제한다.") + void deleteByVoucherSuccess() { + + //given + UUID id = UUID.randomUUID(); + voucherRepository.save(new FixedAmountVoucher(id, 1000)); + //when + voucherRepository.deleteById(id); + Optional findById = voucherRepository.findById(id); + + //then + Assertions.assertThat(findById).isEmpty(); + } + +} From 28a6d757a9805642d155476cb15ccb82141d0a64 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:42:44 +0900 Subject: [PATCH 058/109] =?UTF-8?q?test:=20WalletRepository=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20test=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wallet/WalletRepositoryTest.java | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java diff --git a/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java b/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java new file mode 100644 index 0000000000..f53aeccf95 --- /dev/null +++ b/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java @@ -0,0 +1,172 @@ +package com.prgms.vouchermanager.repository.wallet; + +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.wallet.Wallet; +import com.prgms.vouchermanager.repository.customer.CustomerRepository; +import com.prgms.vouchermanager.repository.voucher.VoucherRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@SpringBootTest +public class WalletRepositoryTest { + + @Autowired + private WalletRepository walletRepository; + @Autowired + private VoucherRepository voucherRepository; + @Autowired + private CustomerRepository customerRepository; + + @Test + @DisplayName("save()실행시 wallets이 참조하는 customer_id와 voucher_id가 존재한다면, 정상적으로 저장된다. ") + void saveWalletSuccess() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + Customer customer = new Customer(1L, "ko", "kp@naver.com", true); + voucherRepository.save(voucher); + customerRepository.save(customer); + + Wallet wallet = new Wallet(6L, 1L, id); + + //when + Wallet savedWallet = walletRepository.save(wallet); + + //then + Assertions.assertThat(wallet).isEqualTo(savedWallet); + } + + + @Test + @DisplayName("save()실행시 wallets이 참조하는 customer_id와 voucher_id가 존재하지 않는다면, 예외가 발생한다. ") + void saveWalletFail() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + Customer customer = new Customer(1L, "ko", "kp@naver.com", true); + Wallet wallet = new Wallet(10L, 1214L, UUID.randomUUID()); //존재하지 않는 참조데이터 + + //when + voucherRepository.save(voucher); + customerRepository.save(customer); + + //then + Assertions.assertThatThrownBy(() -> walletRepository.save(wallet)).isInstanceOf(DataIntegrityViolationException.class); + } + + + @Test + @DisplayName("customer_id에 해당하는 쿠폰 조회에 성공한다.") + void findByCustomerIdSuccess() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + Customer customer = new Customer(10L, "ko", "kp@naver.com", true); + voucherRepository.save(voucher); + customerRepository.save(customer); + Wallet wallet = new Wallet(6L, customer.getId(), id); + + //when + walletRepository.save(wallet); + List wallets = walletRepository.findByCustomerId(customer.getId()); + + //then + Assertions.assertThat(wallets).isNotNull(); + } + @Test + @DisplayName("customer_id에 해당하는 쿠폰 조회에 실패한다.") + void findByCustomerIdFail() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + Customer customer = new Customer(10L, "ko", "kp@naver.com", true); + voucherRepository.save(voucher); + customerRepository.save(customer); + Wallet wallet = new Wallet(6L, customer.getId(), id); + + //when + walletRepository.save(wallet); + List wallets = walletRepository.findByCustomerId(123132L); + + //then + Assertions.assertThat(wallets).isEmpty(); + } + + @Test + @DisplayName("voucher_id에 해당하는 고객 조회에 성공한다.") + void findByVoucherIdSuccess() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + Customer customer = new Customer(10L, "ko", "kp@naver.com", true); + voucherRepository.save(voucher); + customerRepository.save(customer); + Wallet wallet = new Wallet(6L, customer.getId(), id); + + //when + walletRepository.save(wallet); + Optional findByVoucherIdwallet = walletRepository.findByVoucherId(id); + + //then + Assertions.assertThat(findByVoucherIdwallet.get().getId()).isEqualTo(wallet.getId()); + Assertions.assertThat(findByVoucherIdwallet.get().getVoucher_id()).isEqualTo(wallet.getVoucher_id()); + Assertions.assertThat(findByVoucherIdwallet.get().getCustomer_id()).isEqualTo(wallet.getCustomer_id()); + } + + @Test + @DisplayName("voucher_id에 해당하는 고객 조회에 실패한다.") + void findByVoucherIdFail() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + Customer customer = new Customer(10L, "ko", "kp@naver.com", true); + voucherRepository.save(voucher); + customerRepository.save(customer); + Wallet wallet = new Wallet(6L, customer.getId(), id); + + //when + walletRepository.save(wallet); + Optional findByVoucherIdwallet = walletRepository.findByVoucherId(UUID.randomUUID()); + + //then + Assertions.assertThat(findByVoucherIdwallet).isEmpty(); + } + + @Test + @DisplayName("deleteByCustomerId()실행 시 지갑 정보를 성공적으로 삭제한다..") + void deleteByCustomerIdSuccess() { + + //given + UUID id = UUID.randomUUID(); + Voucher voucher = new FixedAmountVoucher(id, 100000); + Customer customer = new Customer(10L, "ko", "kp@naver.com", true); + voucherRepository.save(voucher); + customerRepository.save(customer); + Wallet wallet = new Wallet(6L, customer.getId(), id); + walletRepository.save(wallet); + + //when + walletRepository.deleteByCustomerId(customer.getId()); + + //then + List wallets = walletRepository.findByCustomerId(customer.getId()); + Assertions.assertThat(wallets).isEmpty(); + } + +} From dbd3ca2332f3884d99d6d524bf5117b8bb5c9ae8 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:44:29 +0900 Subject: [PATCH 059/109] =?UTF-8?q?feat:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=8B=9C=20=ED=95=84=EC=9A=94=ED=95=9C=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/resources/application.yaml diff --git a/src/test/resources/application.yaml b/src/test/resources/application.yaml new file mode 100644 index 0000000000..02fd30410a --- /dev/null +++ b/src/test/resources/application.yaml @@ -0,0 +1,15 @@ +spring: + profiles: + active: jdbc + + datasource: + driverClassName: com.mysql.cj.jdbc.Driver + url : jdbc:mysql://127.0.0.1:3306/voucher?useSSL=false&useUnicode=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul + username : yong + password : 1234 + + sql: + init: + mode: always + + From a640858b9135c123aa8f869ea9c455fe912e8e81 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:45:40 +0900 Subject: [PATCH 060/109] =?UTF-8?q?chore:=20gradle=20=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build.gradle b/build.gradle index 0a2e20d77c..d45d73dc45 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,16 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + implementation 'org.projectlombok:lombok:1.18.22' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.mockito:mockito-core:4.8.0' + + annotationProcessor 'org.projectlombok:lombok' + + implementation 'com.mysql:mysql-connector-j:8.1.0' + + } tasks.named('test') { From e37311d3dfdc1cc9b3dc1355d4bec0a3334d4862 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:47:09 +0900 Subject: [PATCH 061/109] =?UTF-8?q?refactor:=20CustomerRepository=20?= =?UTF-8?q?=EC=97=90=20=ED=95=84=EC=9A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerRepository.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java index 2065030fd5..66f293eab6 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerRepository.java @@ -1,25 +1,24 @@ package com.prgms.vouchermanager.repository.customer; import com.prgms.vouchermanager.domain.customer.Customer; -import com.prgms.vouchermanager.util.file.FileManager; -import org.springframework.stereotype.Repository; import java.util.List; -import java.util.Map; +import java.util.Optional; -@Repository -public class CustomerRepository { - private Map blackList; +public interface CustomerRepository { + Customer save(Customer customer); - public CustomerRepository(FileManager fileManager) { + void update(Customer customer); - blackList = fileManager.readBlackListCsv(); - } - public List getBlackList() { + Optional findById(Long id); - return blackList.values() - .stream().toList(); - } + List findAll(); + + void deleteById(Long id); + + void deleteAll(); + + List findBlackList(); } From 8ffee0a0069d46ffca0226386531c78b700e6e1e Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:47:34 +0900 Subject: [PATCH 062/109] =?UTF-8?q?refactor:=20VoucherRepository=20?= =?UTF-8?q?=EC=97=90=20=ED=95=84=EC=9A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/voucher/VoucherRepository.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java index f1a97e15ea..b8656f1d3b 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java @@ -3,10 +3,19 @@ import com.prgms.vouchermanager.domain.voucher.Voucher; import java.util.List; +import java.util.Optional; +import java.util.UUID; public interface VoucherRepository { - void create(Voucher voucher); + Voucher save(Voucher voucher); + void update(Voucher voucher); - List getAllVouchers(); + Optional findById(UUID id); + + List findAll(); + + void deleteById(UUID id); + + void deleteAll(); } From 88e67a5124e99fdc4a15387ceeac43fda5585ed8 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:48:14 +0900 Subject: [PATCH 063/109] =?UTF-8?q?feat:=20CustomerFileRepository=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerFileRepository.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/customer/CustomerFileRepository.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerFileRepository.java b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerFileRepository.java new file mode 100644 index 0000000000..c83f4e0935 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerFileRepository.java @@ -0,0 +1,25 @@ +package com.prgms.vouchermanager.repository.customer; + +import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.util.file.FileManager; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +@Repository +@Profile("file") +public class CustomerFileRepository { + private Map blackList; + + public CustomerFileRepository(FileManager fileManager) { + + blackList = fileManager.readBlackListCsv(); + } + public List getBlackList() { + + return blackList.values() + .stream().toList(); + } +} From b3152dac09b667f172585633179f50acd3f287a0 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:48:40 +0900 Subject: [PATCH 064/109] =?UTF-8?q?feat:=20JdbcCustomerRepository=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/JdbcCustomerRepository.java | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java b/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java new file mode 100644 index 0000000000..929d166c88 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java @@ -0,0 +1,115 @@ +package com.prgms.vouchermanager.repository.customer; + +import com.prgms.vouchermanager.domain.customer.Customer; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Optional; + +import static com.prgms.vouchermanager.repository.customer.CustomerQueryType.*; + + +@Repository +@Slf4j +@Profile("jdbc") +public class JdbcCustomerRepository implements CustomerRepository { + private final NamedParameterJdbcTemplate template; + + public JdbcCustomerRepository(DataSource dataSource) { + template = new NamedParameterJdbcTemplate(dataSource); + } + + public Customer save(Customer customer) { + + SqlParameterSource forSequenceParam = new MapSqlParameterSource(); + Long sequence = template.queryForObject(COUNT.getQuery(), forSequenceParam, Long.class); + customer.setId(sequence+1); + + SqlParameterSource param = new MapSqlParameterSource() + .addValue("id", customer.getId()) + .addValue("name", customer.getName()) + .addValue("email", customer.getEmail()) + .addValue("black_list", customer.isBlackList()); + + + template.update(INSERT.getQuery(), param); + + return customer; + + } + + @Override + public void update(Customer customer) { + + SqlParameterSource param = new MapSqlParameterSource() + .addValue("id", customer.getId()) + .addValue("name", customer.getName()) + .addValue("email", customer.getEmail()) + .addValue("black_list", customer.isBlackList()); + + template.update(UPDATE.getQuery(), param); + } + + @Override + public Optional findById(Long id) { + + SqlParameterSource param = new MapSqlParameterSource() + .addValue("id", id); + + try { + return Optional.of(template.queryForObject(SELECT_BY_ID.getQuery(), param, customerRowMapper())); + } catch (EmptyResultDataAccessException e) { + return Optional.empty(); + } + + } + + @Override + public List findAll() { + + return template.query(SELECT_ALL.getQuery(), customerRowMapper()); + } + + @Override + public void deleteById(Long id) { + + + SqlParameterSource param = new MapSqlParameterSource() + .addValue("id", id); + + template.update(DELETE_BY_ID.getQuery(), param); + + } + + @Override + public void deleteAll() { + + template.update(DELETE_ALL.getQuery(),new MapSqlParameterSource()); + + } + + @Override + public List findBlackList() { + return template.query(BLACKLIST.getQuery(), customerRowMapper()); + } + + private RowMapper customerRowMapper() { + return (rs, count) -> { + Long id = Long.parseLong(rs.getString("id")); + String name = rs.getString("name"); + String email = rs.getString("email"); + Boolean black_list = Boolean.valueOf(rs.getString("black_list")); + + return new Customer(id, name, email, black_list); + }; + } +} From 6dcac91246f31730664e67f86b7a70e93547aef3 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:49:09 +0900 Subject: [PATCH 065/109] =?UTF-8?q?feat:=20JdbcCustomerRepository=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8A=94=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=20=EB=AA=A8=EC=9D=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerQueryType.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/customer/CustomerQueryType.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerQueryType.java b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerQueryType.java new file mode 100644 index 0000000000..0839339794 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerQueryType.java @@ -0,0 +1,23 @@ +package com.prgms.vouchermanager.repository.customer; + +public enum CustomerQueryType { + + INSERT("insert into customers (id, name, email, black_list ) values (:id, :name, :email, :black_list )"), + UPDATE("update customers set id = :id , name = :name , email = :email , black_list = :black_list where id = :id"), + SELECT_BY_ID("select * from customers where id = :id"), + SELECT_ALL("select * from customers"), + DELETE_ALL("delete from customers"), + DELETE_BY_ID("delete from customers where id = :id"), + BLACKLIST("select * from customers where black_list=0"), + COUNT("select max(id) from customers"); + + private final String query; + + CustomerQueryType(String query) { + this.query = query; + } + + public String getQuery() { + return query; + } +} From dec057250b805bfcb9a184466d1e5067a4cd5ada Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:49:30 +0900 Subject: [PATCH 066/109] =?UTF-8?q?refactor:=20FileVoucherRepository=20?= =?UTF-8?q?=EB=82=B4=20=ED=95=84=EC=9A=94=ED=95=9C=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/FileVoucherRepository.java | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java index 698b71af5d..c22d7bd050 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java @@ -7,37 +7,61 @@ import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; @Repository @Profile("file") -public class FileVoucherRepository implements VoucherRepository{ +public class FileVoucherRepository implements VoucherRepository { private final FileManager fileManager; - private final Mapvouchers ; + private final Map vouchers; public FileVoucherRepository(FileManager fileManager) { this.fileManager = fileManager; vouchers = fileManager.readVoucherCsv(); + } + @Override + public Voucher save(Voucher voucher) { + return vouchers.put(voucher.getId(), voucher); } @Override - public void create(Voucher voucher) { + public void update(Voucher voucher) { vouchers.put(voucher.getId(), voucher); } @Override - public List getAllVouchers() { + public Optional findById(UUID id) { + try { + Voucher voucher = vouchers.get(id); + return Optional.of(voucher); + } catch (NullPointerException e) { + return Optional.empty(); + } + } + + @Override + public List findAll() { return new ArrayList<>(vouchers.values()); } + @Override + public void deleteById(UUID id) { + if (vouchers.containsKey(id)) { + vouchers.remove(id); + } + } + + @Override + public void deleteAll() { + vouchers.clear(); + } + @PreDestroy public void saveRepository() { fileManager.saveVoucherFile(vouchers); } } + From b69d9cc28365d06367a56761f9400338188e70a6 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:49:50 +0900 Subject: [PATCH 067/109] =?UTF-8?q?refactor:=20MemoryVoucherRepository=20?= =?UTF-8?q?=EB=82=B4=20=ED=95=84=EC=9A=94=ED=95=9C=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/MemoryVoucherRepository.java | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java index 6de6408f10..946ab0c170 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java @@ -18,12 +18,40 @@ public MemoryVoucherRepository() { } @Override - public void create(Voucher voucher) { + public Voucher save(Voucher voucher) { + return vouchers.put(voucher.getId(), voucher); + } + + @Override + public void update(Voucher voucher) { vouchers.put(voucher.getId(), voucher); } + + @Override + public Optional findById(UUID id) { + try { + Voucher voucher = vouchers.get(id); + return Optional.of(voucher); + } catch (NullPointerException e) { + return Optional.empty(); + } + } + + @Override + public List findAll() { + return new ArrayList<>(vouchers.values()); + } + @Override - public List getAllVouchers() { - List voucherList = new ArrayList<>(vouchers.values()); - return voucherList; + public void deleteAll() { + vouchers.clear(); } + + @Override + public void deleteById(UUID id) { + if (vouchers.containsKey(id)) { + vouchers.remove(id); + } + } + } From 1064947a20e085a37243b5a8315a5902f7b2e65d Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:51:21 +0900 Subject: [PATCH 068/109] =?UTF-8?q?feat:=20JdbcVoucherRepository=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/JdbcVoucherRepository.java | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java new file mode 100644 index 0000000000..17aa43edfb --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java @@ -0,0 +1,106 @@ +package com.prgms.vouchermanager.repository.voucher; + +import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; +import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.voucher.VoucherType; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Profile; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.stereotype.Repository; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static com.prgms.vouchermanager.repository.voucher.VoucherQueryType.*; + + +@Repository +@Slf4j +@Profile("jdbc") +public class JdbcVoucherRepository implements VoucherRepository { + private final NamedParameterJdbcTemplate template; + + public JdbcVoucherRepository(DataSource dataSource) { + template = new NamedParameterJdbcTemplate(dataSource); + } + + @Override + public Voucher save(Voucher voucher) { + + SqlParameterSource param = new MapSqlParameterSource() + .addValue("id", voucher.getId().toString()) + .addValue("discount_value", voucher.getDiscountValue()) + .addValue("type", voucher.getVoucherType().name()); + + + template.update(INSERT.getQuery(), param); + + return voucher; + + } + + @Override + public Optional findById(UUID id) { + SqlParameterSource param = new MapSqlParameterSource() + .addValue("id", id.toString()); + try { + return Optional.of(template.queryForObject(SELECT_BY_ID.getQuery(), param, voucherRowMapper())); + } catch (EmptyResultDataAccessException e) { + return Optional.empty(); + } + } + + @Override + public List findAll() { + + return template.query(SELECT_ALL.getQuery(), voucherRowMapper()); + + } + + @Override + public void update(Voucher voucher) { //항상 존재하는 id에만 실행 가능하도록 전제가 있다. + + SqlParameterSource param = new MapSqlParameterSource() + .addValue("id", voucher.getId().toString()) + .addValue("discount_value", voucher.getDiscountValue()) + .addValue("type", voucher.getVoucherType().name()); + + template.update(UPDATE.getQuery(), param); + } + + @Override + public void deleteById(UUID id) { + SqlParameterSource param = new MapSqlParameterSource() + .addValue("id", id.toString()); + + template.update(DELETE_BY_ID.getQuery(), param); + + } + + @Override + public void deleteAll() { + template.update(DELETE_ALL.getQuery(), new MapSqlParameterSource()); + } + + + private RowMapper voucherRowMapper() { + return (rs, count) -> { + UUID id = UUID.fromString(rs.getString("id")); + VoucherType type = VoucherType.valueOf(rs.getString("type")); + Long discountValue = rs.getLong("discount_value"); + + return type == VoucherType.FIXED_AMOUNT ? + new FixedAmountVoucher(id, discountValue) : + new PercentDiscountVoucher(id, discountValue); + }; + } + + +} From 8fa620b0105861d9d23f4bcc91a3ee2e1c92a2bb Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:51:32 +0900 Subject: [PATCH 069/109] =?UTF-8?q?feat:=20JdbcVoucherRepository=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=95=84=EC=9A=94=ED=95=9C=20=EC=BF=BC=EB=A6=AC=20?= =?UTF-8?q?=EB=AA=A8=EC=9D=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/voucher/VoucherQueryType.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherQueryType.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherQueryType.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherQueryType.java new file mode 100644 index 0000000000..68ed6d496f --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherQueryType.java @@ -0,0 +1,24 @@ +package com.prgms.vouchermanager.repository.voucher; + +public enum VoucherQueryType { + + SELECT_BY_ID("select * from vouchers WHERE id = :id"), + SELECT_ALL("select * from vouchers"), + INSERT("insert into vouchers (id, discount_value, type) " + + "values (:id, :discount_value, :type)"), + + UPDATE("update vouchers set id = :id , discount_value = :discount_value, type = :type "+ + "where id = :id"), + DELETE_BY_ID("delete from vouchers where id = :id"), + DELETE_ALL("delete from vouchers"); + + private final String query; + + VoucherQueryType(String query) { + this.query = query; + } + + public String getQuery() { + return query; + } +} From a56c7d322a6f96cbaba06b0b78d1e84598f84ca2 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:52:07 +0900 Subject: [PATCH 070/109] =?UTF-8?q?feat:=20WalletRepository=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/wallet/WalletRepository.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/wallet/WalletRepository.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletRepository.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletRepository.java new file mode 100644 index 0000000000..e3eb295366 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletRepository.java @@ -0,0 +1,18 @@ +package com.prgms.vouchermanager.repository.wallet; + +import com.prgms.vouchermanager.domain.wallet.Wallet; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface WalletRepository { + + Wallet save(Wallet wallet); + + List findByCustomerId(Long customerId); + + void deleteByCustomerId(Long customerId); + + Optional findByVoucherId(UUID voucherId); +} From 2eaf829c50d43f4def3a40bc3b9203bfc552e37d Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:52:22 +0900 Subject: [PATCH 071/109] =?UTF-8?q?feat:=20JdbcWalletRepository=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wallet/JdbcWalletRepository.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java new file mode 100644 index 0000000000..c396fae3ed --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java @@ -0,0 +1,89 @@ +package com.prgms.vouchermanager.repository.wallet; + +import com.prgms.vouchermanager.domain.wallet.Wallet; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import javax.sql.DataSource; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static com.prgms.vouchermanager.repository.wallet.WalletQueryType.*; + + +@Repository +public class JdbcWalletRepository implements WalletRepository { + + private final NamedParameterJdbcTemplate template; + + public JdbcWalletRepository(DataSource dataSource) { + template = new NamedParameterJdbcTemplate(dataSource); + } + + @Transactional + @Override + public Wallet save(Wallet wallet) { + + SqlParameterSource forSequenceParam = new MapSqlParameterSource(); + Long sequence = template.queryForObject(COUNT.getQuery(), forSequenceParam, Long.class); + wallet.setId(sequence + 1); + + MapSqlParameterSource param = new MapSqlParameterSource() + .addValue("id", wallet.getId()) + .addValue("customer_id", wallet.getCustomer_id()) + .addValue("voucher_id", wallet.getVoucher_id().toString()); + + template.update(INSERT.getQuery(), param); + + return wallet; + } + + @Override + public List findByCustomerId(Long customerId) { + + MapSqlParameterSource param = new MapSqlParameterSource() + .addValue("customer_id", customerId); + + return template.query(SELECT_BY_CUSTOMER_ID.getQuery(), param, walletRowMapper()); + + } + + @Override + public Optional findByVoucherId(UUID voucherId) { + MapSqlParameterSource param = new MapSqlParameterSource() + .addValue("voucher_id", voucherId.toString()); + + try { + return Optional.of(template.queryForObject(SELECT_BY_VOUCHER_ID.getQuery(), param, walletRowMapper())); + } catch (EmptyResultDataAccessException e) { + return Optional.empty(); + } + } + + @Transactional + @Override + public void deleteByCustomerId(Long customerId) { + MapSqlParameterSource param = new MapSqlParameterSource() + .addValue("customer_id", customerId); + + template.update(DELETE_BY_CUSTOMER_ID.getQuery(), param); + + } + + private RowMapper walletRowMapper() { + return (rs, count) -> { + Long id = Long.parseLong(rs.getString("id")); + Long customerId = Long.parseLong(rs.getString("customer_id")); + UUID voucherId = UUID.fromString(rs.getString("voucher_id")); + + return new Wallet(id, customerId, voucherId); + }; + } +} From 32b0e0b6b65dcc4dfec02b427366722ce85d18b1 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:52:38 +0900 Subject: [PATCH 072/109] =?UTF-8?q?feat:=20JdbcWalletRepository=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=95=84=EC=9A=94=ED=95=9C=20=EC=BF=BC=EB=A6=AC=20?= =?UTF-8?q?=EB=AA=A8=EC=9D=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/wallet/WalletQueryType.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java new file mode 100644 index 0000000000..15c5060e27 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java @@ -0,0 +1,25 @@ +package com.prgms.vouchermanager.repository.wallet; + +public enum WalletQueryType { + INSERT("insert into wallets (id, customer_id, voucher_id) " + + "values (:id, :customer_id, :voucher_id)"), + + SELECT_BY_CUSTOMER_ID("select * from wallets where customer_id = :customer_id "), + + SELECT_BY_VOUCHER_ID("select * from wallets where voucher_id = :voucher_id "), + + DELETE_BY_CUSTOMER_ID("delete from wallets where customer_id = :customer_id"), + + COUNT("select max(id) from wallets"); + + + private final String query; + + WalletQueryType(String query) { + this.query = query; + } + + public String getQuery() { + return query; + } +} From a3e8bc87247848d179533e826662282236c47d1f Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:53:03 +0900 Subject: [PATCH 073/109] =?UTF-8?q?refactor:=20CustomerService=20=EB=82=B4?= =?UTF-8?q?=20=ED=95=84=EC=9A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/customer/CustomerService.java | 73 ++++++++++++++++++- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java index e47d718d17..75c6ffe206 100644 --- a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java +++ b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java @@ -1,21 +1,88 @@ package com.prgms.vouchermanager.service.customer; import com.prgms.vouchermanager.domain.customer.Customer; +import com.prgms.vouchermanager.dto.CreateCustomerDto; +import com.prgms.vouchermanager.dto.UpdateCustomerDto; import com.prgms.vouchermanager.repository.customer.CustomerRepository; +import com.prgms.vouchermanager.validation.InputValidation; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; +import static com.prgms.vouchermanager.exception.ExceptionType.*; + @Service public class CustomerService { + private final CustomerRepository customerRepository; + private final InputValidation inputValidation; - public CustomerService(CustomerRepository customerRepository) { + public CustomerService(CustomerRepository customerRepository, InputValidation inputValidation) { this.customerRepository = customerRepository; + this.inputValidation = inputValidation; } - public List getBlackList() { - return customerRepository.getBlackList(); + @Transactional + public Customer create(CreateCustomerDto dto) { + + boolean blackList = false; + + if (inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())) { + + if (dto.getBlackList() == 1) { + blackList = true; + } + + return customerRepository.save(new Customer(null, dto.getName(), dto.getEmail(), blackList)); + } + throw new RuntimeException(INVALID_CUSTOMER_INFO.getMessage()); + + } + + @Transactional + public void update(Long id, UpdateCustomerDto dto) { + + boolean blackList = false; + if (inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())) { + if (dto.getBlackList() == 1) { + blackList = true; + } + customerRepository.update(new Customer(id, dto.getName(), dto.getEmail(), blackList)); + } + } + + public Customer findById(Long id) { + + return customerRepository.findById(id).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(),1)); + + } + + public List findAll() { + + List customers = customerRepository.findAll(); + return customers; + } + + @Transactional + public void deleteById(Long id) { + + customerRepository.deleteById(id); + + } + + @Transactional + public void deleteAll() { + + customerRepository.deleteAll(); + + } + + public List findBlackList() { + + return customerRepository.findBlackList(); + } } From b06bdb4eda6435615e049fee560ea382d9feb144 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:53:20 +0900 Subject: [PATCH 074/109] =?UTF-8?q?refactor:=20VoucherService=EA=B0=80=20?= =?UTF-8?q?=EB=82=B4=20=ED=95=84=EC=9A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/voucher/VoucherService.java | 69 +++++++++++++++---- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java index 004741b1db..9f01129a6a 100644 --- a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java +++ b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java @@ -5,42 +5,87 @@ import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; import com.prgms.vouchermanager.domain.voucher.Voucher; import com.prgms.vouchermanager.dto.CreateVoucherDto; -import com.prgms.vouchermanager.exception.ExceptionType; +import com.prgms.vouchermanager.dto.UpdateVoucherDto; import com.prgms.vouchermanager.repository.voucher.VoucherRepository; import com.prgms.vouchermanager.validation.InputValidation; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.UUID; +import static com.prgms.vouchermanager.exception.ExceptionType.*; + @Service public class VoucherService { - private final InputValidation validation; + private final InputValidation inputValidation; private final VoucherRepository voucherRepository; - public VoucherService(InputValidation validation, VoucherRepository voucherRepository) { - this.validation = validation; + public VoucherService(InputValidation inputValidation, VoucherRepository voucherRepository) { + this.inputValidation = inputValidation; this.voucherRepository = voucherRepository; } - public void create(CreateVoucherDto dto) { + @Transactional + public Voucher create(CreateVoucherDto dto) { Voucher voucher = null; + if (dto.getVoucherType() == 1) { voucher = new FixedAmountVoucher(UUID.randomUUID(), dto.getValue()); } else if (dto.getVoucherType() == 2) { - if (!validation.validVoucherPercent(dto.getValue())) { - throw new RuntimeException(ExceptionType.INVALID_VOUCHER_PERCENT.getMessage()); + if (!inputValidation.validVoucherPercent(dto.getValue())) { + throw new RuntimeException(INVALID_VOUCHER_PERCENT.getMessage()); } voucher = new PercentDiscountVoucher(UUID.randomUUID(), dto.getValue()); - } else - return; + } else throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); - voucherRepository.create(voucher); + try { + return voucherRepository.save(voucher); + } catch (DuplicateKeyException e) { + throw new DuplicateKeyException(DUPLICATED_KEY.getMessage()); + } } - public List getVoucherList() { - return voucherRepository.getAllVouchers(); + @Transactional + public void update(UUID id, UpdateVoucherDto dto) { + + Voucher voucher = null; + + if (dto.getVoucherType() == 1) { + voucher = new FixedAmountVoucher(id, dto.getValue()); + } else if (dto.getVoucherType() == 2) { + if (!inputValidation.validVoucherPercent(dto.getValue())) { + throw new RuntimeException(INVALID_VOUCHER_PERCENT.getMessage()); + } + voucher = new PercentDiscountVoucher(id, dto.getValue()); + } else throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); + + voucherRepository.update(voucher); + + } + + public Voucher findById(UUID id) { + + return voucherRepository.findById(id).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_VOUCHER_ID.getMessage(),1)); + + } + + public List findAll() { + return voucherRepository.findAll(); + } + + @Transactional + public void deleteById(UUID id) { + voucherRepository.deleteById(id); + } + + @Transactional + public void deleteAll() { + voucherRepository.deleteAll(); } } + From 66ac985ff4fd97c3c3866b4f496062f05b687769 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 26 Oct 2023 21:53:40 +0900 Subject: [PATCH 075/109] =?UTF-8?q?feat:=20WalletService=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/wallet/WalletService.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java diff --git a/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java b/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java new file mode 100644 index 0000000000..606cd0e52c --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java @@ -0,0 +1,57 @@ +package com.prgms.vouchermanager.service.wallet; + +import com.prgms.vouchermanager.domain.wallet.Wallet; +import com.prgms.vouchermanager.dto.CreateWalletDto; +import com.prgms.vouchermanager.repository.wallet.WalletRepository; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.UUID; + +import static com.prgms.vouchermanager.exception.ExceptionType.*; + +@Service +public class WalletService { + + private final WalletRepository walletRepository; + + public WalletService(WalletRepository walletRepository) { + this.walletRepository = walletRepository; + } + + @Transactional + public Wallet save(CreateWalletDto dto) { + + try { + return walletRepository.save(new Wallet(null,dto.getCustomerId(), dto.getVoucherId())); + } catch (DataIntegrityViolationException e) { + throw new DataIntegrityViolationException(INVALID_WALLET_INFO.getMessage()); + } + } + + @Transactional + public void deleteByCustomerId(Long customerId) { + + try { + walletRepository.deleteByCustomerId(customerId); + } catch (EmptyResultDataAccessException e){ + throw new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(),0); + } + } + + public List findByCustomerId(Long customerId) { + try { + return walletRepository.findByCustomerId(customerId); + } catch (EmptyResultDataAccessException e) { + throw new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(),0); + } + } + + public Wallet findByVoucherId(UUID voucherId) { + + return walletRepository.findByVoucherId(voucherId).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_VOUCHER_ID.getMessage(),0)); + } +} From 1ef917c826fea466eebe0f6d33b30056fff78049 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Fri, 27 Oct 2023 03:29:31 +0900 Subject: [PATCH 076/109] =?UTF-8?q?refactor:=20test=EC=8B=9C=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/resources/application.yaml b/src/test/resources/application.yaml index 02fd30410a..3623cb01f5 100644 --- a/src/test/resources/application.yaml +++ b/src/test/resources/application.yaml @@ -12,4 +12,11 @@ spring: init: mode: always +file: + path: + voucher: src/test/resources/voucher_list.csv + blacklist: src/test/resources/customer_blackList.csv + + + From 00d83935f282684616e4635f73310187bb474ae8 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 01:35:00 +0900 Subject: [PATCH 077/109] =?UTF-8?q?refactor:=20=EB=9E=8C=EB=8B=A4=EC=8B=9D?= =?UTF-8?q?=20->=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B0=B8=EC=A1=B0?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/contorller/customer/CustomerController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java index 313474379a..20e3342e60 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerController.java @@ -68,7 +68,7 @@ public void getList() { List customers = customerService.findAll(); - customers.forEach(customer -> consoleOutput.printCustomer(customer)); + customers.forEach(consoleOutput::printCustomer); } From e7120e4f4051ba7ed9b8d21a0250f829c777967f Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 01:57:01 +0900 Subject: [PATCH 078/109] =?UTF-8?q?refactor:=20LoggerFactory=20->=20@Slf4j?= =?UTF-8?q?=20=EB=A1=9C=20=EB=AA=A8=EB=91=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/front/FrontController.java | 15 ++++++--------- .../vouchermanager/util/io/ConsoleInput.java | 15 +++++---------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java index 27eafc11be..afe96b598b 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java @@ -10,19 +10,16 @@ import com.prgms.vouchermanager.util.io.ConsoleInput; import com.prgms.vouchermanager.util.io.ConsoleOutput; import com.prgms.vouchermanager.validation.InputValidation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import static com.prgms.vouchermanager.exception.ExceptionType.*; import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_CUSTOMER_MENU; - +@Slf4j @Controller public class FrontController { - private final static Logger logger = LoggerFactory.getLogger(FrontController.class); - private final ConsoleInput consoleInput; private final ConsoleOutput consoleOutput; private final VoucherController voucherController; @@ -62,7 +59,7 @@ public void run() { } } catch (RuntimeException e) { - logger.warn(e.getMessage()); + log.warn(e.getMessage()); continue; } @@ -91,7 +88,7 @@ private void runVoucherController() { } } catch (RuntimeException e) { - logger.warn(e.getMessage()); + log.warn(e.getMessage()); return; } @@ -119,7 +116,7 @@ private void runCustomerContoller() { } } catch (RuntimeException e) { - logger.warn(e.getMessage()); + log.warn(e.getMessage()); return; } @@ -148,7 +145,7 @@ private void runWalletController() { } catch (RuntimeException e) { - logger.warn(e.getMessage()); + log.warn(e.getMessage()); return; } } diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java index e31e6b3aa3..4735d10d00 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java @@ -1,10 +1,6 @@ package com.prgms.vouchermanager.util.io; - -import com.prgms.vouchermanager.contorller.front.FrontController; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Scanner; @@ -13,10 +9,9 @@ import static com.prgms.vouchermanager.exception.ExceptionType.*; import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_INFO; +@Slf4j @Component public class ConsoleInput { - - private final static Logger logger = LoggerFactory.getLogger(FrontController.class); private final Scanner scanner; @@ -28,7 +23,7 @@ public int inputFrontMenu() { try { return scanner.nextInt(); } catch (RuntimeException e) { - logger.warn(e.getMessage()); + log.warn(e.getMessage()); scanner.next(); throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); } @@ -41,7 +36,7 @@ public int inputVoucherMenu() { try { menu = scanner.nextInt(); } catch (RuntimeException e) { - logger.warn(e.getMessage()); + log.warn(e.getMessage()); throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); } return menu; @@ -55,7 +50,7 @@ public int inputCustomerMenu() { try { menu = scanner.nextInt(); } catch (RuntimeException e) { - logger.warn(e.getMessage()); + log.warn(e.getMessage()); throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); } From 9d45a8adb3fc3458ec2f8392dad9a044ccb3ec19 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 02:03:12 +0900 Subject: [PATCH 079/109] =?UTF-8?q?refactor:=20FrontController=EB=82=B4=20?= =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/contorller/front/FrontController.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java index afe96b598b..c17bde6f23 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java @@ -60,7 +60,6 @@ public void run() { } catch (RuntimeException e) { log.warn(e.getMessage()); - continue; } } @@ -89,7 +88,6 @@ private void runVoucherController() { } catch (RuntimeException e) { log.warn(e.getMessage()); - return; } @@ -117,7 +115,6 @@ private void runCustomerContoller() { } } catch (RuntimeException e) { log.warn(e.getMessage()); - return; } @@ -146,7 +143,6 @@ private void runWalletController() { } catch (RuntimeException e) { log.warn(e.getMessage()); - return; } } } From 6fe2b03615722c13ebc5f86bf79a624d313b2020 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 02:08:31 +0900 Subject: [PATCH 080/109] =?UTF-8?q?refactor:=20Wallet=20=EC=9D=98=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=EB=A5=BC=20=EC=B9=B4=EB=A9=9C=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/domain/wallet/Wallet.java | 15 +++++++-------- .../repository/wallet/JdbcWalletRepository.java | 4 ++-- .../repository/wallet/WalletRepositoryTest.java | 4 ++-- .../service/wallet/WalletServiceTest.java | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/domain/wallet/Wallet.java b/src/main/java/com/prgms/vouchermanager/domain/wallet/Wallet.java index f5e405c7ef..93e666fa71 100644 --- a/src/main/java/com/prgms/vouchermanager/domain/wallet/Wallet.java +++ b/src/main/java/com/prgms/vouchermanager/domain/wallet/Wallet.java @@ -1,6 +1,5 @@ package com.prgms.vouchermanager.domain.wallet; -import com.prgms.vouchermanager.domain.voucher.Voucher; import lombok.Getter; import java.util.UUID; @@ -9,13 +8,13 @@ public class Wallet { private Long id; - private final Long customer_id; - private final UUID voucher_id; + private final Long customerId; + private final UUID voucherId; - public Wallet(Long id, Long customer_id, UUID voucher_id) { + public Wallet(Long id, Long customerId, UUID voucherId) { this.id = id; - this.customer_id = customer_id; - this.voucher_id = voucher_id; + this.customerId = customerId; + this.voucherId = voucherId; } public void setId(Long id) { @@ -26,8 +25,8 @@ public void setId(Long id) { public String toString() { return "Wallet{" + "id=" + id + - ", customer_id=" + customer_id + - ", voucher_id=" + voucher_id + + ", customerId=" + customerId + + ", voucherId=" + voucherId + '}'; } } diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java index c396fae3ed..4f83418552 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java @@ -37,8 +37,8 @@ public Wallet save(Wallet wallet) { MapSqlParameterSource param = new MapSqlParameterSource() .addValue("id", wallet.getId()) - .addValue("customer_id", wallet.getCustomer_id()) - .addValue("voucher_id", wallet.getVoucher_id().toString()); + .addValue("customer_id", wallet.getCustomerId()) + .addValue("voucher_id", wallet.getVoucherId().toString()); template.update(INSERT.getQuery(), param); diff --git a/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java b/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java index f53aeccf95..9f2a943eef 100644 --- a/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java +++ b/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java @@ -124,8 +124,8 @@ void findByVoucherIdSuccess() { //then Assertions.assertThat(findByVoucherIdwallet.get().getId()).isEqualTo(wallet.getId()); - Assertions.assertThat(findByVoucherIdwallet.get().getVoucher_id()).isEqualTo(wallet.getVoucher_id()); - Assertions.assertThat(findByVoucherIdwallet.get().getCustomer_id()).isEqualTo(wallet.getCustomer_id()); + Assertions.assertThat(findByVoucherIdwallet.get().getVoucherId()).isEqualTo(wallet.getVoucherId()); + Assertions.assertThat(findByVoucherIdwallet.get().getCustomerId()).isEqualTo(wallet.getCustomerId()); } @Test diff --git a/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java index e8a2ae2596..4f6ab97154 100644 --- a/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java +++ b/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java @@ -41,7 +41,7 @@ void createWalletSuccess() { Wallet wallet = walletService.save(dto); //then - Assertions.assertThat(voucherId).isEqualTo(wallet.getVoucher_id()); + Assertions.assertThat(voucherId).isEqualTo(wallet.getVoucherId()); verify(walletRepository,atLeastOnce()).save(any(Wallet.class)); } From b7827fa776b4eed65b04f3961f8a0394618f507e Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 02:36:27 +0900 Subject: [PATCH 081/109] =?UTF-8?q?refactor:=20final=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/customer/CustomerFileRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerFileRepository.java b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerFileRepository.java index c83f4e0935..2d709e0ee7 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerFileRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerFileRepository.java @@ -11,7 +11,7 @@ @Repository @Profile("file") public class CustomerFileRepository { - private Map blackList; + private final Map blackList; public CustomerFileRepository(FileManager fileManager) { From 7e8202f09547e5c6cc82db51a6f8f6ea7e2449c7 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 03:00:41 +0900 Subject: [PATCH 082/109] =?UTF-8?q?refactor:=20KeyHolder=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/customer/CustomerQueryType.java | 3 +-- .../repository/customer/JdbcCustomerRepository.java | 11 ++++++----- .../repository/wallet/JdbcWalletRepository.java | 12 ++++++++---- .../repository/wallet/WalletQueryType.java | 5 +---- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerQueryType.java b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerQueryType.java index 0839339794..968aba6906 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerQueryType.java +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/CustomerQueryType.java @@ -8,8 +8,7 @@ public enum CustomerQueryType { SELECT_ALL("select * from customers"), DELETE_ALL("delete from customers"), DELETE_BY_ID("delete from customers where id = :id"), - BLACKLIST("select * from customers where black_list=0"), - COUNT("select max(id) from customers"); + BLACKLIST("select * from customers where black_list=0"); private final String query; diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java b/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java index 929d166c88..c5db0bf745 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java @@ -9,6 +9,8 @@ import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Repository; import javax.sql.DataSource; @@ -30,9 +32,7 @@ public JdbcCustomerRepository(DataSource dataSource) { public Customer save(Customer customer) { - SqlParameterSource forSequenceParam = new MapSqlParameterSource(); - Long sequence = template.queryForObject(COUNT.getQuery(), forSequenceParam, Long.class); - customer.setId(sequence+1); + KeyHolder keyHolder = new GeneratedKeyHolder(); SqlParameterSource param = new MapSqlParameterSource() .addValue("id", customer.getId()) @@ -40,9 +40,10 @@ public Customer save(Customer customer) { .addValue("email", customer.getEmail()) .addValue("black_list", customer.isBlackList()); + template.update(INSERT.getQuery(), param, keyHolder); + long id = keyHolder.getKey().longValue(); - template.update(INSERT.getQuery(), param); - + customer.setId(id); return customer; } diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java index 4f83418552..74a8ce7b54 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java @@ -6,6 +6,8 @@ import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @@ -15,6 +17,7 @@ import java.util.Optional; import java.util.UUID; +import static com.prgms.vouchermanager.repository.customer.CustomerQueryType.INSERT; import static com.prgms.vouchermanager.repository.wallet.WalletQueryType.*; @@ -31,16 +34,17 @@ public JdbcWalletRepository(DataSource dataSource) { @Override public Wallet save(Wallet wallet) { - SqlParameterSource forSequenceParam = new MapSqlParameterSource(); - Long sequence = template.queryForObject(COUNT.getQuery(), forSequenceParam, Long.class); - wallet.setId(sequence + 1); + KeyHolder keyHolder = new GeneratedKeyHolder(); MapSqlParameterSource param = new MapSqlParameterSource() .addValue("id", wallet.getId()) .addValue("customer_id", wallet.getCustomerId()) .addValue("voucher_id", wallet.getVoucherId().toString()); - template.update(INSERT.getQuery(), param); + template.update(INSERT.getQuery(), param, keyHolder); + long id = keyHolder.getKey().longValue(); + + wallet.setId(id); return wallet; } diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java index 15c5060e27..15201cba9c 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java @@ -8,10 +8,7 @@ public enum WalletQueryType { SELECT_BY_VOUCHER_ID("select * from wallets where voucher_id = :voucher_id "), - DELETE_BY_CUSTOMER_ID("delete from wallets where customer_id = :customer_id"), - - COUNT("select max(id) from wallets"); - + DELETE_BY_CUSTOMER_ID("delete from wallets where customer_id = :customer_id"); private final String query; From 6a8a1af0d82993059554df348e696b7d634957aa Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 10:43:26 +0900 Subject: [PATCH 083/109] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/voucher/FileVoucherRepository.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java index c22d7bd050..f1b5dd87e5 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java @@ -49,9 +49,7 @@ public List findAll() { @Override public void deleteById(UUID id) { - if (vouchers.containsKey(id)) { - vouchers.remove(id); - } + vouchers.remove(id); } @Override From 12457020dc631e42c674f919bdd814e44df4ea40 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 10:45:18 +0900 Subject: [PATCH 084/109] =?UTF-8?q?refactor:=20Optional=EC=9D=98=20of?= =?UTF-8?q?=EB=A5=BC=20ofNullable=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/customer/JdbcCustomerRepository.java | 2 +- .../repository/voucher/JdbcVoucherRepository.java | 2 +- .../vouchermanager/repository/wallet/JdbcWalletRepository.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java b/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java index c5db0bf745..48d0b82982 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/customer/JdbcCustomerRepository.java @@ -67,7 +67,7 @@ public Optional findById(Long id) { .addValue("id", id); try { - return Optional.of(template.queryForObject(SELECT_BY_ID.getQuery(), param, customerRowMapper())); + return Optional.ofNullable(template.queryForObject(SELECT_BY_ID.getQuery(), param, customerRowMapper())); } catch (EmptyResultDataAccessException e) { return Optional.empty(); } diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java index 17aa43edfb..d0b8ca4438 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java @@ -51,7 +51,7 @@ public Optional findById(UUID id) { SqlParameterSource param = new MapSqlParameterSource() .addValue("id", id.toString()); try { - return Optional.of(template.queryForObject(SELECT_BY_ID.getQuery(), param, voucherRowMapper())); + return Optional.ofNullable(template.queryForObject(SELECT_BY_ID.getQuery(), param, voucherRowMapper())); } catch (EmptyResultDataAccessException e) { return Optional.empty(); } diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java index 74a8ce7b54..7400685c68 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java @@ -65,7 +65,7 @@ public Optional findByVoucherId(UUID voucherId) { .addValue("voucher_id", voucherId.toString()); try { - return Optional.of(template.queryForObject(SELECT_BY_VOUCHER_ID.getQuery(), param, walletRowMapper())); + return Optional.ofNullable(template.queryForObject(SELECT_BY_VOUCHER_ID.getQuery(), param, walletRowMapper())); } catch (EmptyResultDataAccessException e) { return Optional.empty(); } From 4bcd1e0508c5398ec8576d7b7b8244d91b7b15e0 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 11:17:51 +0900 Subject: [PATCH 085/109] =?UTF-8?q?refactor:=20=EC=9D=BD=EA=B8=B0=EC=A0=84?= =?UTF-8?q?=EC=9A=A9=20@Transactional(readOnly=3Dtrue)=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/service/customer/CustomerService.java | 8 +++++--- .../vouchermanager/service/voucher/VoucherService.java | 2 ++ .../vouchermanager/service/wallet/WalletService.java | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java index 75c6ffe206..f605a6de43 100644 --- a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java +++ b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java @@ -15,8 +15,7 @@ @Service public class CustomerService { - - + private final CustomerRepository customerRepository; private final InputValidation inputValidation; @@ -54,12 +53,14 @@ public void update(Long id, UpdateCustomerDto dto) { } } + @Transactional(readOnly = true) public Customer findById(Long id) { - return customerRepository.findById(id).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(),1)); + return customerRepository.findById(id).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(), 1)); } + @Transactional(readOnly = true) public List findAll() { List customers = customerRepository.findAll(); @@ -80,6 +81,7 @@ public void deleteAll() { } + @Transactional(readOnly = true) public List findBlackList() { return customerRepository.findBlackList(); diff --git a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java index 9f01129a6a..b07c0f7df3 100644 --- a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java +++ b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java @@ -67,12 +67,14 @@ public void update(UUID id, UpdateVoucherDto dto) { voucherRepository.update(voucher); } + @Transactional(readOnly = true) public Voucher findById(UUID id) { return voucherRepository.findById(id).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_VOUCHER_ID.getMessage(),1)); } + @Transactional(readOnly = true) public List findAll() { return voucherRepository.findAll(); diff --git a/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java b/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java index 606cd0e52c..fb749421f3 100644 --- a/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java +++ b/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java @@ -42,6 +42,8 @@ public void deleteByCustomerId(Long customerId) { } } + @Transactional(readOnly = true) + public List findByCustomerId(Long customerId) { try { return walletRepository.findByCustomerId(customerId); @@ -50,6 +52,8 @@ public List findByCustomerId(Long customerId) { } } + @Transactional(readOnly = true) + public Wallet findByVoucherId(UUID voucherId) { return walletRepository.findByVoucherId(voucherId).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_VOUCHER_ID.getMessage(),0)); From ac011cf5c6f289ae4cb0b86ebc70f08d3d5beac1 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 11:45:52 +0900 Subject: [PATCH 086/109] =?UTF-8?q?refactor:=20voucher=20Percent=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/voucher/VoucherController.java | 11 ++++++++++- .../service/voucher/VoucherService.java | 7 +++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java index 11b6dcacf8..0adb47b457 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java @@ -6,6 +6,7 @@ import com.prgms.vouchermanager.service.voucher.VoucherService; import com.prgms.vouchermanager.util.io.ConsoleInput; import com.prgms.vouchermanager.util.io.ConsoleOutput; +import com.prgms.vouchermanager.validation.InputValidation; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; @@ -13,6 +14,8 @@ import java.util.List; import java.util.UUID; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_PERCENT; + @Slf4j @Controller public class VoucherController { @@ -23,10 +26,13 @@ public class VoucherController { private final ConsoleOutput consoleOutput; - public VoucherController(VoucherService voucherService, ConsoleInput consoleInput, ConsoleOutput consoleOutput) { + private final InputValidation inputValidation; + + public VoucherController(VoucherService voucherService, ConsoleInput consoleInput, ConsoleOutput consoleOutput, InputValidation inputValidation) { this.voucherService = voucherService; this.consoleInput = consoleInput; this.consoleOutput = consoleOutput; + this.inputValidation = inputValidation; } public void create() { @@ -35,6 +41,9 @@ public void create() { int voucherType = consoleInput.inputVoucherType(); consoleOutput.printVoucherAmount(); long value = consoleInput.inputVoucherValue(); + if (voucherType==2&&!inputValidation.validVoucherPercent(value)) { + throw new RuntimeException(INVALID_VOUCHER_PERCENT.getMessage()); + } Voucher voucher = voucherService.create(new CreateVoucherDto(value, voucherType)); log.info(voucher.toString()); diff --git a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java index b07c0f7df3..af43d139a1 100644 --- a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java +++ b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java @@ -37,9 +37,6 @@ public Voucher create(CreateVoucherDto dto) { if (dto.getVoucherType() == 1) { voucher = new FixedAmountVoucher(UUID.randomUUID(), dto.getValue()); } else if (dto.getVoucherType() == 2) { - if (!inputValidation.validVoucherPercent(dto.getValue())) { - throw new RuntimeException(INVALID_VOUCHER_PERCENT.getMessage()); - } voucher = new PercentDiscountVoucher(UUID.randomUUID(), dto.getValue()); } else throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); @@ -67,13 +64,15 @@ public void update(UUID id, UpdateVoucherDto dto) { voucherRepository.update(voucher); } + @Transactional(readOnly = true) public Voucher findById(UUID id) { - return voucherRepository.findById(id).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_VOUCHER_ID.getMessage(),1)); + return voucherRepository.findById(id).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_VOUCHER_ID.getMessage(), 1)); } + @Transactional(readOnly = true) public List findAll() { From 5f6089942acf810eb96bd271a6b3ff0ca2e50220 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 15:29:14 +0900 Subject: [PATCH 087/109] =?UTF-8?q?refactor:=20=EB=A0=88=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EB=B3=84=20=EC=97=AD=ED=95=A0=20=EB=B3=80=EA=B2=BD=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CustomerRepositoryTest.java | 15 ++++++++------- .../repository/wallet/WalletRepositoryTest.java | 10 ++++++---- .../service/voucher/VoucherServiceTest.java | 12 ------------ 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/test/java/com/prgms/vouchermanager/repository/customer/CustomerRepositoryTest.java b/src/test/java/com/prgms/vouchermanager/repository/customer/CustomerRepositoryTest.java index c625e3a19a..301c9f6ee7 100644 --- a/src/test/java/com/prgms/vouchermanager/repository/customer/CustomerRepositoryTest.java +++ b/src/test/java/com/prgms/vouchermanager/repository/customer/CustomerRepositoryTest.java @@ -25,16 +25,17 @@ void saveCustomrSuccess() { //given Customer customer1 = new Customer(null, "heo", "heo@naver.com", true); Customer customer2 = new Customer(null, "koo", "koo@naver.com", false); - Customer customer3 = new Customer(100L, "koo", "koo@naver.com", false); + Customer customer3 = new Customer(null, "koo1", "koo@naver.com", false); //when - customerRepository.save(customer1); - customerRepository.save(customer2); - customerRepository.save(customer3); + Customer saveCustomer1 = customerRepository.save(customer1); + Customer saveCustomer2 = customerRepository.save(customer2); + Customer saveCustomer3 = customerRepository.save(customer3); + //then - Assertions.assertThat(customer1.getId() + 1).isEqualTo(customer2.getId()); - Assertions.assertThat(customer2.getId() + 1).isEqualTo(customer3.getId()); + Assertions.assertThat(saveCustomer1.getId() + 1).isEqualTo(saveCustomer2.getId()); + Assertions.assertThat(saveCustomer2.getId() + 1).isEqualTo(saveCustomer3.getId()); } @Test @@ -112,7 +113,7 @@ void deleteByCustomerSuccess() { //given Long id = 1L; - Customer customer = new Customer(id, "kim", "lee@naver.com", true); + Customer customer = new Customer(null, "kim33", "lee@naver.com", true); customerRepository.save(customer); //when diff --git a/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java b/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java index 9f2a943eef..30c8572580 100644 --- a/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java +++ b/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java @@ -12,12 +12,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; import java.util.UUID; @SpringBootTest +@Transactional public class WalletRepositoryTest { @Autowired @@ -34,11 +36,11 @@ void saveWalletSuccess() { //given UUID id = UUID.randomUUID(); Voucher voucher = new FixedAmountVoucher(id, 100000); - Customer customer = new Customer(1L, "ko", "kp@naver.com", true); + Customer customer = new Customer(null, "ko", "kp@naver.com", true); voucherRepository.save(voucher); - customerRepository.save(customer); + Customer savedCustomer = customerRepository.save(customer); - Wallet wallet = new Wallet(6L, 1L, id); + Wallet wallet = new Wallet(6L, savedCustomer.getId(), id); //when Wallet savedWallet = walletRepository.save(wallet); @@ -55,7 +57,7 @@ void saveWalletFail() { //given UUID id = UUID.randomUUID(); Voucher voucher = new FixedAmountVoucher(id, 100000); - Customer customer = new Customer(1L, "ko", "kp@naver.com", true); + Customer customer = new Customer(null, "ko", "kp@naver.com", true); Wallet wallet = new Wallet(10L, 1214L, UUID.randomUUID()); //존재하지 않는 참조데이터 //when diff --git a/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java index 7fe115dbcf..a1df05867d 100644 --- a/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java +++ b/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java @@ -48,7 +48,6 @@ void createVoucherSuccess() { new PercentDiscountVoucher(id,dto.getValue()); when(voucherRepository.save(any(Voucher.class))).thenReturn(result); - when(inputValidation.validVoucherPercent(dto.getValue())).thenReturn(true); //when Voucher voucher = voucherService.create(dto); @@ -57,17 +56,6 @@ void createVoucherSuccess() { verify(voucherRepository,atLeastOnce()).save(any(Voucher.class)); } - @Test - @DisplayName("service의 create()에서 repository의 save()를 실행에 실패한다.") - void createVoucherFail() { - //given - CreateVoucherDto dto = new CreateVoucherDto(101, 2); - when(inputValidation.validVoucherPercent(dto.getValue())).thenReturn(false); - //when - //then - Assertions.assertThatThrownBy(() -> voucherService.create(dto)). - isInstanceOf(RuntimeException.class); - } @Test @DisplayName("service의 update()에서 repository의 update()가 정상적으로 실행된다.") From 0e31b6e56dbc84e6bc3b0b264376f39e4c647fcf Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 15:31:47 +0900 Subject: [PATCH 088/109] =?UTF-8?q?refactor:=20scanner=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=ED=95=A0=EB=8B=B9->=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=ED=95=A0=EB=8B=B9=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/prgms/vouchermanager/util/io/ConsoleInput.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java index 4735d10d00..853c83a5cf 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java @@ -12,12 +12,7 @@ @Slf4j @Component public class ConsoleInput { - private final Scanner scanner; - - - public ConsoleInput() { - scanner = new Scanner(System.in); - } + private final Scanner scanner = new Scanner(System.in); public int inputFrontMenu() { try { From 04315536ce5937c230743162b04fa9d421775546 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 16:15:21 +0900 Subject: [PATCH 089/109] =?UTF-8?q?refactor:=20console=20=EC=9E=85?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EB=B6=80=EB=B6=84=20=EA=B3=B5=ED=86=B5?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9C=BC=EB=A1=9C=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/util/io/ConsoleInput.java | 53 ++++++------------- .../vouchermanager/util/io/ConsoleOutput.java | 34 ++++++------ 2 files changed, 33 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java index 853c83a5cf..f0adf3cac3 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleInput.java @@ -1,5 +1,6 @@ package com.prgms.vouchermanager.util.io; +import com.prgms.vouchermanager.exception.ExceptionType; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -14,50 +15,36 @@ public class ConsoleInput { private final Scanner scanner = new Scanner(System.in); - public int inputFrontMenu() { + private int inputMenu(ExceptionType type) { try { return scanner.nextInt(); } catch (RuntimeException e) { - log.warn(e.getMessage()); scanner.next(); - throw new RuntimeException(INVALID_FRONT_MENU.getMessage()); + throw new RuntimeException(type.getMessage()); } } - public int inputVoucherMenu() { - - int menu ; - - try { - menu = scanner.nextInt(); - } catch (RuntimeException e) { - log.warn(e.getMessage()); - throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); - } - return menu; + public int inputFrontMenu() { + return inputMenu(INVALID_FRONT_MENU); + } + public int inputVoucherMenu() { + return inputMenu(INVALID_VOUCHER_MENU); } public int inputCustomerMenu() { - int menu; + return inputMenu(INVALID_CUSTOMER_MENU); + } - try { - menu = scanner.nextInt(); - } catch (RuntimeException e) { - log.warn(e.getMessage()); - throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); - } + public int inputVoucherType() { - return menu; + return inputMenu(INVALID_VOUCHER_TYPE); } - public int inputVoucherType() { - try { - return scanner.nextInt(); - } catch (RuntimeException e) { - throw new RuntimeException(INVALID_VOUCHER_TYPE.getMessage()); - } + public int inputBlackList() { + + return inputMenu(INVALID_CUSTOMER_INFO); } public long inputVoucherValue() { @@ -71,7 +58,7 @@ public long inputVoucherValue() { public UUID inputVoucherId() { try { return UUID.fromString(scanner.next()); - }catch (RuntimeException e) { + } catch (RuntimeException e) { throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); } } @@ -84,14 +71,6 @@ public String inputCustomerEmail() { return scanner.next(); } - public int inputBlackList() { - try { - return scanner.nextInt(); - } catch (RuntimeException e) { - throw new RuntimeException(INVALID_CUSTOMER_INFO.getMessage()); - } - } - public Long inputCustomerId() { try { return scanner.nextLong(); diff --git a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java index dd9e2f1a0d..a4b15fedd9 100644 --- a/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java +++ b/src/main/java/com/prgms/vouchermanager/util/io/ConsoleOutput.java @@ -7,11 +7,11 @@ @Component public class ConsoleOutput { - - public ConsoleOutput() { + private void printCommon(String s) { + System.out.println(s); } public void printFrontMenu() { - System.out.println(""" + printCommon(""" 사용할 메뉴를 선택해주세요. @@ -26,7 +26,7 @@ public void printFrontMenu() { } public void printVoucherMenu() { - System.out.println(""" + printCommon(""" === Voucher Program === 이용할 바우처 메뉴를 선택해주세요 @@ -48,7 +48,7 @@ public void printVoucherMenu() { public void printVoucherType() { - System.out.println(""" + printCommon(""" 이용하실 쿠폰의 타입 번호를 입력해주세요 @@ -60,7 +60,7 @@ public void printVoucherType() { } public void printCustomerMenu() { - System.out.println(""" + printCommon(""" 이용하실 고객 메뉴를 입력해주세요 @@ -82,7 +82,7 @@ public void printCustomerMenu() { } public void printWalletMenu() { - System.out.println(""" + printCommon(""" 이용하실 지갑 메뉴를 입력해주세요 1. CREATE @@ -96,42 +96,42 @@ public void printWalletMenu() { """); } public void printVoucherAmount() { - System.out.println("쿠폰의 할인값을 입력해주세요"); + printCommon("쿠폰의 할인값을 입력해주세요"); } public void printVoucherId() { - System.out.println("쿠폰 번호를 입력해주세요."); + printCommon("쿠폰 번호를 입력해주세요."); } public void printSuccessDelete() { - System.out.println("성공적으로 삭제되었습니다."); + printCommon("성공적으로 삭제되었습니다."); } public void printCustomerName() { - System.out.println("고객명을 입력해주세요.{"); + printCommon("고객명을 입력해주세요.{"); } public void printCustomerEmail() { - System.out.println("이메일을 입력해주세요."); + printCommon("이메일을 입력해주세요."); } public void printBlackList() { - System.out.println("블랙리스트에 등록하시려면 1번, 아니라면 2번을 입력해주세요"); + printCommon("블랙리스트에 등록하시려면 1번, 아니라면 2번을 입력해주세요"); } public void printCustomerId() { - System.out.println("고객 ID를 입력해주세요."); + printCommon("고객 ID를 입력해주세요."); } public void printCustomer(Customer customer) { - System.out.println(customer.toString()); + printCommon(customer.toString()); } public void printSuccessUpdate() { - System.out.println("성공적으로 업데이트 되었습니다."); + printCommon("성공적으로 업데이트 되었습니다."); } public void printWallet(Wallet wallet) { - System.out.println(wallet.toString()); + printCommon(wallet.toString()); } } From 76b98b9cdea96d8d51494aacd8ce2dcc3bba9f63 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 19:38:30 +0900 Subject: [PATCH 090/109] =?UTF-8?q?refactor:=20menu=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=EC=9D=84=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=EC=97=90=EC=84=9C=20enumType=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9C=84=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/customer/CustomerMenuType.java | 14 ++++++++------ .../contorller/front/FrontController.java | 11 ++--------- .../contorller/voucher/VoucherMenuType.java | 12 +++++++----- .../contorller/wallet/WalletMenuType.java | 13 ++++++++----- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java index bd1f45bf20..ef23a5de4f 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/customer/CustomerMenuType.java @@ -2,8 +2,10 @@ import java.util.Arrays; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_CUSTOMER_MENU; + public enum CustomerMenuType { - CREATE(1), UPDATE(2), FIND_ALL(3), FIND_ONE(4), DELETE_ONE(5), DELETE_ALL(6),BLACK_LIST(7); + CREATE(1), UPDATE(2), FIND_ALL(3), FIND_ONE(4), DELETE_ONE(5), DELETE_ALL(6), BLACK_LIST(7); private final int number; @@ -11,15 +13,15 @@ public enum CustomerMenuType { this.number = number; } - public int getNumber() { - return number; - } - public static CustomerMenuType fromValue(int menu) { return Arrays.stream(CustomerMenuType.values()) .filter(customerMenuType -> customerMenuType.getNumber() == menu) .findFirst() - .get(); + .orElseThrow(() -> new RuntimeException(INVALID_CUSTOMER_MENU.getMessage())); + } + + public int getNumber() { + return number; } } diff --git a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java index c17bde6f23..792e3b9eb0 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/front/FrontController.java @@ -13,8 +13,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; -import static com.prgms.vouchermanager.exception.ExceptionType.*; -import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_CUSTOMER_MENU; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_FRONT_MENU; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_WALLET_MENU; @Slf4j @Controller @@ -72,10 +72,6 @@ private void runVoucherController() { try { menu = consoleInput.inputVoucherMenu(); - if (!inputValidation.validVoucherMenu(menu)) { - throw new RuntimeException(INVALID_VOUCHER_MENU.getMessage()); - } - switch (VoucherMenuType.fromValue(menu)) { case CREATE -> voucherController.create(); case UPDATE -> voucherController.update(); @@ -100,9 +96,6 @@ private void runCustomerContoller() { try { menu = consoleInput.inputCustomerMenu(); - if (!inputValidation.validCustomerMenu(menu)) { - throw new RuntimeException(INVALID_CUSTOMER_MENU.getMessage()); - } switch (CustomerMenuType.fromValue(menu)) { case CREATE -> customerController.create(); case UPDATE -> customerController.update(); diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java index e6a769ddf5..cce108b1f2 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherMenuType.java @@ -2,6 +2,8 @@ import java.util.Arrays; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_MENU; + public enum VoucherMenuType { CREATE(1), UPDATE(2), LIST(3), ONE(4), DELETE_ONE(5), DELETE_ALL(6); private final int number; @@ -10,16 +12,16 @@ public enum VoucherMenuType { this.number = number; } - public int getNumber() { - return number; - } - public static VoucherMenuType fromValue(int menu) { return Arrays.stream(VoucherMenuType.values()) .filter(voucherMenuType -> voucherMenuType.getNumber() == menu) .findFirst() - .get(); + .orElseThrow(() -> new RuntimeException(INVALID_VOUCHER_MENU.getMessage())); + } + + public int getNumber() { + return number; } } diff --git a/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletMenuType.java b/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletMenuType.java index 1ba319d08c..5d8ebc2cdb 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletMenuType.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/wallet/WalletMenuType.java @@ -2,6 +2,8 @@ import java.util.Arrays; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_WALLET_MENU; + public enum WalletMenuType { CREATE(1), FIND_BY_CUSTOMER_ID(2), FIND_BY_VOUCHER_ID(3), DELETE_BY_CUSTOMER_ID(4); @@ -11,15 +13,16 @@ public enum WalletMenuType { this.number = number; } - public int getNumber() { - return number; - } - public static WalletMenuType fromValue(int menu) { return Arrays.stream(WalletMenuType.values()) .filter(walletMenuType -> walletMenuType.getNumber() == menu) .findFirst() - .get(); + .orElseThrow(() -> new RuntimeException(INVALID_WALLET_MENU.getMessage())); + + } + + public int getNumber() { + return number; } } From f6e9459e97ccf28c255454b6eb790baf10b20f48 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 21:00:42 +0900 Subject: [PATCH 091/109] =?UTF-8?q?refactor:=20=EC=A0=81=EC=A0=88=ED=95=9C?= =?UTF-8?q?=20=EC=83=81=ED=83=9C=EA=B2=80=EC=A6=9D=EA=B3=BC=20=ED=96=89?= =?UTF-8?q?=EC=9C=84=EA=B2=80=EC=A6=9D=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20?= =?UTF-8?q?DisplayName=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/customer/CustomerServiceTest.java | 63 +++++++++++-------- .../service/voucher/VoucherServiceTest.java | 48 +++++--------- .../service/wallet/WalletServiceTest.java | 61 ++++++++++++------ 3 files changed, 96 insertions(+), 76 deletions(-) diff --git a/src/test/java/com/prgms/vouchermanager/service/customer/CustomerServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/customer/CustomerServiceTest.java index 41fc956586..c61e7fe24b 100644 --- a/src/test/java/com/prgms/vouchermanager/service/customer/CustomerServiceTest.java +++ b/src/test/java/com/prgms/vouchermanager/service/customer/CustomerServiceTest.java @@ -14,7 +14,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.dao.EmptyResultDataAccessException; -import java.util.NoSuchElementException; +import java.util.List; import java.util.Optional; import static org.mockito.Mockito.*; @@ -22,16 +22,13 @@ @ExtendWith(MockitoExtension.class) class CustomerServiceTest { + @InjectMocks + CustomerService customerService; @Mock private CustomerRepository customerRepsotiory; - @Mock private InputValidation inputValidation; - @InjectMocks - CustomerService customerService; - - @Test @DisplayName("service의 create()를 통해 repository의 save()를 정상 실행하고, 값을 받아올수 있다.") void createCusteomerSuccess() { @@ -48,15 +45,14 @@ void createCusteomerSuccess() { //then Assertions.assertThat(customer).isEqualTo(result); - verify(customerRepsotiory,atLeastOnce()).save(any(Customer.class)); } @Test - @DisplayName("service의 create()를 통해 repository의 save()를 실행에 실패한다.") + @DisplayName("service의 create()를 실행시 입력값 검증 실패로 RuntimeException 예외가 발생한다.") void createCusteomerFail() { //given - CreateCustomerDto dto = new CreateCustomerDto("kim", "won05121@naver.com", 1); + CreateCustomerDto dto = new CreateCustomerDto("kim", "won05121@naver.com", 12345); when(inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())) .thenReturn(false); @@ -71,7 +67,6 @@ void createCusteomerFail() { void updateCustomerSuccess() { //given UpdateCustomerDto dto = new UpdateCustomerDto("kim", "won05121@naver.com", 1); - Customer result = new Customer(null, dto.getName(), dto.getEmail(), true); when(inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())).thenReturn(true); //when @@ -82,41 +77,57 @@ void updateCustomerSuccess() { } @Test - @DisplayName("service의 update()를 통해 repository의 update()의 실행에 실패한다.") + @DisplayName("service의 update()를 통해 입력값 검증 실패시 RuntimeException예외가 발생한다.") void updateCustomerFail() { //given UpdateCustomerDto dto = new UpdateCustomerDto("kim", "won05121@naver.com", 1); when(inputValidation.validCustomerInfo(dto.getName(), dto.getEmail(), dto.getBlackList())).thenReturn(false); //when - customerService.update(1L,dto); - //then - verify(customerRepsotiory, never()).update(any(Customer.class)); + Assertions.assertThatThrownBy(() -> customerService.update(1L, dto)).isInstanceOf(RuntimeException.class); } @Test - @DisplayName("service의 findById()의 인자값에 상관없이 ,repository의 findById()는 반드시 한번은 실행된다.") + @DisplayName("service의 findById()로 존재하는 ID가 들어오면 ,repository의 findById()는 성공적으로 값을 찾아온다. .") void findByIdCustomerSuccess() { //given - when(customerRepsotiory.findById(any())) - .thenReturn(Optional.ofNullable(null)); + Customer customer = new Customer(1L, "kk", "kk@naver.com", true); + when(customerRepsotiory.findById(customer.getId())) + .thenReturn(Optional.ofNullable(customer)); + + //when + //then + Assertions.assertThat(customer).isEqualTo(customerService.findById(customer.getId())); + + } + + @Test + @DisplayName("service의 findById()의 인자로 존재하지 않는 ID가 들어오면 EmptyResultDataAccessException 예외가 발생한다 .") + void findByIdCustomerFail() { + //given + Long notExistId = 1L; + //when + when(customerRepsotiory.findById(any())).thenReturn(Optional.ofNullable(null)); - Assertions.assertThatThrownBy(() -> customerService.findById(1L)).isInstanceOf(EmptyResultDataAccessException.class); - verify(customerRepsotiory, atLeastOnce()).findById(any()); + //then + Assertions.assertThatThrownBy(() -> customerService.findById(notExistId)).isInstanceOf(EmptyResultDataAccessException.class); } @Test - @DisplayName("service의 findAll()을 통해 repository 의 findAll() 을 실행에 반드시 성공한다.") + @DisplayName("service의 findAll()을 통해 repository 의 findAll()실행시켜 성공적으로 값을 얻는다.") void findAll() { //given + List customers = List.of(new Customer(1L, "kk", "kk@naver.com", true)); + when(customerRepsotiory.findAll()).thenReturn(customers); + //when - customerService.findAll(); + List customerList = customerService.findAll(); //then - verify(customerRepsotiory, atLeastOnce()).findAll(); + Assertions.assertThat(customers).isEqualTo(customerList); } @@ -143,14 +154,16 @@ void deleteAll() { } @Test - @DisplayName("service의 getBlackList()를 통해 repository의 getBlackList()을 반드시 한번은 실행한다.") + @DisplayName("service의 getBlackList()를 통해 repository의 getBlackList()을 실행시켜 성공적으로 값을 찾아온다.") void getBlackList() { //given + List blackList = List.of(new Customer(1L, "kk", "kk@naver.com", true)); + //when - customerService.findBlackList(); + when(customerRepsotiory.findBlackList()).thenReturn(blackList); //then - verify(customerRepsotiory, atLeastOnce()).findBlackList(); + Assertions.assertThat(blackList).isEqualTo(customerService.findBlackList()); } } diff --git a/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java index a1df05867d..991a8271e3 100644 --- a/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java +++ b/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java @@ -6,7 +6,6 @@ import com.prgms.vouchermanager.dto.CreateVoucherDto; import com.prgms.vouchermanager.dto.UpdateVoucherDto; import com.prgms.vouchermanager.repository.voucher.VoucherRepository; -import com.prgms.vouchermanager.validation.InputValidation; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -17,7 +16,6 @@ import org.springframework.dao.EmptyResultDataAccessException; import java.util.List; -import java.util.NoSuchElementException; import java.util.Optional; import java.util.UUID; @@ -26,15 +24,10 @@ @ExtendWith(MockitoExtension.class) class VoucherServiceTest { - @Mock - private VoucherRepository voucherRepository; - - @Mock - private InputValidation inputValidation; - @InjectMocks VoucherService voucherService; - + @Mock + private VoucherRepository voucherRepository; @Test @DisplayName("service의 create()를 통해 repository의 save()를 정상 실행하고 값을 받아올 수 있다.") @@ -43,9 +36,9 @@ void createVoucherSuccess() { //given CreateVoucherDto dto = new CreateVoucherDto(99, 2); UUID id = UUID.randomUUID(); - Voucher result = dto.getVoucherType()==1? - new FixedAmountVoucher(id, dto.getValue()): - new PercentDiscountVoucher(id,dto.getValue()); + Voucher result = dto.getVoucherType() == 1 ? + new FixedAmountVoucher(id, dto.getValue()) : + new PercentDiscountVoucher(id, dto.getValue()); when(voucherRepository.save(any(Voucher.class))).thenReturn(result); //when @@ -53,7 +46,6 @@ void createVoucherSuccess() { //then Assertions.assertThat(voucher).isEqualTo(result); - verify(voucherRepository,atLeastOnce()).save(any(Voucher.class)); } @@ -62,33 +54,28 @@ void createVoucherSuccess() { void updateUpdateSuccess() { //given UpdateVoucherDto dto = new UpdateVoucherDto(10, 2); - - when(inputValidation.validVoucherPercent(dto.getValue())).thenReturn(true); - UUID id = UUID.randomUUID(); + //when - voucherService.update(id,dto); + voucherService.update(id, dto); //then verify(voucherRepository, atLeastOnce()).update(any(Voucher.class)); } @Test - @DisplayName("service의 update()를 통해 repository의 save()를 실행에 실패한다.") + @DisplayName("service의 update()에서 바우처타입 검증 실패시 RuntimeException예외가 발생한다.") void updateVoucherFail() { //given - UpdateVoucherDto dto = new UpdateVoucherDto(10000, 2); - - when(inputValidation.validVoucherPercent(dto.getValue())).thenReturn(false); - + UpdateVoucherDto dto = new UpdateVoucherDto(10000, 142124); UUID id = UUID.randomUUID(); + //when //then - Assertions.assertThatThrownBy(() -> voucherService.update((id),dto)). + Assertions.assertThatThrownBy(() -> voucherService.update((id), dto)). isInstanceOf(RuntimeException.class); } - @Test @DisplayName("service의 findById()에 존재하는ID라면 ,repository의 findById()를 통해 정상 반환된다.") void findByIdVoucherSuccess() { @@ -101,28 +88,25 @@ void findByIdVoucherSuccess() { Voucher result = voucherService.findById(id); //then - verify(voucherRepository, atLeastOnce()).findById(id); Assertions.assertThat(id).isEqualTo(result.getId()); } @Test - @DisplayName("service의 findById()에 존재하지 않는 ID를 넘겨주면 ,repository의 findById()가 반드시 한번은 실행되고 예외가 발생한다.") + @DisplayName("service의 findById()에 존재하지 않는 ID를 넘겨주면 , EmptyResultDataAccessException예외가 발생한다.") void findByIdVoucherFail() { //given UUID id = UUID.randomUUID(); when(voucherRepository.findById(id)).thenReturn(Optional.ofNullable(null)); Assertions.assertThatThrownBy(() -> voucherService.findById(id)).isInstanceOf(EmptyResultDataAccessException.class); - verify(voucherRepository, atLeastOnce()).findById(any()); - } @Test - @DisplayName("service의 findAll()을 통해 repository 의 findAll() 실행을 성공한다.") + @DisplayName("service의 findAll()을 성공적으로 실행해서 필요 데이터를 가져올 수 있다.") void findAllSuccess() { //given - List vouchers = List.of(new FixedAmountVoucher(UUID.randomUUID(), 100),new PercentDiscountVoucher(UUID.randomUUID(),22)); + List vouchers = List.of(new FixedAmountVoucher(UUID.randomUUID(), 100), new PercentDiscountVoucher(UUID.randomUUID(), 22)); when(voucherRepository.findAll()).thenReturn(vouchers); //when @@ -130,8 +114,6 @@ void findAllSuccess() { //then Assertions.assertThat(findAllVouchers).isEqualTo(vouchers); - verify(voucherRepository, atLeastOnce()).findAll(); - } @Test @@ -147,7 +129,7 @@ void deleteByIdSuccess() { } @Test - @DisplayName("service의 deleteAll()으로 repository 의 deleteAll() 을 반드시 한번은 실행한다.") + @DisplayName("service의 deleteAll()으로 repository 의 deleteAll()을 실행한다.") void deleteAll() { //given //when diff --git a/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java index 4f6ab97154..bb418de95b 100644 --- a/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java +++ b/src/test/java/com/prgms/vouchermanager/service/wallet/WalletServiceTest.java @@ -12,7 +12,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.dao.DataIntegrityViolationException; -import java.util.NoSuchElementException; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -21,12 +21,10 @@ @ExtendWith(MockitoExtension.class) class WalletServiceTest { - @Mock - private WalletRepository walletRepository; - @InjectMocks WalletService walletService; - + @Mock + private WalletRepository walletRepository; @Test @DisplayName("service의 create()를 통해 repository의 save()를 정상 실행하고, 값을 받아올 수 있다.") @@ -35,19 +33,18 @@ void createWalletSuccess() { //given UUID voucherId = UUID.randomUUID(); CreateWalletDto dto = new CreateWalletDto(1L, voucherId); - when(walletRepository.save(any(Wallet.class))).thenReturn(new Wallet(1L,1L,voucherId)); + when(walletRepository.save(any(Wallet.class))).thenReturn(new Wallet(1L, 1L, voucherId)); //when Wallet wallet = walletService.save(dto); //then Assertions.assertThat(voucherId).isEqualTo(wallet.getVoucherId()); - verify(walletRepository,atLeastOnce()).save(any(Wallet.class)); } @Test - @DisplayName("service의 create()를 통해 존재하지 않는 회원값,UUID쿠폰값을 입력하면 예외를 터트린다. ") + @DisplayName("service의 create()를 통해 존재하지 않는 회원값,UUID쿠폰값을 입력하면 DataIntegrityViolationException예외를 터트린다. ") void createWalletFail() { //given CreateWalletDto dto = new CreateWalletDto(1L, UUID.randomUUID()); @@ -56,27 +53,41 @@ void createWalletFail() { //when //then Assertions.assertThatThrownBy(() -> walletService.save(dto)).isInstanceOf(DataIntegrityViolationException.class); - verify(walletRepository, atLeastOnce()).save(any(Wallet.class)); - } @Test @DisplayName("service의 findByCustomerId()를 통해 repository의 findByCustomerId()가 정상적으로 실행된다.") - void walletfindByCustomerId() { + void findByCustomerIdWalletSuccess() { //given - Long customerId = 1L; - when(walletRepository.findByCustomerId(1L)).thenReturn(any()); + Long customerId = 2L; + List wallets = List.of(new Wallet(1L, customerId, UUID.randomUUID())); + when(walletRepository.findByCustomerId(customerId)).thenReturn(wallets); + + //when + List byCustomerIdWallets = walletService.findByCustomerId(customerId); + + //then + Assertions.assertThat(wallets).isEqualTo(byCustomerIdWallets); + } + + @Test + @DisplayName("service의 findByCustomerId()실행시 존재하지 않는 customerId 입력시 DataIntegrityViolationException 예외를 터트린다. ") + void findByCustomerIdWalletFail() { + + //given + Long customerId = 2L; //when - walletService.findByCustomerId(customerId); + when(walletRepository.findByCustomerId(customerId)).thenThrow(DataIntegrityViolationException.class); //then - verify(walletRepository, atLeastOnce()).findByCustomerId(customerId); + Assertions.assertThatThrownBy(() -> walletService.findByCustomerId(customerId)).isInstanceOf(DataIntegrityViolationException.class); + } @Test @DisplayName("service의 findByVoucherId()를 통해 repository의 findByVoucherId()가 정상적으로 실행된다.") - void walletFindByVoucherIdSuccess() { + void findByVoucherIdWalletSuccess() { //given UUID voucherId = UUID.randomUUID(); @@ -84,11 +95,24 @@ void walletFindByVoucherIdSuccess() { when(walletRepository.findByVoucherId(voucherId)).thenReturn(Optional.of(wallet)); //when - walletService.findByVoucherId(voucherId); + Wallet byVoucherIdWallet = walletService.findByVoucherId(voucherId); //then - verify(walletRepository, atLeastOnce()).findByVoucherId(voucherId); + Assertions.assertThat(wallet).isEqualTo(byVoucherIdWallet); + } + + @Test + @DisplayName("service의 findByVoucherId()에 존재하지 않는 voucherId입력시 DataIntegrityViolationException 예외가 발생한다.") + void findByVoucherIdWalletFail() { + //given + UUID voucherId = UUID.randomUUID(); + + //when + when(walletRepository.findByVoucherId(voucherId)).thenThrow(DataIntegrityViolationException.class); + + //then + Assertions.assertThatThrownBy(() -> walletService.findByVoucherId(voucherId)).isInstanceOf(DataIntegrityViolationException.class); } @Test @@ -97,6 +121,7 @@ void deleteByCustomerId() { //given Long customerId = 1L; + //when walletService.deleteByCustomerId(customerId); From 0d393fcf51acdfff610aaecbc57882bce7e15143 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 21:01:01 +0900 Subject: [PATCH 092/109] =?UTF-8?q?refactor:=20schema=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=86=8D=EC=84=B1=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/schema.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 1f7ea0da32..d9f3200a9a 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -10,7 +10,7 @@ CREATE TABLE vouchers( CREATE TABLE customers( - id BIGINT primary key , + id BIGINT primary key auto_increment, name varchar(10), email varchar(40), black_list bool @@ -18,7 +18,7 @@ CREATE TABLE customers( CREATE TABLE wallets( - id BIGINT primary key , + id BIGINT primary key auto_increment , customer_id BIGINT, voucher_id VARCHAR(36), foreign key (customer_id) REFERENCES customers(id) on delete cascade on update cascade, From cc9bc7d06b07cf37969ad1887d5c6aa82e2356bd Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 21:02:58 +0900 Subject: [PATCH 093/109] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F?= =?UTF-8?q?=20=EC=98=88=EC=99=B8=EC=83=81=ED=99=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/service/customer/CustomerService.java | 7 ++++--- .../vouchermanager/service/voucher/VoucherService.java | 8 +------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java index f605a6de43..c04f4d378c 100644 --- a/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java +++ b/src/main/java/com/prgms/vouchermanager/service/customer/CustomerService.java @@ -11,11 +11,12 @@ import java.util.List; -import static com.prgms.vouchermanager.exception.ExceptionType.*; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_CUSTOMER_ID; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_CUSTOMER_INFO; @Service public class CustomerService { - + private final CustomerRepository customerRepository; private final InputValidation inputValidation; @@ -50,7 +51,7 @@ public void update(Long id, UpdateCustomerDto dto) { blackList = true; } customerRepository.update(new Customer(id, dto.getName(), dto.getEmail(), blackList)); - } + } else throw new RuntimeException(INVALID_CUSTOMER_INFO.getMessage()); } @Transactional(readOnly = true) diff --git a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java index af43d139a1..e0a49e834c 100644 --- a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java +++ b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java @@ -7,7 +7,6 @@ import com.prgms.vouchermanager.dto.CreateVoucherDto; import com.prgms.vouchermanager.dto.UpdateVoucherDto; import com.prgms.vouchermanager.repository.voucher.VoucherRepository; -import com.prgms.vouchermanager.validation.InputValidation; import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Service; @@ -21,11 +20,9 @@ @Service public class VoucherService { - private final InputValidation inputValidation; private final VoucherRepository voucherRepository; - public VoucherService(InputValidation inputValidation, VoucherRepository voucherRepository) { - this.inputValidation = inputValidation; + public VoucherService(VoucherRepository voucherRepository) { this.voucherRepository = voucherRepository; } @@ -55,9 +52,6 @@ public void update(UUID id, UpdateVoucherDto dto) { if (dto.getVoucherType() == 1) { voucher = new FixedAmountVoucher(id, dto.getValue()); } else if (dto.getVoucherType() == 2) { - if (!inputValidation.validVoucherPercent(dto.getValue())) { - throw new RuntimeException(INVALID_VOUCHER_PERCENT.getMessage()); - } voucher = new PercentDiscountVoucher(id, dto.getValue()); } else throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); From a24a411904466e7c288e3b7a288fb35e5691372f Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sat, 28 Oct 2023 21:04:08 +0900 Subject: [PATCH 094/109] =?UTF-8?q?refactor:=20=EB=B0=94=EC=9A=B0=EC=B2=98?= =?UTF-8?q?=20=EA=B0=92=20=EA=B2=80=EC=A6=9D=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/contorller/voucher/VoucherController.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java index 0adb47b457..201b653fb5 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/VoucherController.java @@ -41,7 +41,7 @@ public void create() { int voucherType = consoleInput.inputVoucherType(); consoleOutput.printVoucherAmount(); long value = consoleInput.inputVoucherValue(); - if (voucherType==2&&!inputValidation.validVoucherPercent(value)) { + if (voucherType == 2 && !inputValidation.validVoucherPercent(value)) { throw new RuntimeException(INVALID_VOUCHER_PERCENT.getMessage()); } Voucher voucher = voucherService.create(new CreateVoucherDto(value, voucherType)); @@ -61,6 +61,9 @@ public void update() { int voucherType = consoleInput.inputVoucherType(); consoleOutput.printVoucherAmount(); long value = consoleInput.inputVoucherValue(); + if (voucherType == 2 && !inputValidation.validVoucherPercent(value)) { + throw new RuntimeException(INVALID_VOUCHER_PERCENT.getMessage()); + } voucherService.update(id, new UpdateVoucherDto(value, voucherType)); } catch (RuntimeException e) { From 3fa46ed4986d5946ed98c8f204006879158c3bcd Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Tue, 31 Oct 2023 09:29:04 +0900 Subject: [PATCH 095/109] =?UTF-8?q?refactor:=203=ED=95=AD=20=EC=97=B0?= =?UTF-8?q?=EC=82=B0=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vouchermanager/util/file/FileManager.java | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java b/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java index 38c5b4fb6f..8d64e72d75 100644 --- a/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java +++ b/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java @@ -5,7 +5,6 @@ import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; import com.prgms.vouchermanager.domain.voucher.Voucher; import com.prgms.vouchermanager.domain.voucher.VoucherType; -import com.prgms.vouchermanager.exception.ExceptionType; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -16,15 +15,14 @@ import java.util.concurrent.ConcurrentHashMap; import static com.prgms.vouchermanager.domain.voucher.VoucherType.valueOf; -import static com.prgms.vouchermanager.exception.ExceptionType.*; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_READ_FILE; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_WRITE_FILE; /** - * * 1. 바우처 FIle을 Repo에 return하기 * 2. Repo를 바우처 File에 저장하기 - * + *

* 3. BlackList File을 Repo에 return하기 - * */ @Component public class FileManager { @@ -35,16 +33,16 @@ public class FileManager { public FileManager( @Value("${file.path.voucher}") String voucherListPath, - @Value("${file.path.blacklist}") String blackListPath ) { + @Value("${file.path.blacklist}") String blackListPath) { this.voucherListPath = voucherListPath; this.blackListPath = blackListPath; } public Map readVoucherCsv() { - Map voucherMap = new ConcurrentHashMap<>(); + Map voucherMap = new ConcurrentHashMap<>(); - try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(voucherListPath)))) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(voucherListPath)))) { String line = ""; br.readLine(); while ((line = br.readLine()) != null) { @@ -53,9 +51,8 @@ public Map readVoucherCsv() { UUID id = UUID.fromString(split[0]); Long value = Long.parseLong(split[1]); VoucherType voucherType = valueOf(split[2]); - if (voucherType == VoucherType.FIXED_AMOUNT) { - voucherMap.put(id, new FixedAmountVoucher(id,value)); + voucherMap.put(id, new FixedAmountVoucher(id, value)); } else if (voucherType == VoucherType.PERCENT_DISCOUNT) { voucherMap.put(id, new PercentDiscountVoucher(id, value)); } @@ -69,9 +66,9 @@ public Map readVoucherCsv() { public Map readBlackListCsv() { - Map customerMap = new ConcurrentHashMap<>(); + Map customerMap = new ConcurrentHashMap<>(); - try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(blackListPath)))) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(blackListPath)))) { String line = ""; br.readLine(); while ((line = br.readLine()) != null) { @@ -80,9 +77,9 @@ public Map readBlackListCsv() { Long id = Long.parseLong(split[0]); String name = split[1]; String email = split[2]; - boolean blackList = split[3].equals("1") ? true : false; + boolean blackList = split[3].equals("1"); - customerMap.put(id, new Customer(id, name, email,blackList)); + customerMap.put(id, new Customer(id, name, email, blackList)); } } catch (IOException e) { throw new RuntimeException(INVALID_READ_FILE.getMessage()); @@ -90,12 +87,12 @@ public Map readBlackListCsv() { return customerMap; } - public void saveVoucherFile(MapvoucherMap) { + public void saveVoucherFile(Map voucherMap) { try (BufferedWriter bw = new BufferedWriter(new FileWriter(voucherListPath))) { bw.write("id, discount value, voucher type"); bw.newLine(); for (Voucher voucher : new ArrayList<>(voucherMap.values())) { - bw.write(voucher.getId() + ", " + voucher.getDiscountValue()+", "+voucher.getVoucherType()); + bw.write(voucher.getId() + ", " + voucher.getDiscountValue() + ", " + voucher.getVoucherType()); bw.newLine(); } } catch (IOException e) { From e9f7ebfab2865dcaf12534770e175a46a99cae7a Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 12:05:19 +0900 Subject: [PATCH 096/109] =?UTF-8?q?refactor:=20voucher=20=EB=82=B4=20creat?= =?UTF-8?q?ed=5Fat=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/voucher/FixedAmountVoucher.java | 18 ++++++++++++++---- .../domain/voucher/PercentDiscountVoucher.java | 14 +++++++++++--- .../vouchermanager/domain/voucher/Voucher.java | 3 +++ .../vouchermanager/dto/CreateVoucherDto.java | 6 +++--- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/domain/voucher/FixedAmountVoucher.java b/src/main/java/com/prgms/vouchermanager/domain/voucher/FixedAmountVoucher.java index 9d44867562..3b76eba4b8 100644 --- a/src/main/java/com/prgms/vouchermanager/domain/voucher/FixedAmountVoucher.java +++ b/src/main/java/com/prgms/vouchermanager/domain/voucher/FixedAmountVoucher.java @@ -1,18 +1,22 @@ package com.prgms.vouchermanager.domain.voucher; +import java.time.LocalDateTime; import java.util.UUID; -public class FixedAmountVoucher implements Voucher{ +public class FixedAmountVoucher implements Voucher { private final UUID id; private final long amount; - private final VoucherType type ; + private final VoucherType type; - public FixedAmountVoucher(UUID id, long amount) { + private LocalDateTime createdAt; + + public FixedAmountVoucher(UUID id, long amount, LocalDateTime createdAt) { this.id = id; this.amount = amount; + this.createdAt = createdAt; type = VoucherType.FIXED_AMOUNT; } @@ -32,12 +36,18 @@ public VoucherType getVoucherType() { return VoucherType.FIXED_AMOUNT; } + @Override + public LocalDateTime getCreatedAt() { + return createdAt; + } + @Override public String toString() { - return "{" + + return "FixedAmountVoucher{" + "id=" + id + ", amount=" + amount + ", type=" + type + + ", createdAt=" + createdAt + '}'; } } diff --git a/src/main/java/com/prgms/vouchermanager/domain/voucher/PercentDiscountVoucher.java b/src/main/java/com/prgms/vouchermanager/domain/voucher/PercentDiscountVoucher.java index d8bf100cfa..2f088c9fac 100644 --- a/src/main/java/com/prgms/vouchermanager/domain/voucher/PercentDiscountVoucher.java +++ b/src/main/java/com/prgms/vouchermanager/domain/voucher/PercentDiscountVoucher.java @@ -1,5 +1,6 @@ package com.prgms.vouchermanager.domain.voucher; +import java.time.LocalDateTime; import java.util.UUID; public class PercentDiscountVoucher implements Voucher { @@ -10,9 +11,12 @@ public class PercentDiscountVoucher implements Voucher { private final VoucherType type; - public PercentDiscountVoucher(UUID id, long percent) { + private LocalDateTime createdAt; + + public PercentDiscountVoucher(UUID id, long percent, LocalDateTime createdAt) { this.id = id; this.percent = percent; + this.createdAt = createdAt; type = VoucherType.PERCENT_DISCOUNT; } @@ -31,14 +35,18 @@ public VoucherType getVoucherType() { return VoucherType.PERCENT_DISCOUNT; } - + @Override + public LocalDateTime getCreatedAt() { + return createdAt; + } @Override public String toString() { - return "{" + + return "PercentDiscountVoucher{" + "id=" + id + ", percent=" + percent + ", type=" + type + + ", createdAt=" + createdAt + '}'; } } diff --git a/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java b/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java index 32889a7c62..391125f589 100644 --- a/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java +++ b/src/main/java/com/prgms/vouchermanager/domain/voucher/Voucher.java @@ -1,5 +1,6 @@ package com.prgms.vouchermanager.domain.voucher; +import java.time.LocalDateTime; import java.util.UUID; public interface Voucher { @@ -9,4 +10,6 @@ public interface Voucher { VoucherType getVoucherType(); + LocalDateTime getCreatedAt(); + } diff --git a/src/main/java/com/prgms/vouchermanager/dto/CreateVoucherDto.java b/src/main/java/com/prgms/vouchermanager/dto/CreateVoucherDto.java index 238c95f82a..9d77dc4153 100644 --- a/src/main/java/com/prgms/vouchermanager/dto/CreateVoucherDto.java +++ b/src/main/java/com/prgms/vouchermanager/dto/CreateVoucherDto.java @@ -3,11 +3,11 @@ public class CreateVoucherDto { private final long value; - private final int VoucherType; + private final int voucherType; public CreateVoucherDto(long value, int voucherType) { this.value = value; - this.VoucherType = voucherType; + this.voucherType = voucherType; } public long getValue() { @@ -15,6 +15,6 @@ public long getValue() { } public int getVoucherType() { - return VoucherType; + return voucherType; } } From b45172ce00a8961b74fc15ab54c8527528bdc4ca Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 12:06:55 +0900 Subject: [PATCH 097/109] =?UTF-8?q?refactor:=20voucherRepository=20?= =?UTF-8?q?=EB=82=B4=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/FileVoucherRepository.java | 18 ++++++++ .../voucher/JdbcVoucherRepository.java | 43 ++++++++++++++++--- .../voucher/MemoryVoucherRepository.java | 22 +++++++++- .../repository/voucher/VoucherQueryType.java | 4 +- .../repository/voucher/VoucherRepository.java | 7 +++ 5 files changed, 84 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java index f1b5dd87e5..5c31242c93 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/FileVoucherRepository.java @@ -2,12 +2,15 @@ import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.voucher.VoucherType; import com.prgms.vouchermanager.util.file.FileManager; import jakarta.annotation.PreDestroy; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; +import java.time.LocalDateTime; import java.util.*; +import java.util.stream.Collectors; @Repository @Profile("file") @@ -57,6 +60,21 @@ public void deleteAll() { vouchers.clear(); } + @Override + public List findByDate(LocalDateTime startTime, LocalDateTime endTime) { + return vouchers.values().stream() + .filter(voucher -> voucher.getCreatedAt().isAfter(startTime) && voucher.getCreatedAt().isBefore(endTime)) + .collect(Collectors.toUnmodifiableList()); + } + + @Override + public List findByType(VoucherType type) { + return vouchers.values().stream() + .filter(voucher -> voucher.getVoucherType().equals(VoucherType.FIXED_AMOUNT)) + .collect(Collectors.toUnmodifiableList()); + } + + @PreDestroy public void saveRepository() { fileManager.saveVoucherFile(vouchers); diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java index d0b8ca4438..1d2c4cbf5d 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/JdbcVoucherRepository.java @@ -6,6 +6,7 @@ import com.prgms.vouchermanager.domain.voucher.VoucherType; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Profile; +import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; @@ -14,10 +15,13 @@ import org.springframework.stereotype.Repository; import javax.sql.DataSource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Optional; import java.util.UUID; +import static com.prgms.vouchermanager.exception.ExceptionType.DUPLICATED_KEY; import static com.prgms.vouchermanager.repository.voucher.VoucherQueryType.*; @@ -39,8 +43,11 @@ public Voucher save(Voucher voucher) { .addValue("discount_value", voucher.getDiscountValue()) .addValue("type", voucher.getVoucherType().name()); - - template.update(INSERT.getQuery(), param); + try { + template.update(INSERT.getQuery(), param); + } catch (DuplicateKeyException e) { + throw new DuplicateKeyException(DUPLICATED_KEY.getMessage()); + } return voucher; @@ -65,7 +72,7 @@ public List findAll() { } @Override - public void update(Voucher voucher) { //항상 존재하는 id에만 실행 가능하도록 전제가 있다. + public void update(Voucher voucher) { SqlParameterSource param = new MapSqlParameterSource() .addValue("id", voucher.getId().toString()) @@ -89,16 +96,38 @@ public void deleteAll() { template.update(DELETE_ALL.getQuery(), new MapSqlParameterSource()); } + @Override + public List findByDate(LocalDateTime startTime, LocalDateTime endTime) { + { + SqlParameterSource param = new MapSqlParameterSource() + .addValue("start_time", startTime) + .addValue("end_time", endTime); + + return template.query(SELECT_BETWEEN_DATE.getQuery(), param, voucherRowMapper()); + } + } + + @Override + public List findByType(VoucherType type) { + { + SqlParameterSource param = new MapSqlParameterSource() + .addValue("type", type.name()); - private RowMapper voucherRowMapper() { + return template.query(SELECT_BY_TYPE.getQuery(), param, voucherRowMapper()); + } + } + + + private RowMapper voucherRowMapper() { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); return (rs, count) -> { UUID id = UUID.fromString(rs.getString("id")); VoucherType type = VoucherType.valueOf(rs.getString("type")); Long discountValue = rs.getLong("discount_value"); - + LocalDateTime createdAt = LocalDateTime.parse(rs.getString("created_at"), formatter); return type == VoucherType.FIXED_AMOUNT ? - new FixedAmountVoucher(id, discountValue) : - new PercentDiscountVoucher(id, discountValue); + new FixedAmountVoucher(id, discountValue, createdAt) : + new PercentDiscountVoucher(id, discountValue, createdAt); }; } diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java index 946ab0c170..41f9f1b2d3 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/MemoryVoucherRepository.java @@ -1,17 +1,20 @@ package com.prgms.vouchermanager.repository.voucher; import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.voucher.VoucherType; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Repository; +import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; @Repository @Profile("memory") -public class MemoryVoucherRepository implements VoucherRepository{ +public class MemoryVoucherRepository implements VoucherRepository { - private final Mapvouchers; + private final Map vouchers; public MemoryVoucherRepository() { this.vouchers = new ConcurrentHashMap<>(); @@ -47,6 +50,21 @@ public void deleteAll() { vouchers.clear(); } + + @Override + public List findByType(VoucherType type) { + return vouchers.values().stream() + .filter(voucher -> voucher.getVoucherType().equals(VoucherType.FIXED_AMOUNT)) + .collect(Collectors.toUnmodifiableList()); + } + + @Override + public List findByDate(LocalDateTime startTime, LocalDateTime endTime) { + return vouchers.values().stream() + .filter(voucher -> voucher.getCreatedAt().isAfter(startTime) && voucher.getCreatedAt().isBefore(endTime)) + .collect(Collectors.toUnmodifiableList()); + } + @Override public void deleteById(UUID id) { if (vouchers.containsKey(id)) { diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherQueryType.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherQueryType.java index 68ed6d496f..4c60a2f7dc 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherQueryType.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherQueryType.java @@ -3,11 +3,13 @@ public enum VoucherQueryType { SELECT_BY_ID("select * from vouchers WHERE id = :id"), + SELECT_BY_TYPE("select * from vouchers WHERE type = :type "), + SELECT_BETWEEN_DATE("select * from vouchers where created_at >= :start_time and created_at <= :end_time"), SELECT_ALL("select * from vouchers"), INSERT("insert into vouchers (id, discount_value, type) " + "values (:id, :discount_value, :type)"), - UPDATE("update vouchers set id = :id , discount_value = :discount_value, type = :type "+ + UPDATE("update vouchers set id = :id , discount_value = :discount_value, type = :type " + "where id = :id"), DELETE_BY_ID("delete from vouchers where id = :id"), DELETE_ALL("delete from vouchers"); diff --git a/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java index b8656f1d3b..accd0bf8a5 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/voucher/VoucherRepository.java @@ -1,7 +1,9 @@ package com.prgms.vouchermanager.repository.voucher; import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.voucher.VoucherType; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -9,6 +11,7 @@ public interface VoucherRepository { Voucher save(Voucher voucher); + void update(Voucher voucher); Optional findById(UUID id); @@ -18,4 +21,8 @@ public interface VoucherRepository { void deleteById(UUID id); void deleteAll(); + + List findByDate(LocalDateTime startTime, LocalDateTime endTime); + + List findByType(VoucherType type); } From 1c7250dc04bd6981ce7c385e5d1c637f261ea124 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 12:07:24 +0900 Subject: [PATCH 098/109] =?UTF-8?q?refactor:=20WalletRepository=20?= =?UTF-8?q?=EB=82=B4=20=ED=95=84=EC=9A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/wallet/JdbcWalletRepository.java | 8 +++++--- .../vouchermanager/repository/wallet/WalletQueryType.java | 3 ++- .../repository/wallet/WalletRepository.java | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java index 7400685c68..92542cdbe9 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/JdbcWalletRepository.java @@ -5,19 +5,16 @@ import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; - import java.util.List; import java.util.Optional; import java.util.UUID; -import static com.prgms.vouchermanager.repository.customer.CustomerQueryType.INSERT; import static com.prgms.vouchermanager.repository.wallet.WalletQueryType.*; @@ -71,6 +68,11 @@ public Optional findByVoucherId(UUID voucherId) { } } + @Override + public List findAll() { + return template.query(SELECT_ALL.getQuery(), walletRowMapper()); + } + @Transactional @Override public void deleteByCustomerId(Long customerId) { diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java index 15201cba9c..b2464fbed1 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletQueryType.java @@ -8,7 +8,8 @@ public enum WalletQueryType { SELECT_BY_VOUCHER_ID("select * from wallets where voucher_id = :voucher_id "), - DELETE_BY_CUSTOMER_ID("delete from wallets where customer_id = :customer_id"); + DELETE_BY_CUSTOMER_ID("delete from wallets where customer_id = :customer_id"), + SELECT_ALL("select * from wallets"); private final String query; diff --git a/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletRepository.java b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletRepository.java index e3eb295366..9698d9a7b6 100644 --- a/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletRepository.java +++ b/src/main/java/com/prgms/vouchermanager/repository/wallet/WalletRepository.java @@ -15,4 +15,6 @@ public interface WalletRepository { void deleteByCustomerId(Long customerId); Optional findByVoucherId(UUID voucherId); + + List findAll(); } From c4815ba71d237dda491ddd79b9122505ba2ecdb8 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 12:10:05 +0900 Subject: [PATCH 099/109] =?UTF-8?q?refactor:=20service=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EC=97=90=20=ED=95=84=EC=9A=94=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/voucher/VoucherService.java | 28 +++++++++++-------- .../service/wallet/WalletService.java | 14 ++++++---- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java index e0a49e834c..dbf257330e 100644 --- a/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java +++ b/src/main/java/com/prgms/vouchermanager/service/voucher/VoucherService.java @@ -4,18 +4,20 @@ import com.prgms.vouchermanager.domain.voucher.FixedAmountVoucher; import com.prgms.vouchermanager.domain.voucher.PercentDiscountVoucher; import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.voucher.VoucherType; import com.prgms.vouchermanager.dto.CreateVoucherDto; import com.prgms.vouchermanager.dto.UpdateVoucherDto; import com.prgms.vouchermanager.repository.voucher.VoucherRepository; -import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; import java.util.UUID; -import static com.prgms.vouchermanager.exception.ExceptionType.*; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_ID; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_INFO; @Service public class VoucherService { @@ -32,16 +34,12 @@ public Voucher create(CreateVoucherDto dto) { Voucher voucher = null; if (dto.getVoucherType() == 1) { - voucher = new FixedAmountVoucher(UUID.randomUUID(), dto.getValue()); + voucher = new FixedAmountVoucher(UUID.randomUUID(), dto.getValue(), null); } else if (dto.getVoucherType() == 2) { - voucher = new PercentDiscountVoucher(UUID.randomUUID(), dto.getValue()); + voucher = new PercentDiscountVoucher(UUID.randomUUID(), dto.getValue(), null); } else throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); - try { - return voucherRepository.save(voucher); - } catch (DuplicateKeyException e) { - throw new DuplicateKeyException(DUPLICATED_KEY.getMessage()); - } + return voucherRepository.save(voucher); } @Transactional @@ -50,9 +48,9 @@ public void update(UUID id, UpdateVoucherDto dto) { Voucher voucher = null; if (dto.getVoucherType() == 1) { - voucher = new FixedAmountVoucher(id, dto.getValue()); + voucher = new FixedAmountVoucher(id, dto.getValue(), null); } else if (dto.getVoucherType() == 2) { - voucher = new PercentDiscountVoucher(id, dto.getValue()); + voucher = new PercentDiscountVoucher(id, dto.getValue(), null); } else throw new RuntimeException(INVALID_VOUCHER_INFO.getMessage()); voucherRepository.update(voucher); @@ -82,5 +80,13 @@ public void deleteById(UUID id) { public void deleteAll() { voucherRepository.deleteAll(); } + + public List findByDate(LocalDateTime startTime, LocalDateTime endTime) { + return voucherRepository.findByDate(startTime, endTime); + } + + public List findByType(VoucherType type) { + return voucherRepository.findByType(type); + } } diff --git a/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java b/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java index fb749421f3..4714f6a312 100644 --- a/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java +++ b/src/main/java/com/prgms/vouchermanager/service/wallet/WalletService.java @@ -26,7 +26,7 @@ public WalletService(WalletRepository walletRepository) { public Wallet save(CreateWalletDto dto) { try { - return walletRepository.save(new Wallet(null,dto.getCustomerId(), dto.getVoucherId())); + return walletRepository.save(new Wallet(null, dto.getCustomerId(), dto.getVoucherId())); } catch (DataIntegrityViolationException e) { throw new DataIntegrityViolationException(INVALID_WALLET_INFO.getMessage()); } @@ -37,8 +37,8 @@ public void deleteByCustomerId(Long customerId) { try { walletRepository.deleteByCustomerId(customerId); - } catch (EmptyResultDataAccessException e){ - throw new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(),0); + } catch (EmptyResultDataAccessException e) { + throw new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(), 0); } } @@ -48,7 +48,7 @@ public List findByCustomerId(Long customerId) { try { return walletRepository.findByCustomerId(customerId); } catch (EmptyResultDataAccessException e) { - throw new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(),0); + throw new EmptyResultDataAccessException(INVALID_CUSTOMER_ID.getMessage(), 0); } } @@ -56,6 +56,10 @@ public List findByCustomerId(Long customerId) { public Wallet findByVoucherId(UUID voucherId) { - return walletRepository.findByVoucherId(voucherId).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_VOUCHER_ID.getMessage(),0)); + return walletRepository.findByVoucherId(voucherId).orElseThrow(() -> new EmptyResultDataAccessException(INVALID_VOUCHER_ID.getMessage(), 0)); + } + + public List findAll() { + return walletRepository.findAll(); } } From a9355d422685e361e669fddf519049126a4f9fa4 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 12:10:18 +0900 Subject: [PATCH 100/109] =?UTF-8?q?refactor:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=82=B4=20created=5Fat=20=EC=8B=9C=EA=B0=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prgms/vouchermanager/util/file/FileManager.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java b/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java index 8d64e72d75..3fec51bef5 100644 --- a/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java +++ b/src/main/java/com/prgms/vouchermanager/util/file/FileManager.java @@ -9,6 +9,8 @@ import org.springframework.stereotype.Component; import java.io.*; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Map; import java.util.UUID; @@ -42,6 +44,8 @@ public FileManager( public Map readVoucherCsv() { Map voucherMap = new ConcurrentHashMap<>(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(voucherListPath)))) { String line = ""; br.readLine(); @@ -51,10 +55,11 @@ public Map readVoucherCsv() { UUID id = UUID.fromString(split[0]); Long value = Long.parseLong(split[1]); VoucherType voucherType = valueOf(split[2]); + LocalDateTime createdAt = LocalDateTime.now(); if (voucherType == VoucherType.FIXED_AMOUNT) { - voucherMap.put(id, new FixedAmountVoucher(id, value)); + voucherMap.put(id, new FixedAmountVoucher(id, value, createdAt)); } else if (voucherType == VoucherType.PERCENT_DISCOUNT) { - voucherMap.put(id, new PercentDiscountVoucher(id, value)); + voucherMap.put(id, new PercentDiscountVoucher(id, value, createdAt)); } } } catch (IOException e) { @@ -101,3 +106,4 @@ public void saveVoucherFile(Map voucherMap) { } } + From a73ba65994b2de91e1bb97cae5ca6a701d8027d2 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 13:05:47 +0900 Subject: [PATCH 101/109] =?UTF-8?q?feat:=20WebVoucherController,=20ApiVouc?= =?UTF-8?q?herController=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/ApiVoucherController.java | 96 +++++++++++++++++++ .../voucher/WebVoucherController.java | 91 ++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/voucher/ApiVoucherController.java create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/voucher/WebVoucherController.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/ApiVoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/ApiVoucherController.java new file mode 100644 index 0000000000..0673b64e11 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/ApiVoucherController.java @@ -0,0 +1,96 @@ +package com.prgms.vouchermanager.contorller.voucher; + +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.domain.voucher.VoucherType; +import com.prgms.vouchermanager.dto.CreateVoucherDto; +import com.prgms.vouchermanager.dto.UpdateVoucherDto; +import com.prgms.vouchermanager.service.voucher.VoucherService; +import lombok.RequiredArgsConstructor; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDateTime; +import java.util.InputMismatchException; +import java.util.List; +import java.util.UUID; + +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_INFO; +import static com.prgms.vouchermanager.exception.ExceptionType.INVALID_VOUCHER_PERCENT; + +@RestController +@RequestMapping("/api/vouchers") +@RequiredArgsConstructor +public class ApiVoucherController { + + private final VoucherService voucherService; + + @GetMapping("/{id}") + ResponseEntity findById(@PathVariable String id) { + return ResponseEntity.ok(voucherService.findById(UUID.fromString(id))); + } + + @GetMapping("/date") + ResponseEntity> findByDate(@RequestParam String startTime, @RequestParam String endTime) { + LocalDateTime startDate = LocalDateTime.parse(startTime); + LocalDateTime endDate = LocalDateTime.parse(endTime); + return ResponseEntity.ok(voucherService.findByDate(startDate, endDate)); + } + + @GetMapping("/type") + ResponseEntity> findByType(@RequestParam String type) { + VoucherType voucherType = VoucherType.valueOf(type); + return ResponseEntity.ok(voucherService.findByType(voucherType)); + } + + @GetMapping("") + ResponseEntity> findAll() { + return ResponseEntity.ok(voucherService.findAll()); + } + + @PostMapping("/create") + ResponseEntity create(@RequestBody CreateVoucherDto dto) { + if (dto.getVoucherType() == 2 && dto.getValue() > 100) { + throw new InputMismatchException(INVALID_VOUCHER_PERCENT.getMessage()); + } + return ResponseEntity + .status(HttpStatus.CREATED) + .body(voucherService.create(dto)); + } + + + @PutMapping("/{id}/edit") + ResponseEntity update(@PathVariable String id, @RequestBody UpdateVoucherDto dto) { + voucherService.update(UUID.fromString(id), dto); + return ResponseEntity.ok().build(); + } + + @DeleteMapping("/{id}") + ResponseEntity delete(@PathVariable String id) { + voucherService.deleteById(UUID.fromString(id)); + return ResponseEntity.ok().build(); + } + + @ExceptionHandler + String ArgumentTypeMistMatch(HttpMessageNotReadableException e) { + return INVALID_VOUCHER_INFO.getMessage(); + } + + @ExceptionHandler + String DuplicatedId(DuplicateKeyException e) { + return e.getMessage(); + } + + @ExceptionHandler + String ExceedVoucherPercent(InputMismatchException e) { + return e.getMessage(); + } + + @ExceptionHandler + String EmptyResult(EmptyResultDataAccessException e) { + return e.getMessage(); + } +} diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/WebVoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/WebVoucherController.java new file mode 100644 index 0000000000..a318f4b7a9 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/WebVoucherController.java @@ -0,0 +1,91 @@ +package com.prgms.vouchermanager.contorller.voucher; + +import com.prgms.vouchermanager.domain.voucher.Voucher; +import com.prgms.vouchermanager.dto.CreateVoucherDto; +import com.prgms.vouchermanager.dto.UpdateVoucherDto; +import com.prgms.vouchermanager.service.voucher.VoucherService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import java.util.List; +import java.util.UUID; + + +@Controller +@Slf4j +@RequestMapping("/admin/vouchers") +@RequiredArgsConstructor +public class WebVoucherController { + + private final VoucherService voucherService; + + @GetMapping("/{id}") + String findById(@PathVariable String id, Model model) { + Voucher voucher = voucherService.findById(UUID.fromString(id)); + model.addAttribute("voucher", voucher); + + return "voucher_one.html"; + } + + @GetMapping("") + String findAll(Model model) { + List vouchers = voucherService.findAll(); + model.addAttribute("vouchers", vouchers); + + return "voucher_list.html"; + } + + @GetMapping("/create") + String getCreateForm() { + return "voucher_create.html"; + } + + @PostMapping("/create") + String create(@ModelAttribute CreateVoucherDto dto, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) { + if (bindingResult.hasErrors()) { + model.addAttribute("code", "바우처 입력 정보가 잘못되었습니다."); + return "voucher_exception.html"; + } + if (dto.getVoucherType() == 2 && dto.getValue() > 100) { + model.addAttribute("code", "percent는 100%를 넘어갈 수 없습니다."); + return "voucher_exception.html"; + } + Voucher voucher = voucherService.create(dto); + redirectAttributes.addAttribute("id", voucher.getId()); + return "redirect:/admin/vouchers/{id}"; + } + + @GetMapping("/{id}/edit") + String getUpdateForm(@PathVariable String id, Model model) { + Voucher voucher = voucherService.findById(UUID.fromString(id)); + model.addAttribute("voucher", voucher); + return "voucher_edit.html"; + } + + @PutMapping("/{id}/edit") + String update(@PathVariable String id, @ModelAttribute UpdateVoucherDto dto, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) { + if (bindingResult.hasErrors()) { + model.addAttribute("code", "바우처 입력 정보가 잘못되었습니다."); + return "voucher_exception.html"; + } + if (dto.getVoucherType() == 2 && dto.getValue() > 100) { + model.addAttribute("code", "percent는 100%를 넘어갈 수 없습니다."); + return "voucher_exception.html"; + } + voucherService.update(UUID.fromString(id), dto); + redirectAttributes.addAttribute("id", id); + return "redirect:/admin/vouchers/{id}"; + + } + + @DeleteMapping("/{id}") + String delete(@PathVariable String id) { + voucherService.deleteById(UUID.fromString(id)); + return "redirect:/admin/vouchers"; + } +} From a237e1e33d85e68b9cd44fcc44fcb00b90181bae Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 13:06:20 +0900 Subject: [PATCH 102/109] =?UTF-8?q?feat:=20WebWalletController=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wallet/WebWalletController.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/main/java/com/prgms/vouchermanager/contorller/wallet/WebWalletController.java diff --git a/src/main/java/com/prgms/vouchermanager/contorller/wallet/WebWalletController.java b/src/main/java/com/prgms/vouchermanager/contorller/wallet/WebWalletController.java new file mode 100644 index 0000000000..09931c3706 --- /dev/null +++ b/src/main/java/com/prgms/vouchermanager/contorller/wallet/WebWalletController.java @@ -0,0 +1,78 @@ +package com.prgms.vouchermanager.contorller.wallet; + +import com.prgms.vouchermanager.domain.wallet.Wallet; +import com.prgms.vouchermanager.dto.CreateWalletDto; +import com.prgms.vouchermanager.service.wallet.WalletService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import java.util.List; +import java.util.UUID; + + +@Controller +@Slf4j +@RequestMapping("/admin/wallets") +@RequiredArgsConstructor +public class WebWalletController { + + private final WalletService walletService; + + @GetMapping("/customer/{customerId}") + String findByCustomerId(@PathVariable Long customerId, Model model) { + List wallets = walletService.findByCustomerId(customerId); + model.addAttribute("wallets", wallets); + return "wallet_list.html"; + } + + @GetMapping("/voucher/{voucherId}") + String findByVoucherId(@PathVariable UUID voucherId, Model model) { + Wallet wallet = walletService.findByVoucherId(voucherId); + model.addAttribute("wallets", wallet); + return "wallet_list.html"; + } + + @GetMapping("") + String findAll(Model model) { + List wallets = walletService.findAll(); + model.addAttribute("wallets", wallets); + + return "wallet_list.html"; + } + + @GetMapping("/create") + String getCreateForm() { + return "wallet_create.html"; + } + + @PostMapping("/create") + String create(@ModelAttribute CreateWalletDto dto, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) { + if (bindingResult.hasErrors()) { + model.addAttribute("code", "입력값 타입 형태가 잘못되었습니다."); + return "wallet_exception.html"; + } + Wallet wallet = walletService.save(dto); + redirectAttributes.addAttribute("id", wallet.getId()); + return "redirect:/admin/wallets"; + } + + @DeleteMapping("/{id}") + String deleteByCustomerId(@PathVariable Long id) { + walletService.deleteByCustomerId(id); + return "redirect:/admin/wallets"; + } + + @ExceptionHandler + String NotExistInfo(DataIntegrityViolationException e1, EmptyResultDataAccessException e2, Model model) { + model.addAttribute("code", "회원번호 또는 바우처번호가 존재하지 않습니다."); + return "wallet_exception.html"; + } + +} From 7d59d19b52774c798dc96e6b1f82bcbec083ff1d Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 13:07:01 +0900 Subject: [PATCH 103/109] =?UTF-8?q?refactor:=20profile=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VouchermanagerApplication.java | 25 +++++++++++++++++-- src/main/resources/application.yaml | 14 +++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java b/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java index f9da90cb50..e653e1e01a 100644 --- a/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java +++ b/src/main/java/com/prgms/vouchermanager/VouchermanagerApplication.java @@ -3,17 +3,38 @@ import com.prgms.vouchermanager.contorller.front.FrontController; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; @SpringBootApplication public class VouchermanagerApplication { + private static ApplicationContext ac; + + + public VouchermanagerApplication(ConfigurableApplicationContext applicationContext) { + this.ac = applicationContext; + } + public static void main(String[] args) { + SpringApplication.run(VouchermanagerApplication.class, args); + } + + @Profile(value = "tomcat") + @Bean + public ServletWebServerFactory servletTomcatServerContainer() { + return new TomcatServletWebServerFactory(); + } - ApplicationContext ac = SpringApplication.run(VouchermanagerApplication.class, args); + @Profile("console") + @Bean + public void init() { FrontController frontController = ac.getBean(FrontController.class); frontController.run(); - } } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 59fb433071..42bb539b35 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,18 +1,22 @@ spring: profiles: - active: jdbc + active: jdbc , tomcat + datasource: driverClassName: com.mysql.cj.jdbc.Driver - url : jdbc:mysql://127.0.0.1:3306/voucher?useSSL=false&useUnicode=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul - username : yong - password : 1234 + url: jdbc:mysql://127.0.0.1:3306/voucher?useSSL=false&useUnicode=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul + username: yong + password: 1234 sql: init: mode: always - + mvc: + hiddenmethod: + filter: + enabled: true file: From 0b8fa3426e89002cd0a48ed1f79b5bb0aa2e88bb Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 13:07:34 +0900 Subject: [PATCH 104/109] =?UTF-8?q?refactor:=20schema=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/data.sql | 21 ++++++++++++++------- src/main/resources/schema.sql | 34 +++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 7a9e449b02..f7d2189210 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,10 +1,17 @@ -insert into vouchers values ('bc2e6a9d-1319-4db0-83ba-e07a85fffab8',22,'PERCENT_DISCOUNT'); -insert into vouchers values ('50976229-81af-4dd2-a36d-0f15a58d6f33',10000,'FIXED_AMOUNT'); +insert into vouchers +values ('bc2e6a9d-1319-4db0-83ba-e07a85fffab8', 22, 'PERCENT_DISCOUNT', now()); +insert into vouchers +values ('50976229-81af-4dd2-a36d-0f15a58d6f33', 10000, 'FIXED_AMOUNT', now()); -insert into customers values (1,'kim','won05121@naver.com',0); -insert into customers values (2,'park','park@naver.com',1); -insert into customers values (3,'lee','lee@naver.com',0); +insert into customers +values (1, 'kim', 'won05121@naver.com', 0); +insert into customers +values (2, 'park', 'park@naver.com', 1); +insert into customers +values (3, 'lee', 'lee@naver.com', 0); -insert into wallets values (1,2,'bc2e6a9d-1319-4db0-83ba-e07a85fffab8'); -insert into wallets values (2,3,'50976229-81af-4dd2-a36d-0f15a58d6f33'); +insert into wallets +values (1, 2, 'bc2e6a9d-1319-4db0-83ba-e07a85fffab8'); +insert into wallets +values (2, 3, '50976229-81af-4dd2-a36d-0f15a58d6f33'); diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index d9f3200a9a..077f988453 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -2,26 +2,30 @@ DROP TABLE IF EXISTS wallets; DROP TABLE IF EXISTS vouchers; DROP TABLE IF EXISTS customers; -CREATE TABLE vouchers( - id varchar(36) primary key , - discount_value INT, - type varchar(20) +CREATE TABLE vouchers +( + id varchar(36) primary key, + discount_value INT, + type varchar(20), + created_at datetime default now() ); -CREATE TABLE customers( - id BIGINT primary key auto_increment, - name varchar(10), - email varchar(40), - black_list bool +CREATE TABLE customers +( + id BIGINT primary key auto_increment, + name varchar(10), + email varchar(40), + black_list bool ); -CREATE TABLE wallets( - id BIGINT primary key auto_increment , - customer_id BIGINT, - voucher_id VARCHAR(36), - foreign key (customer_id) REFERENCES customers(id) on delete cascade on update cascade, - foreign key (voucher_id) REFERENCES vouchers(id) on delete cascade on update cascade +CREATE TABLE wallets +( + id BIGINT primary key auto_increment, + customer_id BIGINT, + voucher_id VARCHAR(36), + foreign key (customer_id) REFERENCES customers (id) on delete cascade on update cascade, + foreign key (voucher_id) REFERENCES vouchers (id) on delete cascade on update cascade ); From bdd9a92e1ab85a215879532725431fd54dbd34b8 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 13:10:06 +0900 Subject: [PATCH 105/109] =?UTF-8?q?refactor:=20created=5Fat=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=BD=94=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/VoucherRepositoryTest.java | 15 ++++++++------- .../repository/wallet/WalletRepositoryTest.java | 16 +++++++++------- .../service/voucher/VoucherServiceTest.java | 9 +++++---- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/test/java/com/prgms/vouchermanager/repository/voucher/VoucherRepositoryTest.java b/src/test/java/com/prgms/vouchermanager/repository/voucher/VoucherRepositoryTest.java index ddcf68c41c..ee1a5a7095 100644 --- a/src/test/java/com/prgms/vouchermanager/repository/voucher/VoucherRepositoryTest.java +++ b/src/test/java/com/prgms/vouchermanager/repository/voucher/VoucherRepositoryTest.java @@ -11,6 +11,7 @@ import org.springframework.dao.DuplicateKeyException; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -28,7 +29,7 @@ void saveVoucherSuccess() { //given - Voucher voucher = new FixedAmountVoucher(UUID.randomUUID(), 100000); + Voucher voucher = new FixedAmountVoucher(UUID.randomUUID(), 100000, null); //when Voucher savedVoucher = voucherRepository.save(voucher); @@ -43,8 +44,8 @@ void saveVoucherFail() { //given UUID id = UUID.randomUUID(); - Voucher voucher1 = new FixedAmountVoucher(id, 100000); - Voucher voucher2 = new PercentDiscountVoucher(id, 10); + Voucher voucher1 = new FixedAmountVoucher(id, 100000, null); + Voucher voucher2 = new PercentDiscountVoucher(id, 10, null); //when voucherRepository.save(voucher1); @@ -60,9 +61,9 @@ void updateVoucherSuccess() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Voucher savedVoucher = voucherRepository.save(voucher); - Voucher updatedVoucher = new FixedAmountVoucher(savedVoucher.getId(), 9999); + Voucher updatedVoucher = new FixedAmountVoucher(savedVoucher.getId(), 9999, LocalDateTime.now()); //when voucherRepository.update(updatedVoucher); @@ -82,7 +83,7 @@ void findByIdVoucherSuccess() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Voucher savedCustomer = voucherRepository.save(voucher); @@ -128,7 +129,7 @@ void deleteByVoucherSuccess() { //given UUID id = UUID.randomUUID(); - voucherRepository.save(new FixedAmountVoucher(id, 1000)); + voucherRepository.save(new FixedAmountVoucher(id, 1000, LocalDateTime.now())); //when voucherRepository.deleteById(id); Optional findById = voucherRepository.findById(id); diff --git a/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java b/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java index 30c8572580..dbe5ec11cc 100644 --- a/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java +++ b/src/test/java/com/prgms/vouchermanager/repository/wallet/WalletRepositoryTest.java @@ -14,6 +14,7 @@ import org.springframework.dao.DataIntegrityViolationException; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -35,7 +36,7 @@ void saveWalletSuccess() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Customer customer = new Customer(null, "ko", "kp@naver.com", true); voucherRepository.save(voucher); Customer savedCustomer = customerRepository.save(customer); @@ -56,7 +57,7 @@ void saveWalletFail() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Customer customer = new Customer(null, "ko", "kp@naver.com", true); Wallet wallet = new Wallet(10L, 1214L, UUID.randomUUID()); //존재하지 않는 참조데이터 @@ -75,7 +76,7 @@ void findByCustomerIdSuccess() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Customer customer = new Customer(10L, "ko", "kp@naver.com", true); voucherRepository.save(voucher); customerRepository.save(customer); @@ -88,13 +89,14 @@ void findByCustomerIdSuccess() { //then Assertions.assertThat(wallets).isNotNull(); } + @Test @DisplayName("customer_id에 해당하는 쿠폰 조회에 실패한다.") void findByCustomerIdFail() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Customer customer = new Customer(10L, "ko", "kp@naver.com", true); voucherRepository.save(voucher); customerRepository.save(customer); @@ -114,7 +116,7 @@ void findByVoucherIdSuccess() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Customer customer = new Customer(10L, "ko", "kp@naver.com", true); voucherRepository.save(voucher); customerRepository.save(customer); @@ -136,7 +138,7 @@ void findByVoucherIdFail() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Customer customer = new Customer(10L, "ko", "kp@naver.com", true); voucherRepository.save(voucher); customerRepository.save(customer); @@ -156,7 +158,7 @@ void deleteByCustomerIdSuccess() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 100000); + Voucher voucher = new FixedAmountVoucher(id, 100000, LocalDateTime.now()); Customer customer = new Customer(10L, "ko", "kp@naver.com", true); voucherRepository.save(voucher); customerRepository.save(customer); diff --git a/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java b/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java index 991a8271e3..796640ee1f 100644 --- a/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java +++ b/src/test/java/com/prgms/vouchermanager/service/voucher/VoucherServiceTest.java @@ -15,6 +15,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.dao.EmptyResultDataAccessException; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -37,8 +38,8 @@ void createVoucherSuccess() { CreateVoucherDto dto = new CreateVoucherDto(99, 2); UUID id = UUID.randomUUID(); Voucher result = dto.getVoucherType() == 1 ? - new FixedAmountVoucher(id, dto.getValue()) : - new PercentDiscountVoucher(id, dto.getValue()); + new FixedAmountVoucher(id, dto.getValue(), LocalDateTime.now()) : + new PercentDiscountVoucher(id, dto.getValue(), LocalDateTime.now()); when(voucherRepository.save(any(Voucher.class))).thenReturn(result); //when @@ -81,7 +82,7 @@ void updateVoucherFail() { void findByIdVoucherSuccess() { //given UUID id = UUID.randomUUID(); - Voucher voucher = new FixedAmountVoucher(id, 1000); + Voucher voucher = new FixedAmountVoucher(id, 1000, LocalDateTime.now()); when(voucherRepository.findById(id)).thenReturn(Optional.ofNullable(voucher)); //when @@ -106,7 +107,7 @@ void findByIdVoucherFail() { @DisplayName("service의 findAll()을 성공적으로 실행해서 필요 데이터를 가져올 수 있다.") void findAllSuccess() { //given - List vouchers = List.of(new FixedAmountVoucher(UUID.randomUUID(), 100), new PercentDiscountVoucher(UUID.randomUUID(), 22)); + List vouchers = List.of(new FixedAmountVoucher(UUID.randomUUID(), 100, LocalDateTime.now()), new PercentDiscountVoucher(UUID.randomUUID(), 22, LocalDateTime.now())); when(voucherRepository.findAll()).thenReturn(vouchers); //when From bd67111cc86338dccc49cf02a8d122a052a28c89 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 13:10:54 +0900 Subject: [PATCH 106/109] =?UTF-8?q?feat:=20api=20controller=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80(=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EC=A4=91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voucher/ApiVoucherControllerTest.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/java/com/prgms/vouchermanager/controller/voucher/ApiVoucherControllerTest.java diff --git a/src/test/java/com/prgms/vouchermanager/controller/voucher/ApiVoucherControllerTest.java b/src/test/java/com/prgms/vouchermanager/controller/voucher/ApiVoucherControllerTest.java new file mode 100644 index 0000000000..dda2278e06 --- /dev/null +++ b/src/test/java/com/prgms/vouchermanager/controller/voucher/ApiVoucherControllerTest.java @@ -0,0 +1,60 @@ +package com.prgms.vouchermanager.controller.voucher; + +import com.prgms.vouchermanager.contorller.voucher.ApiVoucherController; +import com.prgms.vouchermanager.service.voucher.VoucherService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.UUID; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(ApiVoucherController.class) +public class ApiVoucherControllerTest { + private final UUID existId = UUID.fromString("bc2e6a9d-1319-4db0-83ba-e07a85fffab8"); + private final UUID NotExistId = UUID.fromString("ac2e6a9d-1319-4db0-83ba-e07a85fffab1"); + @Autowired + private MockMvc mockMvc; + @MockBean + private VoucherService voucherService; + + @Test + @DisplayName("findAll()으로 모든 목록 불러오기를 성공한다.") + void findAll() throws Exception { + + mockMvc.perform(get("/api/vouchers") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(print()); + + } + + @Test + @DisplayName("findById()로 존재하는 바우처 읽기에 성공한다.") + void findByIdSuccess() throws Exception { + + mockMvc.perform(get("/api/vouchers/{id}", existId) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(print()); + + } + +// @Test +// @DisplayName("findById()로 존재하지 않는 바우처 읽기에 실패한다.") +// void findByIdFail() throws Exception { +// mockMvc.perform(get("/api/vouchers/{id}", NotExistId) +// .contentType(MediaType.APPLICATION_JSON)) +// .andExpect(status().isNotFound()) +// .andDo(print()); +// } --> 웹이나 postman에서는 notFound 처리되지만, mockMvc 테스트만 항상 200처리됩니다. + + +} From fc92cb5ae270105660fa55d614386ee6bb4e5834 Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 13:11:25 +0900 Subject: [PATCH 107/109] =?UTF-8?q?feat:=20gradle=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index d45d73dc45..b9f8a1baff 100644 --- a/build.gradle +++ b/build.gradle @@ -1,34 +1,36 @@ plugins { - id 'java' - id 'org.springframework.boot' version '3.1.4' - id 'io.spring.dependency-management' version '1.1.3' + id 'java' + id 'org.springframework.boot' version '3.1.4' + id 'io.spring.dependency-management' version '1.1.3' } group = 'com.prgms' version = '0.0.1-SNAPSHOT' java { - sourceCompatibility = '17' + sourceCompatibility = '17' } repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter' - implementation 'org.springframework.boot:spring-boot-starter-jdbc' - implementation 'org.projectlombok:lombok:1.18.22' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.mockito:mockito-core:4.8.0' + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + implementation 'org.projectlombok:lombok:1.18.22' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.mockito:mockito-core:4.8.0' - annotationProcessor 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' - implementation 'com.mysql:mysql-connector-j:8.1.0' + implementation 'com.mysql:mysql-connector-j:8.1.0' } tasks.named('test') { - useJUnitPlatform() + useJUnitPlatform() } From 7e1dad1a6b2300aab956ebcaeb42c2997797c4ef Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Thu, 2 Nov 2023 13:41:06 +0900 Subject: [PATCH 108/109] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contorller/voucher/WebVoucherController.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/com/prgms/vouchermanager/contorller/voucher/WebVoucherController.java b/src/main/java/com/prgms/vouchermanager/contorller/voucher/WebVoucherController.java index a318f4b7a9..69bbae1b77 100644 --- a/src/main/java/com/prgms/vouchermanager/contorller/voucher/WebVoucherController.java +++ b/src/main/java/com/prgms/vouchermanager/contorller/voucher/WebVoucherController.java @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import java.util.InputMismatchException; import java.util.List; import java.util.UUID; @@ -88,4 +89,16 @@ String delete(@PathVariable String id) { voucherService.deleteById(UUID.fromString(id)); return "redirect:/admin/vouchers"; } + + @ExceptionHandler + String ExceedVoucherPercent(InputMismatchException e, Model model) { + model.addAttribute("code", e.getMessage()); + return "voucher_exception.html"; + } + + @ExceptionHandler + String CommonException(Exception e, Model model) { + model.addAttribute("code", "잘못된 접근입니다."); + return "voucher_exception.html"; + } } From 1d2ce07aa69fe6b2a6d18af23f2368afa21a708f Mon Sep 17 00:00:00 2001 From: YongNyeo Date: Sun, 5 Nov 2023 22:47:13 +0900 Subject: [PATCH 109/109] =?UTF-8?q?feat:=20templates=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/templates/fragment/header.html | 64 +++++++++++++++++++ .../resources/templates/voucher_create.html | 38 +++++++++++ .../resources/templates/voucher_edit.html | 41 ++++++++++++ .../templates/voucher_exception.html | 29 +++++++++ .../resources/templates/voucher_list.html | 32 ++++++++++ src/main/resources/templates/voucher_one.html | 37 +++++++++++ .../resources/templates/wallet_create.html | 35 ++++++++++ .../resources/templates/wallet_exception.html | 29 +++++++++ src/main/resources/templates/wallet_list.html | 38 +++++++++++ 9 files changed, 343 insertions(+) create mode 100644 src/main/resources/templates/fragment/header.html create mode 100644 src/main/resources/templates/voucher_create.html create mode 100644 src/main/resources/templates/voucher_edit.html create mode 100644 src/main/resources/templates/voucher_exception.html create mode 100644 src/main/resources/templates/voucher_list.html create mode 100644 src/main/resources/templates/voucher_one.html create mode 100644 src/main/resources/templates/wallet_create.html create mode 100644 src/main/resources/templates/wallet_exception.html create mode 100644 src/main/resources/templates/wallet_list.html diff --git a/src/main/resources/templates/fragment/header.html b/src/main/resources/templates/fragment/header.html new file mode 100644 index 0000000000..2e9e001695 --- /dev/null +++ b/src/main/resources/templates/fragment/header.html @@ -0,0 +1,64 @@ +

+ + +
+ + + + + + + diff --git a/src/main/resources/templates/voucher_create.html b/src/main/resources/templates/voucher_create.html new file mode 100644 index 0000000000..e3ee9dc6d6 --- /dev/null +++ b/src/main/resources/templates/voucher_create.html @@ -0,0 +1,38 @@ + + + +
+
+
+ + + + +
+
+
+
+

+ +

+ + +
+ +
+
+
+ + diff --git a/src/main/resources/templates/voucher_edit.html b/src/main/resources/templates/voucher_edit.html new file mode 100644 index 0000000000..15699be6c3 --- /dev/null +++ b/src/main/resources/templates/voucher_edit.html @@ -0,0 +1,41 @@ + + + +
+
+
+ + + + +
+
+
+
+ + +

+ + +

+ + +
+ +
+
+
+ + diff --git a/src/main/resources/templates/voucher_exception.html b/src/main/resources/templates/voucher_exception.html new file mode 100644 index 0000000000..a5fd898494 --- /dev/null +++ b/src/main/resources/templates/voucher_exception.html @@ -0,0 +1,29 @@ + + + +
+
+
+ + + + +
+
+
+

+ +
+
+
+ + diff --git a/src/main/resources/templates/voucher_list.html b/src/main/resources/templates/voucher_list.html new file mode 100644 index 0000000000..8d5b4c39c2 --- /dev/null +++ b/src/main/resources/templates/voucher_list.html @@ -0,0 +1,32 @@ + + + +
+
+
+ + + + +
+
+
+
+

쿠폰 번호

+ +
+
+
+
+
+ + diff --git a/src/main/resources/templates/voucher_one.html b/src/main/resources/templates/voucher_one.html new file mode 100644 index 0000000000..a7fddda9d2 --- /dev/null +++ b/src/main/resources/templates/voucher_one.html @@ -0,0 +1,37 @@ + + + +
+
+
+ + + + +
+
+
+

쿠폰번호

+

할인 타입

+
할인값
+
생성 시간
+
+
+ +
+
+ +
+
+
+ + diff --git a/src/main/resources/templates/wallet_create.html b/src/main/resources/templates/wallet_create.html new file mode 100644 index 0000000000..9d8a219eb4 --- /dev/null +++ b/src/main/resources/templates/wallet_create.html @@ -0,0 +1,35 @@ + + + +
+
+
+ + + + +
+
+
+
+ +

+ +

+ +
+ +
+
+
+ + diff --git a/src/main/resources/templates/wallet_exception.html b/src/main/resources/templates/wallet_exception.html new file mode 100644 index 0000000000..cf9edebce2 --- /dev/null +++ b/src/main/resources/templates/wallet_exception.html @@ -0,0 +1,29 @@ + + + +
+
+
+ + + + +
+
+
+

+ +
+
+
+ + diff --git a/src/main/resources/templates/wallet_list.html b/src/main/resources/templates/wallet_list.html new file mode 100644 index 0000000000..7a5ee73d3d --- /dev/null +++ b/src/main/resources/templates/wallet_list.html @@ -0,0 +1,38 @@ + + + +
+
+
+ + + + +
+
+
+
+

지갑 ID

+ +

회원 ID

+

바우처 ID

+ + +
+
+
+
+
+ +