diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..0252613508
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,38 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### maven ###
+mvnw
+mvnw.cmd
+.mvn
diff --git a/CommandApplication.jar b/CommandApplication.jar
new file mode 100644
index 0000000000..40a3259a9a
Binary files /dev/null and b/CommandApplication.jar differ
diff --git a/customer_blacklist.csv b/customer_blacklist.csv
new file mode 100644
index 0000000000..5092bd6024
--- /dev/null
+++ b/customer_blacklist.csv
@@ -0,0 +1,5 @@
+normal,ea7bda51-f029-43f6-bcb2-d95afd77f23d,엄진환
+black,0042406f-f5ff-4b4a-b062-02fa6fc9eaf7,AAA
+normal,b7603e9e-dc0d-4376-8e7a-7bd4586954a6,BBB
+normal,ce26496d-c3eb-44ed-acbd-0e5a908b2b4a,CCC
+black,0042406f-f5ff-4b4a-b062-01fa6fc9eaf7,DDD
\ No newline at end of file
diff --git a/logs/access-2021-08-26.log b/logs/access-2021-08-26.log
new file mode 100644
index 0000000000..79f4e84a4c
--- /dev/null
+++ b/logs/access-2021-08-26.log
@@ -0,0 +1,37 @@
+18:04:05.296 [main] INFO o.p.k.a.KdtSpringDemoApplication - Starting KdtSpringDemoApplication using Java 16.0.2 on DESKTOP-8KCHBP3 with PID 3312 (C:\Users\Qup\Documents\GitHub\w3-SpringBoot\target\classes started by Qup in C:\Users\Qup\Documents\GitHub\w3-SpringBoot)
+18:04:05.298 [main] DEBUG o.p.k.a.KdtSpringDemoApplication - Running with Spring Boot v2.5.4, Spring v5.3.9
+18:04:05.298 [main] INFO o.p.k.a.KdtSpringDemoApplication - The following profiles are active: dev
+18:04:05.823 [main] DEBUG o.p.k.order.OrderProperties - version -> v1.0
+18:04:05.823 [main] DEBUG o.p.k.order.OrderProperties - minimumOrderAmount -> 1
+18:04:05.823 [main] DEBUG o.p.k.order.OrderProperties - supportVendors -> [a, b, c, d]
+18:04:05.823 [main] DEBUG o.p.k.order.OrderProperties - description -> line 1 hello world
+line 2 xxxx
+line 3
+18:04:05.909 [main] INFO o.p.k.a.KdtSpringDemoApplication - Started KdtSpringDemoApplication in 1.124 seconds (JVM running for 4.021)
+18:11:16.195 [main] INFO o.p.k.a.KdtSpringDemoApplication - Starting KdtSpringDemoApplication using Java 16.0.2 on DESKTOP-8KCHBP3 with PID 22428 (C:\Users\Qup\Documents\GitHub\w3-SpringBoot\target\classes started by Qup in C:\Users\Qup\Documents\GitHub\w3-SpringBoot)
+18:11:16.198 [main] DEBUG o.p.k.a.KdtSpringDemoApplication - Running with Spring Boot v2.5.4, Spring v5.3.9
+18:11:16.199 [main] INFO o.p.k.a.KdtSpringDemoApplication - The following profiles are active: dev
+18:11:16.768 [main] DEBUG o.p.k.order.OrderProperties - version -> v1.0
+18:11:16.768 [main] DEBUG o.p.k.order.OrderProperties - minimumOrderAmount -> 1
+18:11:16.769 [main] DEBUG o.p.k.order.OrderProperties - supportVendors -> [a, b, c, d]
+18:11:16.769 [main] DEBUG o.p.k.order.OrderProperties - description -> line 1 hello world
+line 2 xxxx
+line 3
+18:11:16.856 [main] INFO o.p.k.a.KdtSpringDemoApplication - Started KdtSpringDemoApplication in 1.13 seconds (JVM running for 2.362)
+18:21:51.419 [main] INFO o.p.k.a.KdtSpringDemoApplication - Starting KdtSpringDemoApplication using Java 16.0.2 on DESKTOP-8KCHBP3 with PID 20888 (C:\Users\Qup\Documents\GitHub\w3-SpringBoot\target\classes started by Qup in C:\Users\Qup\Documents\GitHub\w3-SpringBoot)
+18:21:51.422 [main] DEBUG o.p.k.a.KdtSpringDemoApplication - Running with Spring Boot v2.5.4, Spring v5.3.9
+18:21:51.422 [main] INFO o.p.k.a.KdtSpringDemoApplication - The following profiles are active: dev
+18:21:52.015 [main] DEBUG o.p.k.order.OrderProperties - version -> v1.0
+18:21:52.015 [main] DEBUG o.p.k.order.OrderProperties - minimumOrderAmount -> 1
+18:21:52.015 [main] DEBUG o.p.k.order.OrderProperties - supportVendors -> [a, b, c, d]
+18:21:52.016 [main] DEBUG o.p.k.order.OrderProperties - description -> line 1 hello world
+line 2 xxxx
+line 3
+18:21:52.099 [main] INFO o.p.k.a.KdtSpringDemoApplication - Started KdtSpringDemoApplication in 1.147 seconds (JVM running for 2.116)
+18:21:52.102 [main] WARN o.p.k.a.KdtSpringDemoApplication - logger name -> org.prgrms.kdtspringdemo.KdtSpringDemoApplication
+18:21:52.103 [main] ERROR o.p.k.a.KdtSpringDemoApplication - version -> v1.0
+18:21:52.104 [main] ERROR o.p.k.a.KdtSpringDemoApplication - minimumOrderAmount -> 1
+18:21:52.104 [main] INFO o.p.k.a.KdtSpringDemoApplication - supportVendors -> [a, b, c, d]
+18:21:52.104 [main] DEBUG o.p.k.a.KdtSpringDemoApplication - description -> line 1 hello world
+line 2 xxxx
+line 3
diff --git a/logs/access-2021-08-27.log b/logs/access-2021-08-27.log
new file mode 100644
index 0000000000..56718630fe
--- /dev/null
+++ b/logs/access-2021-08-27.log
@@ -0,0 +1 @@
+01:00:29.550 [main] ERROR o.p.kdtspringdemo.console.Console - Invalid command type. Your input -> asdf
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000..6e3882833a
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.5.4
+
+
+ org.prgrms.kdtspringdemo
+ w3-SpringBoot
+ 0.0.1-SNAPSHOT
+ w3-SpringBoot
+ w3-SpringBoot
+
+ 16
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/src/main/java/org/prgrms/kdtspringdemo/CommandType.java b/src/main/java/org/prgrms/kdtspringdemo/CommandType.java
new file mode 100644
index 0000000000..acd9c16402
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/CommandType.java
@@ -0,0 +1,5 @@
+package org.prgrms.kdtspringdemo;
+
+public enum CommandType {
+ CREATE, LIST, CUSTOMERS, BLACKS, EXIT, ERROR
+}
\ No newline at end of file
diff --git a/src/main/java/org/prgrms/kdtspringdemo/KdtSpringDemoApplication.java b/src/main/java/org/prgrms/kdtspringdemo/KdtSpringDemoApplication.java
new file mode 100644
index 0000000000..c3a1b99d62
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/KdtSpringDemoApplication.java
@@ -0,0 +1,12 @@
+package org.prgrms.kdtspringdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class KdtSpringDemoApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(KdtSpringDemoApplication.class, args);
+ }
+
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/VoucherType.java b/src/main/java/org/prgrms/kdtspringdemo/VoucherType.java
new file mode 100644
index 0000000000..28ece8fad3
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/VoucherType.java
@@ -0,0 +1,45 @@
+package org.prgrms.kdtspringdemo;
+
+import org.prgrms.kdtspringdemo.voucher.FixedAmountVoucher;
+import org.prgrms.kdtspringdemo.voucher.PercentDiscountVoucher;
+import org.prgrms.kdtspringdemo.voucher.Voucher;
+
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.UUID;
+
+public enum VoucherType {
+ FIXED_AMOUNT("F"), PERCENT_DISCOUNT("P");
+
+ private final String inputCommand;
+
+ VoucherType(String p) {
+ this.inputCommand = p;
+ }
+
+ public static boolean isInVoucherType(String command) {
+ long count = Arrays.stream(VoucherType.values())
+ .filter(voucherType -> voucherType.inputCommand.equals(command))
+ .count();
+ return count != 0;
+ }
+
+ private static VoucherType findByCommand(String command) {
+ return Arrays.stream(VoucherType.values())
+ .filter(voucherType -> voucherType.inputCommand.equals(command))
+ .findAny()
+ .orElseThrow(IllegalArgumentException::new);
+ }
+
+ public static Optional getVoucher(String inputCommand, long value) {
+ Optional voucher = Optional.empty();
+
+ switch (findByCommand(inputCommand)) {
+ case FIXED_AMOUNT -> voucher = Optional.of(new FixedAmountVoucher(UUID.randomUUID(), value));
+ case PERCENT_DISCOUNT -> voucher = Optional.of(new PercentDiscountVoucher(UUID.randomUUID(), value));
+ }
+ return voucher;
+ }
+
+ ;
+};
diff --git a/src/main/java/org/prgrms/kdtspringdemo/application/CommandLineApplication.java b/src/main/java/org/prgrms/kdtspringdemo/application/CommandLineApplication.java
new file mode 100644
index 0000000000..d640ac6fd8
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/application/CommandLineApplication.java
@@ -0,0 +1,22 @@
+package org.prgrms.kdtspringdemo.application;
+
+import org.prgrms.kdtspringdemo.console.Console;
+import org.prgrms.kdtspringdemo.console.CustomerOperator;
+import org.prgrms.kdtspringdemo.console.VoucherOperator;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class CommandLineApplication implements ApplicationRunner {
+ private final VoucherOperator voucherOperator;
+
+ public CommandLineApplication(VoucherOperator voucherOperator) {
+ this.voucherOperator = voucherOperator;
+ }
+
+ @Override
+ public void run(ApplicationArguments args) throws Exception {
+ new ConsoleApp(new Console(), voucherOperator, new CustomerOperator());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/prgrms/kdtspringdemo/application/ConsoleApp.java b/src/main/java/org/prgrms/kdtspringdemo/application/ConsoleApp.java
new file mode 100644
index 0000000000..aea3640233
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/application/ConsoleApp.java
@@ -0,0 +1,27 @@
+package org.prgrms.kdtspringdemo.application;
+
+import org.prgrms.kdtspringdemo.CommandType;
+import org.prgrms.kdtspringdemo.console.Console;
+import org.prgrms.kdtspringdemo.console.CustomerOperator;
+import org.prgrms.kdtspringdemo.console.VoucherOperator;
+
+public class ConsoleApp {
+ public ConsoleApp(Console console, VoucherOperator voucherOperator, CustomerOperator customerOperator) {
+ console.printStartAppInfo();
+
+ while (true) {
+ CommandType command = console.getInputCommand();
+ switch (command) {
+ case CREATE -> {
+ console.printCreateTypes();
+ String[] createCommand = console.getCreateLine().split(" ");
+ voucherOperator.create(createCommand);
+ }
+ case CUSTOMERS -> customerOperator.printAll();
+ case BLACKS -> customerOperator.printBlacklist();
+ case LIST -> voucherOperator.printAll();
+ case EXIT -> System.exit(0);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/configuration/AppConfiguration.java b/src/main/java/org/prgrms/kdtspringdemo/configuration/AppConfiguration.java
new file mode 100644
index 0000000000..6451cb2256
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/configuration/AppConfiguration.java
@@ -0,0 +1,18 @@
+package org.prgrms.kdtspringdemo.configuration;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+@Configuration
+@ComponentScan(basePackages = {
+ "org.prgrms.kdtspringdemo.order",
+ "org.prgrms.kdtspringdemo.voucher",
+ "org.prgrms.kdtspringdemo.customer",
+ "org.prgrms.kdtspringdemo.configuration"
+})
+@PropertySource(value = "application.yaml", factory = YamlPropertiesFactory.class)
+@EnableConfigurationProperties
+public class AppConfiguration {
+}
\ No newline at end of file
diff --git a/src/main/java/org/prgrms/kdtspringdemo/configuration/AwsConfiguration.java b/src/main/java/org/prgrms/kdtspringdemo/configuration/AwsConfiguration.java
new file mode 100644
index 0000000000..fd6dc873d4
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/configuration/AwsConfiguration.java
@@ -0,0 +1,7 @@
+package org.prgrms.kdtspringdemo.configuration;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AwsConfiguration {
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/configuration/GcpConfiguration.java b/src/main/java/org/prgrms/kdtspringdemo/configuration/GcpConfiguration.java
new file mode 100644
index 0000000000..99984c9e30
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/configuration/GcpConfiguration.java
@@ -0,0 +1,7 @@
+package org.prgrms.kdtspringdemo.configuration;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class GcpConfiguration {
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/configuration/SecurityConfiguration.java b/src/main/java/org/prgrms/kdtspringdemo/configuration/SecurityConfiguration.java
new file mode 100644
index 0000000000..85b040695d
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/configuration/SecurityConfiguration.java
@@ -0,0 +1,7 @@
+package org.prgrms.kdtspringdemo.configuration;
+
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SecurityConfiguration {
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/configuration/YamlPropertiesFactory.java b/src/main/java/org/prgrms/kdtspringdemo/configuration/YamlPropertiesFactory.java
new file mode 100644
index 0000000000..f047821515
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/configuration/YamlPropertiesFactory.java
@@ -0,0 +1,20 @@
+package org.prgrms.kdtspringdemo.configuration;
+
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
+import org.springframework.core.env.PropertiesPropertySource;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.io.support.EncodedResource;
+import org.springframework.core.io.support.PropertySourceFactory;
+
+import java.io.IOException;
+
+public class YamlPropertiesFactory implements PropertySourceFactory {
+ @Override
+ public PropertySource> createPropertySource(String s, EncodedResource encodedResource) throws IOException {
+ var yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
+ yamlPropertiesFactoryBean.setResources(encodedResource.getResource());
+
+ var properties = yamlPropertiesFactoryBean.getObject();
+ return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/console/CommandOperator.java b/src/main/java/org/prgrms/kdtspringdemo/console/CommandOperator.java
new file mode 100644
index 0000000000..2278d4cae4
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/console/CommandOperator.java
@@ -0,0 +1,7 @@
+package org.prgrms.kdtspringdemo.console;
+
+public interface CommandOperator {
+ public void create(String[] splitList);
+
+ public void printAll();
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/console/Console.java b/src/main/java/org/prgrms/kdtspringdemo/console/Console.java
new file mode 100644
index 0000000000..b21054629f
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/console/Console.java
@@ -0,0 +1,72 @@
+package org.prgrms.kdtspringdemo.console;
+
+import org.prgrms.kdtspringdemo.CommandType;
+import org.prgrms.kdtspringdemo.io.*;
+import org.prgrms.kdtspringdemo.order.OrderProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.MessageFormat;
+import java.util.Scanner;
+
+public class Console implements Input, Output {
+ private final static Logger logger = LoggerFactory.getLogger(Console.class);
+ private Scanner input;
+
+ public Console() {
+ this.input = new Scanner(System.in);
+ }
+
+ @Override
+ public void printStartAppInfo() {
+ System.out.println("=== Voucher Program ===");
+ printCommandList();
+ }
+
+ @Override
+ public void printCommandList() {
+ System.out.println("""
+ Type exit to exit the program.
+ Type create to create a new voucher.
+ Type list to list all vouchers.
+ Type customers to list all customers
+ Type blacks to list all blacklist customers""");
+ }
+
+ @Override
+ public void printCommandError(String command) {
+ System.out.println(MessageFormat.format("[ERROR]Invalid command type \nYour input : {0}", command));
+ printCommandList();
+ System.out.println("=================");
+ }
+
+ @Override
+ public void printCreateTypes() {
+ System.out.println("""
+ input voucher info
+
+ voucherType
+ \tP : FixedAmountVoucher
+ \tF : PercentDiscountVoucher
+ data is long value
+ ex) P 10""");
+ }
+
+ @Override
+ public CommandType getInputCommand() {
+ ;
+ String command = input.nextLine();
+ try {
+ return CommandType.valueOf(command.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ logger.error(MessageFormat.format("Invalid command type. Your input -> {0}", command));
+ printCommandError(command);
+ return CommandType.ERROR;
+ }
+ }
+
+ @Override
+ public String getCreateLine() {
+ return input.nextLine();
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/console/CustomerOperator.java b/src/main/java/org/prgrms/kdtspringdemo/console/CustomerOperator.java
new file mode 100644
index 0000000000..0b86f50ede
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/console/CustomerOperator.java
@@ -0,0 +1,28 @@
+package org.prgrms.kdtspringdemo.console;
+
+import org.prgrms.kdtspringdemo.configuration.AppConfiguration;
+import org.prgrms.kdtspringdemo.customer.CustomerService;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+public class CustomerOperator implements CommandOperator {
+ private final CustomerService customerService;
+
+ public CustomerOperator() {
+ var application = new AnnotationConfigApplicationContext(AppConfiguration.class);
+ customerService = application.getBean(CustomerService.class);
+ }
+
+ @Override
+ public void create(String[] splitList) {
+ //None
+ }
+
+ @Override
+ public void printAll() {
+ customerService.printAll();
+ }
+
+ public void printBlacklist() {
+ customerService.printBlacklist();
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/console/VoucherOperator.java b/src/main/java/org/prgrms/kdtspringdemo/console/VoucherOperator.java
new file mode 100644
index 0000000000..8aa4ab3b85
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/console/VoucherOperator.java
@@ -0,0 +1,48 @@
+package org.prgrms.kdtspringdemo.console;
+
+import org.prgrms.kdtspringdemo.VoucherType;
+import org.prgrms.kdtspringdemo.voucher.Voucher;
+import org.prgrms.kdtspringdemo.voucher.VoucherService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.text.MessageFormat;
+import java.util.Optional;
+
+@Component
+public class VoucherOperator implements CommandOperator {
+ private final static Logger logger = LoggerFactory.getLogger(VoucherOperator.class);
+ private final VoucherService voucherService;
+
+ public VoucherOperator(VoucherService voucherService) {
+ this.voucherService = voucherService;
+ }
+
+ @Override
+ public void create(String[] splitList) {
+ Optional voucher = createVoucher(splitList);
+ voucher.ifPresent(voucherService::saveVoucher);
+ }
+
+ public Optional createVoucher(String[] splitList) {
+ if (splitList.length != 2) return Optional.empty();
+
+ Optional voucher = Optional.empty();
+ if (VoucherType.isInVoucherType(splitList[0])) {
+ voucher = VoucherType.getVoucher(splitList[0], Long.parseLong(splitList[1]));
+
+ System.out.println("This is create : " + voucher);
+ } else {
+ logger.error(MessageFormat.format("Invalid create command. Your input -> {0}, {1}", splitList[0], splitList[1]));
+ System.out.println("[ERROR]Invalid create command");
+ System.out.println(MessageFormat.format("Your input : {0}, {1}", splitList[0], splitList[1]));
+ }
+ return voucher;
+ }
+
+ @Override
+ public void printAll() {
+ voucherService.printAllVoucher();
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/customer/BlackCustomer.java b/src/main/java/org/prgrms/kdtspringdemo/customer/BlackCustomer.java
new file mode 100644
index 0000000000..b19cd15d1e
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/customer/BlackCustomer.java
@@ -0,0 +1,29 @@
+package org.prgrms.kdtspringdemo.customer;
+
+import java.text.MessageFormat;
+import java.util.UUID;
+
+public class BlackCustomer implements Customer {
+ private UUID uuid;
+ private String name;
+
+ public BlackCustomer(UUID customerId, String name) {
+ this.uuid = customerId;
+ this.name = name;
+ }
+
+ @Override
+ public UUID getId() {
+ return UUID.randomUUID();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return MessageFormat.format("id : {0}, name : {1}, {2}", uuid, name, this.getClass().getSimpleName());
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/customer/Customer.java b/src/main/java/org/prgrms/kdtspringdemo/customer/Customer.java
new file mode 100644
index 0000000000..077f9159ef
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/customer/Customer.java
@@ -0,0 +1,8 @@
+package org.prgrms.kdtspringdemo.customer;
+
+import java.util.UUID;
+
+public interface Customer {
+ UUID getId();
+ String getName();
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/customer/CustomerRepository.java b/src/main/java/org/prgrms/kdtspringdemo/customer/CustomerRepository.java
new file mode 100644
index 0000000000..7602a6f5f4
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/customer/CustomerRepository.java
@@ -0,0 +1,16 @@
+package org.prgrms.kdtspringdemo.customer;
+
+import org.prgrms.kdtspringdemo.voucher.Voucher;
+
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+public interface CustomerRepository {
+ Optional findById(UUID customerId);
+ Customer insert(Customer customer);
+
+ Stream findAll();
+
+ Stream findBlacklist();
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/customer/CustomerService.java b/src/main/java/org/prgrms/kdtspringdemo/customer/CustomerService.java
new file mode 100644
index 0000000000..ada3c10989
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/customer/CustomerService.java
@@ -0,0 +1,24 @@
+package org.prgrms.kdtspringdemo.customer;
+
+import org.springframework.stereotype.Service;
+
+import java.util.stream.Stream;
+
+@Service
+public class CustomerService {
+ private final CustomerRepository customerRepository;
+
+ public CustomerService(CustomerRepository customerRepository) {
+ this.customerRepository = customerRepository;
+ }
+
+ public void printAll() {
+ Stream allCustomer = customerRepository.findAll();
+ allCustomer.forEach(System.out::println);
+ }
+
+ public void printBlacklist() {
+ Stream allCustomer = customerRepository.findBlacklist();
+ allCustomer.forEach(System.out::println);
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/customer/FileCustomerRepository.java b/src/main/java/org/prgrms/kdtspringdemo/customer/FileCustomerRepository.java
new file mode 100644
index 0000000000..8e4e6a6148
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/customer/FileCustomerRepository.java
@@ -0,0 +1,68 @@
+package org.prgrms.kdtspringdemo.customer;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Repository;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
+@Repository
+@Primary
+public class FileCustomerRepository implements CustomerRepository, InitializingBean {
+ private final Map storage = new ConcurrentHashMap<>();
+ private final Map blacklist_storage = new ConcurrentHashMap<>();
+ private final String FILE_NAME = "customer_blacklist.csv";
+
+ @Override
+ public Optional findById(UUID customerId) {
+ return Optional.ofNullable(storage.get(customerId));
+ }
+
+ @Override
+ public Customer insert(Customer customer) {
+ return null;
+ }
+
+ @Override
+ public Stream findAll() {
+ return storage.values().stream();
+ }
+
+ @Override
+ public Stream findBlacklist() {
+ return blacklist_storage.values().stream();
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ try (BufferedReader reader = Files.newBufferedReader(Path.of(FILE_NAME))) {
+ reader.lines().forEach(line -> {
+ String[] dataArray = line.split(",");
+ String customerType = dataArray[0];
+ String uuid = dataArray[1];
+ String name = dataArray[2];
+
+ if (customerType.equals("normal")) {
+ var customer = new NormalCustomer(UUID.fromString(uuid), name);
+ storage.put(customer.getId(), customer);
+ } else if (customerType.equals("black")) {
+ var customer = new BlackCustomer(UUID.fromString(uuid), name);
+ storage.put(customer.getId(), customer);
+ blacklist_storage.put(customer.getId(), customer);
+ } else {
+ System.out.println("None CustomerType!!! : " + customerType);
+ }
+ });
+ } catch (IOException e) {
+ System.out.println("Doesn't exist file.");
+ }
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/customer/NormalCustomer.java b/src/main/java/org/prgrms/kdtspringdemo/customer/NormalCustomer.java
new file mode 100644
index 0000000000..52614d2b40
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/customer/NormalCustomer.java
@@ -0,0 +1,29 @@
+package org.prgrms.kdtspringdemo.customer;
+
+import java.text.MessageFormat;
+import java.util.UUID;
+
+public class NormalCustomer implements Customer {
+ private UUID uuid;
+ private String name;
+
+ public NormalCustomer(UUID customerId, String name) {
+ this.uuid = customerId;
+ this.name = name;
+ }
+
+ @Override
+ public UUID getId() {
+ return UUID.randomUUID();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return MessageFormat.format("id : {0}, name : {1}, {2}", uuid, name, this.getClass().getSimpleName());
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/io/Input.java b/src/main/java/org/prgrms/kdtspringdemo/io/Input.java
new file mode 100644
index 0000000000..c44f13800e
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/io/Input.java
@@ -0,0 +1,9 @@
+package org.prgrms.kdtspringdemo.io;
+
+import org.prgrms.kdtspringdemo.CommandType;
+
+public interface Input {
+ CommandType getInputCommand();
+
+ String getCreateLine();
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/io/Output.java b/src/main/java/org/prgrms/kdtspringdemo/io/Output.java
new file mode 100644
index 0000000000..4306dd52a8
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/io/Output.java
@@ -0,0 +1,11 @@
+package org.prgrms.kdtspringdemo.io;
+
+public interface Output {
+ void printCommandList();
+
+ void printStartAppInfo();
+
+ void printCommandError(String command);
+
+ void printCreateTypes();
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/order/MemoryOrderRepository.java b/src/main/java/org/prgrms/kdtspringdemo/order/MemoryOrderRepository.java
new file mode 100644
index 0000000000..46c7362059
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/order/MemoryOrderRepository.java
@@ -0,0 +1,18 @@
+package org.prgrms.kdtspringdemo.order;
+
+import org.springframework.stereotype.Repository;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Repository
+public class MemoryOrderRepository implements OrderRepository {
+ private final Map storage = new ConcurrentHashMap<>();
+
+ @Override
+ public Order insert(Order order) {
+ storage.put(order.getOrderId(), order);
+ return order;
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/order/Order.java b/src/main/java/org/prgrms/kdtspringdemo/order/Order.java
new file mode 100644
index 0000000000..d7e95edd69
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/order/Order.java
@@ -0,0 +1,46 @@
+package org.prgrms.kdtspringdemo.order;
+
+import org.prgrms.kdtspringdemo.voucher.Voucher;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+public class Order {
+ private final UUID orderId;
+ private final UUID customerId;
+ private final List orderItems;
+ private Optional voucher;
+ private OrderStatus orderStatus;
+
+ public Order(UUID orderId, UUID customerId, List orderItems) {
+ this.orderId = orderId;
+ this.customerId = customerId;
+ this.orderItems = orderItems;
+ this.voucher = Optional.empty();
+ }
+
+
+ public Order(UUID orderId, UUID customerId, List orderItems, Voucher voucher) {
+ this.orderId = orderId;
+ this.customerId = customerId;
+ this.orderItems = orderItems;
+ this.voucher = Optional.of(voucher);
+ }
+
+ public long totalAmount() {
+ var beforeDiscount = orderItems.stream()
+ .map(v -> v.productPrice() * v.quantity())
+ .reduce(0L, Long::sum);
+
+ return voucher.map(value -> value.discount(beforeDiscount)).orElse(beforeDiscount);
+ }
+
+ public void setOrderStatus(OrderStatus orderStatus) {
+ this.orderStatus = orderStatus;
+ }
+
+ public UUID getOrderId() {
+ return orderId;
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/order/OrderItem.java b/src/main/java/org/prgrms/kdtspringdemo/order/OrderItem.java
new file mode 100644
index 0000000000..b24faff65b
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/order/OrderItem.java
@@ -0,0 +1,8 @@
+package org.prgrms.kdtspringdemo.order;
+
+import java.util.UUID;
+
+public record OrderItem (UUID productId,
+ long productPrice,
+ long quantity) {
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/order/OrderProperties.java b/src/main/java/org/prgrms/kdtspringdemo/order/OrderProperties.java
new file mode 100644
index 0000000000..63f40f5f23
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/order/OrderProperties.java
@@ -0,0 +1,64 @@
+package org.prgrms.kdtspringdemo.order;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+@Configuration
+@ConfigurationProperties(prefix = "kdt")
+public class OrderProperties implements InitializingBean {
+ private final static Logger logger = LoggerFactory.getLogger(OrderProperties.class);
+
+ private String version;
+
+ private Integer minimumOrderAmount;
+
+ private List supportVendors;
+
+ private String description;
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ logger.debug(MessageFormat.format("version -> {0}", version));
+ logger.debug(MessageFormat.format("minimumOrderAmount -> {0}", minimumOrderAmount));
+ logger.debug(MessageFormat.format("supportVendors -> {0}", supportVendors));
+ logger.debug(MessageFormat.format("description -> {0}", description));
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public Integer getMinimumOrderAmount() {
+ return minimumOrderAmount;
+ }
+
+ public void setMinimumOrderAmount(Integer minimumOrderAmount) {
+ this.minimumOrderAmount = minimumOrderAmount;
+ }
+
+ public List getSupportVendors() {
+ return supportVendors;
+ }
+
+ public void setSupportVendors(List supportVendors) {
+ this.supportVendors = supportVendors;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/order/OrderRepository.java b/src/main/java/org/prgrms/kdtspringdemo/order/OrderRepository.java
new file mode 100644
index 0000000000..7ef4ed3694
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/order/OrderRepository.java
@@ -0,0 +1,5 @@
+package org.prgrms.kdtspringdemo.order;
+
+public interface OrderRepository {
+ Order insert(Order order);
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/order/OrderService.java b/src/main/java/org/prgrms/kdtspringdemo/order/OrderService.java
new file mode 100644
index 0000000000..1dfc40a45d
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/order/OrderService.java
@@ -0,0 +1,33 @@
+package org.prgrms.kdtspringdemo.order;
+
+import org.prgrms.kdtspringdemo.voucher.VoucherService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.UUID;
+
+@Service
+@Profile("dev")
+public class OrderService {
+ private final VoucherService voucherService;
+ private final OrderRepository orderRepository;
+
+ public OrderService(VoucherService voucherService, OrderRepository orderRepository) {
+ this.voucherService = voucherService;
+ this.orderRepository = orderRepository;
+ }
+
+ public Order createOrder(UUID customerId, List orderItems) {
+ var order = new Order(UUID.randomUUID(), customerId, orderItems);
+ return orderRepository.insert(order);
+ }
+
+ public Order createOrder(UUID customerId, List orderItems, UUID voucherId) {
+ var voucher = voucherService.getVoucher(voucherId);
+ var order = new Order(UUID.randomUUID(), customerId, orderItems, voucher);
+ orderRepository.insert(order);
+ voucherService.useVourcher(voucher);
+ return order;
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/order/OrderStatus.java b/src/main/java/org/prgrms/kdtspringdemo/order/OrderStatus.java
new file mode 100644
index 0000000000..f5aa119efa
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/order/OrderStatus.java
@@ -0,0 +1,12 @@
+package org.prgrms.kdtspringdemo.order;
+
+public enum OrderStatus {
+ ACCEPTED,
+ PAYMENT_REQUIRED,
+ PAYMENT_CONFIRMED,
+ PAYMENT_REJECTED,
+ READY_FOR_DELIVERY,
+ SHIPPED,
+ SETTLED,
+ CANCELLED
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/voucher/FileVoucherRepository.java b/src/main/java/org/prgrms/kdtspringdemo/voucher/FileVoucherRepository.java
new file mode 100644
index 0000000000..1e0a65020f
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/voucher/FileVoucherRepository.java
@@ -0,0 +1,68 @@
+package org.prgrms.kdtspringdemo.voucher;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Repository;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
+@Repository
+@Profile("dev")
+public class FileVoucherRepository implements VoucherRepository, InitializingBean {
+ private final Map storage = new ConcurrentHashMap<>();
+ private final String FILE_NAME = "voucher.csv";
+
+ @Override
+ public Optional findById(UUID voucherId) {
+ return Optional.ofNullable(storage.get(voucherId));
+ }
+
+ @Override
+ public Voucher insert(Voucher voucher) {
+ try (BufferedWriter writer = Files.newBufferedWriter(Path.of(FILE_NAME), StandardOpenOption.CREATE, StandardOpenOption.APPEND)) {
+ String contents = voucher.saveCSV();
+ writer.append(contents).append("\n");
+ storage.put(voucher.getVoucherId(), voucher);
+ } catch (IOException ioException) {
+ ioException.printStackTrace();
+ }
+ return voucher;
+ }
+
+ @Override
+ public Stream findAll() {
+ return storage.values().stream();
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ try (BufferedReader reader = Files.newBufferedReader(Path.of(FILE_NAME))) {
+ reader.lines().forEach(line -> {
+ String[] dataArray = line.split(",");
+ String voucherType = dataArray[0];
+ String uuid = dataArray[1];
+ String data = dataArray[2];
+
+ if (voucherType.equals("FixedAmountVoucher")) {
+ var voucher = new FixedAmountVoucher(UUID.fromString(uuid), Long.parseLong(data));
+ storage.put(voucher.getVoucherId(), voucher);
+ } else if (voucherType.equals("PercentDiscountVoucher")) {
+ var voucher = new PercentDiscountVoucher(UUID.fromString(uuid), Long.parseLong(data));
+ storage.put(voucher.getVoucherId(), voucher);
+ } else {
+ System.out.println("None VoucherType!!! : " + voucherType);
+ }
+ });
+ } catch (IOException e) {
+ System.out.println("Doesn't exist file.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/prgrms/kdtspringdemo/voucher/FixedAmountVoucher.java b/src/main/java/org/prgrms/kdtspringdemo/voucher/FixedAmountVoucher.java
new file mode 100644
index 0000000000..46c5cb5aba
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/voucher/FixedAmountVoucher.java
@@ -0,0 +1,33 @@
+package org.prgrms.kdtspringdemo.voucher;
+
+import java.text.MessageFormat;
+import java.util.UUID;
+
+public class FixedAmountVoucher implements Voucher {
+ private final UUID voucherId;
+ private final long amount;
+
+ @Override
+ public String toString() {
+ return MessageFormat.format("[FixedAmountVoucher] voucherId : {0}, amount : {1}", voucherId, amount);
+ }
+
+ public FixedAmountVoucher(UUID voucherId, long amount) {
+ this.voucherId = voucherId;
+ this.amount = amount;
+ }
+
+ @Override
+ public UUID getVoucherId() {
+ return voucherId;
+ }
+
+ @Override
+ public String saveCSV() {
+ return String.format("FixedAmountVoucher,%s,%s", voucherId, amount);
+ }
+
+ public long discount(long beforeDiscount) {
+ return beforeDiscount - amount;
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/voucher/JdbcVoucherRepository.java b/src/main/java/org/prgrms/kdtspringdemo/voucher/JdbcVoucherRepository.java
new file mode 100644
index 0000000000..1d8dd78b21
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/voucher/JdbcVoucherRepository.java
@@ -0,0 +1,30 @@
+package org.prgrms.kdtspringdemo.voucher;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Repository;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
+@Repository
+@Profile("dev2")
+public class JdbcVoucherRepository implements VoucherRepository {
+ private final Map storage = new ConcurrentHashMap<>();
+
+ @Override
+ public Optional findById(UUID voucherId) {
+ return Optional.ofNullable(storage.get(voucherId));
+ }
+
+ @Override
+ public Voucher insert(Voucher voucher) {
+ storage.put(voucher.getVoucherId(), voucher);
+ return voucher;
+ }
+
+ @Override
+ public Stream findAll() {
+ return storage.values().stream();
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/voucher/MemoryVoucherRepository.java b/src/main/java/org/prgrms/kdtspringdemo/voucher/MemoryVoucherRepository.java
new file mode 100644
index 0000000000..cd884dc62d
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/voucher/MemoryVoucherRepository.java
@@ -0,0 +1,30 @@
+package org.prgrms.kdtspringdemo.voucher;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Repository;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
+@Repository
+@Profile("local")
+public class MemoryVoucherRepository implements VoucherRepository {
+ private final Map storage = new ConcurrentHashMap<>();
+
+ @Override
+ public Optional findById(UUID voucherId) {
+ return Optional.ofNullable(storage.get(voucherId));
+ }
+
+ @Override
+ public Voucher insert(Voucher voucher) {
+ storage.put(voucher.getVoucherId(), voucher);
+ return voucher;
+ }
+
+ @Override
+ public Stream findAll() {
+ return storage.values().stream();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/prgrms/kdtspringdemo/voucher/PercentDiscountVoucher.java b/src/main/java/org/prgrms/kdtspringdemo/voucher/PercentDiscountVoucher.java
new file mode 100644
index 0000000000..b0d42ad038
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/voucher/PercentDiscountVoucher.java
@@ -0,0 +1,34 @@
+package org.prgrms.kdtspringdemo.voucher;
+
+import java.text.MessageFormat;
+import java.util.UUID;
+
+public class PercentDiscountVoucher implements Voucher {
+ private final UUID voucherId;
+ private final long percent;
+
+ @Override
+ public String toString() {
+ return MessageFormat.format("[PercentDiscountVoucher] voucherId : {0}, percent : {1}", voucherId, percent);
+ }
+
+ public PercentDiscountVoucher(UUID voucherId, long percent) {
+ this.voucherId = voucherId;
+ this.percent = percent;
+ }
+
+ @Override
+ public UUID getVoucherId() {
+ return voucherId;
+ }
+
+ @Override
+ public String saveCSV() {
+ return String.format("PercentDiscountVoucher,%s,%s", voucherId, percent);
+ }
+
+ @Override
+ public long discount(long beforeDiscount) {
+ return beforeDiscount * (percent / 100);
+ }
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/voucher/Voucher.java b/src/main/java/org/prgrms/kdtspringdemo/voucher/Voucher.java
new file mode 100644
index 0000000000..98417ea38f
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/voucher/Voucher.java
@@ -0,0 +1,11 @@
+package org.prgrms.kdtspringdemo.voucher;
+
+import java.util.UUID;
+
+public interface Voucher {
+ UUID getVoucherId();
+
+ String saveCSV();
+
+ long discount(long beforeDiscount);
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/voucher/VoucherRepository.java b/src/main/java/org/prgrms/kdtspringdemo/voucher/VoucherRepository.java
new file mode 100644
index 0000000000..cf65a03339
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/voucher/VoucherRepository.java
@@ -0,0 +1,13 @@
+package org.prgrms.kdtspringdemo.voucher;
+
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+public interface VoucherRepository {
+ public Optional findById(UUID voucherId);
+
+ public Voucher insert(Voucher voucher);
+
+ public Stream findAll();
+}
diff --git a/src/main/java/org/prgrms/kdtspringdemo/voucher/VoucherService.java b/src/main/java/org/prgrms/kdtspringdemo/voucher/VoucherService.java
new file mode 100644
index 0000000000..67e3a9dc3a
--- /dev/null
+++ b/src/main/java/org/prgrms/kdtspringdemo/voucher/VoucherService.java
@@ -0,0 +1,36 @@
+package org.prgrms.kdtspringdemo.voucher;
+
+import org.springframework.stereotype.Service;
+
+import java.text.MessageFormat;
+import java.util.UUID;
+import java.util.stream.Stream;
+
+@Service
+public class VoucherService {
+ private final VoucherRepository voucherRepository;
+
+ public VoucherService(VoucherRepository voucherRepository) {
+ this.voucherRepository = voucherRepository;
+ }
+
+ public Voucher getVoucher(UUID voucherId) {
+ return voucherRepository
+ .findById(voucherId)
+ .orElseThrow(() -> new RuntimeException(MessageFormat.format("Can not find a voucher for {0}", voucherId)));
+ }
+
+ // 이번 요구사항에 포함되지 않았습니다.
+ public void useVourcher(Voucher voucher) {
+ }
+
+ public Voucher saveVoucher(Voucher voucher) {
+ voucherRepository.insert(voucher);
+ return voucher;
+ }
+
+ public void printAllVoucher() {
+ Stream allVoucher = voucherRepository.findAll();
+ allVoucher.forEach(System.out::println);
+ }
+}
diff --git a/src/main/resources/application-local.yaml b/src/main/resources/application-local.yaml
new file mode 100644
index 0000000000..fa26ed4435
--- /dev/null
+++ b/src/main/resources/application-local.yaml
@@ -0,0 +1,7 @@
+kdt:
+ version: "v1.0-local"
+ minimum-order-amount: 1
+ support-vendors:
+ - a
+ description: |-
+ line 1 hello world
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000000..e6a71141de
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,7 @@
+#version = v1.0.0
+#
+#kdt.version = v1.0.0
+#
+#kdt.support-vendors = a, b, c, d, e, f, g
+#
+#kdt.minimum-order-amount = 1
\ No newline at end of file
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
new file mode 100644
index 0000000000..b299e6eef3
--- /dev/null
+++ b/src/main/resources/application.yaml
@@ -0,0 +1,16 @@
+kdt:
+ version: "v1.0"
+ minimum-order-amount: 1
+ support-vendors:
+ - a
+ - b
+ - c
+ - d
+ description: |-
+ line 1 hello world
+ line 2 xxxx
+ line 3
+
+spring:
+ profiles:
+ active: dev
\ No newline at end of file
diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt
new file mode 100644
index 0000000000..b3660a71d1
--- /dev/null
+++ b/src/main/resources/banner.txt
@@ -0,0 +1,8 @@
+# __ _ ___ ______ ____ ____ ____ _ ____ __ ____ ______ ____ ___ ____
+# | l/ ]| \ | T / T| \| \| T l j / ] / T| Tl j/ \ | \
+# | ' / | \ | | Y o || o ) o ) | | T / / Y o || | | TY Y| _ Y
+# | \ | D Yl_j l_j | || _/| _/| l___ | | / / | |l_j l_j | || O || | |
+# | Y| | | | | _ || | | | | T | |/ \_ | _ | | | | || || | |
+# | . || | | | | | || | | | | | j l\ || | | | | j ll !| | |
+# l__j\_jl_____j l__j l__j__jl__j l__j l_____j|____j\____jl__j__j l__j |____j\___/ l__j__j
+#
\ No newline at end of file
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000000..5c3c96afb0
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ ${CONSOLE_LOG_PATTERN}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ logs/access-%d{yyyy-MM-dd}.log
+
+
+ ${FILE_LOG_PATTERN}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/logback_fail.xml b/src/main/resources/logback_fail.xml
new file mode 100644
index 0000000000..6d7174ade6
--- /dev/null
+++ b/src/main/resources/logback_fail.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/sample.txt b/test/sample.txt
new file mode 100644
index 0000000000..f02196481c
--- /dev/null
+++ b/test/sample.txt
@@ -0,0 +1,2 @@
+hello I'm a sample file!
+Hi hi hmmm...
\ No newline at end of file
diff --git a/voucher.csv b/voucher.csv
new file mode 100644
index 0000000000..bf604953cf
--- /dev/null
+++ b/voucher.csv
@@ -0,0 +1,6 @@
+PercentDiscountVoucher,ea7bda51-f029-43f6-bcb2-d95afd77f83d,10
+FixedAmountVoucher,0042406f-f5ff-4b4a-b062-02fa6fc9eff7,20
+PercentDiscountVoucher,b7603e9e-dc0d-4376-8e7a-7bd4586955a6,111
+FixedAmountVoucher,ce26496d-c3eb-44ed-acbd-0e5a908b7b4a,22
+PercentDiscountVoucher,c43e3fdd-144d-4fdb-9cfb-183fa948dca7,3
+PercentDiscountVoucher,56699650-0a14-4d9c-9764-edc7218f2457,5