diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..42b5b3fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +.idea +out \ No newline at end of file diff --git a/src/READMD.md b/src/READMD.md new file mode 100644 index 00000000..c635db5f --- /dev/null +++ b/src/READMD.md @@ -0,0 +1,92 @@ +# 프로젝트 요구사항 + +## Customer + +### 명세서 + + +고객 속성 +- 고객 이름 +- 고객 아이디 +- 고객 스마트스토어를 이용시간 +- 고객 스마트스토어에서 구매한 총 결제금액서 +- Group 속성 추가 + +### 요구사항 + +- Customers - Refresh() 메서드 구현 +- Customers - Summary sort 메서드 구현 +- Customers - 정렬 로직 구현 + +### 해결책 및 코드 로직 + +1. 속성 만들기 +2. Getter, Setter 구현 + +## Group + +### 요구 사항 + +- Groups - find() 구현 + +### 명세서 + +- 분류 기준 : 시간 - 금액 + - General + - VIP + - VVIP + - NONE + +### 해결책 및 코드 로직 + + +1. Parameter (minTime, minPay) + +## Menu + +### 요구 사항 + +분류기준 +- 고객의 분류기준을 입력할 수 있다. +- 고객의 분류기준을 설정할 수 있다. +- 고객의 분류기준을 수정할 수 있다. + + +고객정보 +- 고객의 정보를 입력할 수 있다. +- 고객의 정보를 추가할 수 있다. +- 고객의 정보를 삭제할 수 있다. + + +고객 분류기능 +- 분류기준에 의해 고객을 분류할 수 있다. +- 분류기준에 의해 분류된 고객의 정보를 출력할 수 있다. +- 분류기준에 의해 분류된 고객의 정보를 이름순으로 정렬할 수 있다. +- 분류기준에 의해 분류된 고객의 정보를 총 이용시간 순으로 정렬할 수 있다. +- 분류기준에 의해 분류된 고객의 정보를 총 결제금액 순으로 정렬할 수 있다. + +### 해결책 및 코드 로직 + +1. GroupMenu + - Set Parameter + - View Parameter + - Update Parameter + +2. CustomerMenu + - Add Customer Data + - View Customer Data + - Update Customer Data + - Delete Customer Data + +3. SummaryMenu + - Summary view + - By Name Sort + - By Time Sort + - By Pay Sort + + +## TODO - Refactoring + +- [ ] Summary sort 반복적인 코드 일관성 있게 리펙토링 필요 +- [ ] TEST코드 구현 필요 +- [ ] 반복되는 코드 객체지향적으로 풀이 필요 diff --git a/src/me/smartstore/Main.java b/src/me/smartstore/Main.java new file mode 100644 index 00000000..c8a51d22 --- /dev/null +++ b/src/me/smartstore/Main.java @@ -0,0 +1,9 @@ +package me.smartstore; + +public class Main { + public static void main(String[] args) { + SmartStoreApp.getInstance().test().run(); // function chaining +// SmartStoreApp.getInstance().run(); + + } +} diff --git a/src/me/smartstore/SmartStoreApp.java b/src/me/smartstore/SmartStoreApp.java new file mode 100644 index 00000000..ebc16e3c --- /dev/null +++ b/src/me/smartstore/SmartStoreApp.java @@ -0,0 +1,67 @@ +package me.smartstore; + +import me.smartstore.customers.Customer; +import me.smartstore.customers.Customers; +import me.smartstore.groups.Group; +import me.smartstore.groups.GroupType; +import me.smartstore.groups.Groups; +import me.smartstore.groups.Parameter; +import me.smartstore.menu.MainMenu; +import me.smartstore.menu.Menu; + +public class SmartStoreApp { + private final Groups allGroups = Groups.getInstance(); + private final Customers allCustomers = Customers.getInstance(); + private final MainMenu mainMenu = MainMenu.getInstance(); + + // singleton + public static SmartStoreApp smartStoreApp; + + public static SmartStoreApp getInstance() { + if (smartStoreApp == null) { + smartStoreApp = new SmartStoreApp(); + } + return smartStoreApp; + } + + private SmartStoreApp() {} + + public void details() { + System.out.println("\n\n==========================================="); + System.out.println(" Title : SmartStore Customer Classification"); + System.out.println(" Release Date : 23.04.27"); + System.out.println(" Copyright 2023 Eunbin All rights reserved."); + System.out.println("===========================================\n"); + } + + // who type is SmartStoreApp + // 체이닝이 되어야 하니까. test().run() + public SmartStoreApp test() { + allGroups.add(new Group(new Parameter(0, 0), GroupType.NONE)); +// allGroups.add(new Group(new Parameter(10, 100000), GroupType.GENERAL)); + allGroups.add(new Group(new Parameter(20, 200000), GroupType.VIP)); + allGroups.add(new Group(new Parameter(30, 300000), GroupType.VVIP)); + + for (int i = 0; i < 26; i++) { + allCustomers.add(new Customer( + Character.toString((char)('a' + i)), + (char)('a' + i) + "123", + ((int) (Math.random() * 5)+ 1) * 10, + ((int) (Math.random() * 5) + 1) * 100000)); + } + + + System.out.println("allCustomers = " + allCustomers); + System.out.println("allGroups = " + allGroups); + + // @TODO +// allCustomers.refresh(allGroups); + + return this; + } + + public void run() { + details(); + mainMenu.manage(); + } +} diff --git a/src/me/smartstore/customers/Customer.java b/src/me/smartstore/customers/Customer.java new file mode 100644 index 00000000..4d1ed0a4 --- /dev/null +++ b/src/me/smartstore/customers/Customer.java @@ -0,0 +1,92 @@ +package me.smartstore.customers; + +import me.smartstore.groups.Group; + +import java.util.Objects; + +public class Customer { + private String cName; + private String cId; + private Integer totalTime; + private Integer totalPay; + private Group group; + + public Customer() { + } + + public Customer(String cName, String cId) { + this.cName = cName; + this.cId = cId; + } + + public Customer(String cName, String cId, Integer totalTime, Integer totalPay) { + this.cName = cName; + this.cId = cId; + this.totalTime = totalTime; + this.totalPay = totalPay; + } + + public String getcName() { + return cName; + } + + public void setcName(String cName) { + this.cName = cName; + } + + public String getcId() { + return cId; + } + + public void setcId(String cId) { + this.cId = cId; + } + + public Integer getTotalTime() { + return totalTime; + } + + public void setTotalTime(Integer totalTime) { + this.totalTime = totalTime; + } + + public Integer getTotalPay() { + return totalPay; + } + + public void setTotalPay(Integer totalPay) { + this.totalPay = totalPay; + } + + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Customer customer = (Customer) o; + return Objects.equals(cName, customer.cName) && Objects.equals(cId, customer.cId) && Objects.equals(totalTime, customer.totalTime) && Objects.equals(totalPay, customer.totalPay) && Objects.equals(group, customer.group); + } + + @Override + public int hashCode() { + return Objects.hash(cName, cId, totalTime, totalPay, group); + } + + @Override + public String toString() { + return "Customer{" + + "cName='" + cName + '\'' + + ", cId='" + cId + '\'' + + ", totalTime=" + totalTime + + ", totalPay=" + totalPay + + ", group=" + group + + '}'; + } +} diff --git a/src/me/smartstore/customers/Customers.java b/src/me/smartstore/customers/Customers.java new file mode 100644 index 00000000..802d6ed9 --- /dev/null +++ b/src/me/smartstore/customers/Customers.java @@ -0,0 +1,71 @@ +package me.smartstore.customers; + +import me.smartstore.groups.Group; +import me.smartstore.groups.Groups; +import me.smartstore.util.arrays.Array; + +import java.util.Arrays; +import java.util.Comparator; + +public class Customers extends Array { + private static Customers allCustomers; + private final Groups allGroups = Groups.getInstance(); + + public static Customers getInstance() { + if (allCustomers == null) { + allCustomers = new Customers(); + } + return allCustomers; + } + + private Customers() {}; + + public void refresh() { + for (int i = 0; i < allCustomers.size(); i++) { + Customer customer = allCustomers.get(i); + + + for (int j = 0; j < allGroups.size(); j++) { + Group group = allGroups.get(j); + + if (group.getParmeter().getMinTime() == null || group.getParmeter().getMinPayment() == null || + customer.getTotalPay() == null || customer.getTotalTime() == null) { + continue; + } + + if ((customer.getTotalTime() >= group.getParmeter().getMinTime()) && (customer.getTotalPay() >= group.getParmeter().getMinPayment())) { + customer.setGroup(group); + } + } + } + } + + + public Customer[] sortSummary(Comparator comparator) { + Customer[] customerArr = initCustomers(); + Arrays.sort(customerArr, comparator); + return customerArr; + } + + public Customer[] initCustomers() { + Customer[] customerArrs = new Customer[allCustomers.size()]; + + for (int i = 0; i < allCustomers.size(); i++) { + customerArrs[i] = allCustomers.get(i); + } + return customerArrs; + } + + public Comparator sortName(int num) { + return (customer1, customer2) -> num * customer1.getcName().compareTo(customer2.getcName()); + } + + public Comparator sortTime(int num) { + return (customer1, customer2) -> num * customer1.getTotalTime().compareTo(customer2.getTotalTime()); + } + + public Comparator sortPay(int num) { + return (customer1, customer2) -> num * customer1.getTotalPay().compareTo(customer2.getTotalPay()); + } + +}; diff --git a/src/me/smartstore/groups/Group.java b/src/me/smartstore/groups/Group.java new file mode 100644 index 00000000..0b6638c7 --- /dev/null +++ b/src/me/smartstore/groups/Group.java @@ -0,0 +1,56 @@ +package me.smartstore.groups; + +import java.util.Objects; + +public class Group { + + // 기준치를 가지는 Parameter + // 기준치를 GroupType에 따라 구분 + private Parameter parmeter; + private GroupType groupType; + + public Group() { + } + + public Group(Parameter parmeter, GroupType groupType) { + this.parmeter = parmeter; + this.groupType = groupType; + } + + public Parameter getParmeter() { + return parmeter; + } + + public void setParmeter(Parameter parmeter) { + this.parmeter = parmeter; + } + + public GroupType getGroupType() { + return groupType; + } + + public void setGroupType(GroupType groupType) { + this.groupType = groupType; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Group group = (Group) o; + return Objects.equals(parmeter, group.parmeter) && groupType == group.groupType; + } + + @Override + public int hashCode() { + return Objects.hash(parmeter, groupType); + } + + @Override + public String toString() { + return "Group{" + + "parmeter=" + parmeter + + ", groupType=" + groupType + + '}'; + } +} diff --git a/src/me/smartstore/groups/GroupType.java b/src/me/smartstore/groups/GroupType.java new file mode 100644 index 00000000..a8634bbd --- /dev/null +++ b/src/me/smartstore/groups/GroupType.java @@ -0,0 +1,26 @@ +package me.smartstore.groups; + +// N, G, V, VV +// NONE, GENERAL, VIP, VVIP +public enum GroupType { + NONE("해당없음"), GENERAL("일반고객"), VIP("우수고객"), VVIP("최우수고객"), + N("해당없음"), G("일반고객"), V("우수고객"), VV("최우수고객"); + + String groupType = ""; + + GroupType(String groupType) { + this.groupType = groupType; + } + + /* + * TODO : 엔터나, 특수문자 예외처리 생각하기 + * */ + public GroupType replaceFullName() { + if (this == N) return NONE; + else if (this == G) return GENERAL; + else if (this == V) return VIP; + else if (this == VV) return VVIP; + return this; + } + +} diff --git a/src/me/smartstore/groups/Groups.java b/src/me/smartstore/groups/Groups.java new file mode 100644 index 00000000..fc738243 --- /dev/null +++ b/src/me/smartstore/groups/Groups.java @@ -0,0 +1,30 @@ +package me.smartstore.groups; + +import me.smartstore.util.arrays.Array; + +public class Groups extends Array { + + // singleton + private static Groups allGroups; + private Parameter parameter; + + private Groups() {} + + public static Groups getInstance() { + if (allGroups == null) { + allGroups = new Groups(); + } + return allGroups; + } + + public Group find(GroupType groupType) { + for (int i = 0; i < allGroups.size(); i++) { + Group group = allGroups.get(i); + + if (group.getGroupType() == groupType) { + return group; + } + } + return null; + } +} diff --git a/src/me/smartstore/groups/Parameter.java b/src/me/smartstore/groups/Parameter.java new file mode 100644 index 00000000..396d7627 --- /dev/null +++ b/src/me/smartstore/groups/Parameter.java @@ -0,0 +1,51 @@ +package me.smartstore.groups; + +import java.util.Objects; + +public class Parameter { + private Integer minTime; + private Integer minPayment; + + public Parameter() {} + public Parameter(Integer minTime, Integer minPayment) { + this.minTime = minTime; + this.minPayment = minPayment; + } + + public Integer getMinTime() { + return minTime; + } + + public void setMinTime(Integer minTime) { + this.minTime = minTime; + } + + public Integer getMinPayment() { + return minPayment; + } + + public void setMinPayment(Integer minPayment) { + this.minPayment = minPayment; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Parameter parameter = (Parameter) o; + return Objects.equals(minTime, parameter.minTime) && Objects.equals(minPayment, parameter.minPayment); + } + + @Override + public int hashCode() { + return Objects.hash(minTime, minPayment); + } + + @Override + public String toString() { + return "Parameter{" + + "minTime=" + minTime + + ", minPayment=" + minPayment + + '}'; + } +} diff --git a/src/me/smartstore/menu/CustomerMenu.java b/src/me/smartstore/menu/CustomerMenu.java new file mode 100644 index 00000000..feec0e24 --- /dev/null +++ b/src/me/smartstore/menu/CustomerMenu.java @@ -0,0 +1,211 @@ +package me.smartstore.menu; + +import me.smartstore.customers.Customer; +import me.smartstore.customers.Customers; +import me.smartstore.util.Board; +import me.smartstore.util.Message; +import me.smartstore.util.exception.*; + +public class CustomerMenu implements Menu { + + // singleton + private static CustomerMenu customerMenu; + private final Customers allCustomers = Customers.getInstance(); + + public static CustomerMenu getInstance() { + if (customerMenu == null) { + customerMenu = new CustomerMenu(); + } + return customerMenu; + } + + private CustomerMenu() { + } + + @Override + public void manage() { + while (true) { + int choice = chooseMenu(Board.CUSTOMER_MENU.getBoard()); + + if (choice == 1) addCustomer(); + else if (choice == 2) viewCustomer(); + else if (choice == 3) updateCustomer(); + else if (choice == 4) deleteCustomer(); + else break; + + } + } + + private void addCustomer() { + while (true) { + try { + System.out.println("How many customers to input?"); + String choice = nextLine(Message.END_MSG); + Integer addNum = Integer.parseInt(choice); + + for (int i = 1; i < addNum + 1; i++) { + System.out.printf("====== Customer %d Info. ======\n", i); + Customer customer = new Customer(); + customerInfo(customer); + allCustomers.add(customer); + } + allCustomers.refresh(); + return; + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + + } catch (IllegalArgumentException | InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + + } catch (NullArgumentException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_NULL); + } + + } + } + + private void customerInfo(Customer customer) { + while (true) { + int choice = chooseMenu(Board.CUSTOMER_ADD_MENU.getBoard()); + + if (choice == 1) setCustomerName(customer); + else if (choice == 2) setCustomerId(customer); + else if (choice == 3) setCustomerSpentTime(customer); + else if (choice == 4) setCustomerTotalPay(customer); + else break; + } + } + + private void setCustomerName(Customer customer) { + try { + System.out.println("Input Customer's Name: "); + customer.setcName(nextLine(Message.END_MSG)); + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + } + } + + private void setCustomerId(Customer customer) { + try { + System.out.println("Input Customer's ID: "); + customer.setcId(nextLine(Message.END_MSG)); + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + } + } + + private void setCustomerSpentTime(Customer customer) { + try { + System.out.println("Input Customer's Spent Time: "); + Integer time = Integer.parseInt(nextLine(Message.END_MSG)); + if (time < 0) throw new InputRangeException(); + customer.setTotalTime(time); + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + + private void setCustomerTotalPay(Customer customer) { + try { + System.out.println("Input Customer's Total Pay: "); + Integer pay = Integer.parseInt(nextLine(Message.END_MSG)); + + if (pay < 0) throw new InputRangeException(); + customer.setTotalPay(pay); + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + + private void viewCustomer() { + try { + if (allCustomers.size() == 0) { + throw new EmptyArrayException(); + } else { + allCustomers.refresh(); + System.out.println("======= Customer Info. =======\n"); + for (int i = 0; i < allCustomers.size(); i++) { + System.out.printf("No. %d => %s\n", i + 1, allCustomers.get(i)); + } + } + } catch (EmptyArrayException e) { + System.out.println(Message.ERR_MSG_INVALID_ARR_EMPTY); + } + + } + + private void updateCustomer() { + viewCustomer(); + while ( true ) { + System.out.printf("\nWhich customer ( 1 ~ %d )?", allCustomers.size()); + + try { + Integer customerNumber = Integer.parseInt(nextLine(Message.END_MSG)); + if (customerNumber < 0 || customerNumber > allCustomers.size()) { + throw new InputRangeException(); + } + + Customer customer = allCustomers.get(customerNumber - 1); + customerInfo(customer); + allCustomers.refresh(); + return; + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + } + + private void deleteCustomer() { + viewCustomer(); + while ( true ) { + System.out.printf("\nWhich customer ( 1 ~ %d )?", allCustomers.size()); + + try { + Integer customerNumber = Integer.parseInt(nextLine(Message.END_MSG)); + if (customerNumber < 0 || customerNumber > allCustomers.size()) { + throw new InputRangeException(); + } + + System.out.println(allCustomers.pop(customerNumber - 1)); + viewCustomer(); + return; + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + } +} diff --git a/src/me/smartstore/menu/GroupMenu.java b/src/me/smartstore/menu/GroupMenu.java new file mode 100644 index 00000000..b16ee7bd --- /dev/null +++ b/src/me/smartstore/menu/GroupMenu.java @@ -0,0 +1,218 @@ +package me.smartstore.menu; + +import me.smartstore.customers.Customers; +import me.smartstore.groups.Group; +import me.smartstore.groups.GroupType; +import me.smartstore.groups.Groups; +import me.smartstore.groups.Parameter; +import me.smartstore.util.Board; +import me.smartstore.util.Message; +import me.smartstore.util.exception.InputEndException; +import me.smartstore.util.exception.InputRangeException; +import me.smartstore.util.exception.NullArgumentException; + +public class GroupMenu implements Menu { + private final Groups allGroups = Groups.getInstance(); + private final Customers allCustomers = Customers.getInstance(); + // singleton + + private static GroupMenu groupMenu; + + public static GroupMenu getInstance() { + if (groupMenu == null) { + groupMenu = new GroupMenu(); + } + return groupMenu; + } + + private GroupMenu() {} + + @Override + public void manage() { + while ( true ) { + int choice = chooseMenu(Board.GROUP_MENU.getBoard()); + + if (choice == 1) setParameter(); + else if (choice == 2) viewParameter(); + else if (choice == 3) updateParameter(); + else break; + } + } + + /* + * chooseGroup() 못쓰게 됌 : setParameter()에서 값을 못가져 오는 이슈 + * */ + + /* + * 가장 처음 초기화 할 때 + * 값이 있을 경우 + * @ group(choice) -> GroupType(enum) + * @ E -> GroupType.E : Error + * => IllegalArgumentException + * */ + private void setParameter() { + while (true) { + try { + System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? "); + String choice = nextLine(Message.END_MSG); + GroupType groupType = GroupType.valueOf(choice).replaceFullName(); + Group group = allGroups.find(groupType); + + if (group != null && group.getParmeter() != null) { + System.out.println("\n" + group.getGroupType() + " group already exists."); + } else { + Parameter parameter = new Parameter(); + setParameterValue(parameter, groupType); + allCustomers.refresh(); + } + System.out.println("\nGroupType: " + groupType); + + if (group == null) { + System.out.println("Parameter: " + group); + } else { + System.out.println("Parameter: " + group.getParmeter()); + } + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + + } catch (IllegalArgumentException | InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + + } catch (NullArgumentException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_NULL); + } + } + } + + private void setParameterValue(Parameter parameter, GroupType groupType) { + while (true) { + + int choice = chooseMenu(Board.PARAMETER_MENU.getBoard()); + + if (choice == 1) { + while (true) { + try { + System.out.println("\nInput Minimum Spent Time:"); + String minSpentTime = nextLine(Message.END_MSG); + + if (Integer.parseInt(minSpentTime) < 0) { + throw new InputRangeException(); + } + + parameter.setMinTime(Integer.parseInt(minSpentTime)); +// System.out.println(parameter); + System.out.println(); + break; + + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + System.out.println(); + + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + System.out.println(); + } + } + } else if (choice == 2) { + while (true) { + try { + System.out.println("\nInput Minimum Total Pay:"); + String minPayment = nextLine(Message.END_MSG); + + if (Integer.parseInt(minPayment) < 0) { + throw new InputRangeException(); + } + + parameter.setMinPayment(Integer.parseInt(minPayment)); +// System.out.println(parameter); + System.out.println(); + break; + + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + System.out.println(); + + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + System.out.println(); + } + } + } else { + if (allGroups.find(groupType) == null) { + allGroups.add(new Group(new Parameter(parameter.getMinTime(), parameter.getMinPayment()), groupType)); + } + break; + } + } + } + + private void viewParameter() { + while ( true ) { + try { + System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? "); + String choice = nextLine(Message.END_MSG); + GroupType groupType = GroupType.valueOf(choice).replaceFullName(); + Group group = allGroups.find(groupType); + + System.out.println("\nGroupType: " + groupType); + if (group == null) { + System.out.println("Parameter: " + group); + } else { + System.out.println("Parameter: " + group.getParmeter()); + } + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + + } catch (IllegalArgumentException | InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + + } catch (NullArgumentException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_NULL); + } + } + } + + private void updateParameter() { + while ( true ) { + try { + System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? "); + String choice = nextLine(Message.END_MSG); + GroupType groupType = GroupType.valueOf(choice).replaceFullName(); + Group group = allGroups.find(groupType); + + if (group == null) { + System.out.println("No parameter. Set the parameter first."); + break; + } + else { + Parameter parameter = group.getParmeter(); + setParameterValue(parameter, groupType); + group.setParmeter(parameter); + allCustomers.refresh(); + } + + System.out.println("\nGroupType: " + groupType); + + if (group == null) { + System.out.println("Parameter: " + group); + } else { + System.out.println("Parameter: " + group.getParmeter()); + } + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + + } catch (IllegalArgumentException | InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + + } catch (NullArgumentException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_NULL); + } + } + } + +} diff --git a/src/me/smartstore/menu/MainMenu.java b/src/me/smartstore/menu/MainMenu.java new file mode 100644 index 00000000..46411cc8 --- /dev/null +++ b/src/me/smartstore/menu/MainMenu.java @@ -0,0 +1,38 @@ +package me.smartstore.menu; + +import me.smartstore.util.Board; + + +public class MainMenu implements Menu { + private final CustomerMenu customerMenu = CustomerMenu.getInstance(); + private final GroupMenu groupMenu = GroupMenu.getInstance(); + private final SummaryMenu summaryMenu = SummaryMenu.getInstance(); + + + // singleton + public static MainMenu mainMenu; + + public static MainMenu getInstance() { + if (mainMenu == null) { + mainMenu = new MainMenu(); + } + return mainMenu; + } + + private MainMenu() {} + + @Override + public void manage() { + while (true) { + int choice = mainMenu.chooseMenu(Board.MAIN_MENU.getBoard()); + + if (choice == 1) groupMenu.manage(); + else if (choice == 2) customerMenu.manage(); + else if (choice == 3) summaryMenu.manage(); + else if (choice == 4) { + System.out.println("Program Finished"); + break; + } + } + } +} diff --git a/src/me/smartstore/menu/Menu.java b/src/me/smartstore/menu/Menu.java new file mode 100644 index 00000000..ff881be7 --- /dev/null +++ b/src/me/smartstore/menu/Menu.java @@ -0,0 +1,64 @@ +package me.smartstore.menu; + +import me.smartstore.util.exception.InputEndException; +import me.smartstore.util.exception.InputRangeException; +import me.smartstore.util.Message; + +import java.util.Scanner; + +public interface Menu { + Scanner scanner = new Scanner(System.in); + + default String nextLine() { + return scanner.nextLine().toUpperCase(); + } + + default String nextLine(String end) { + System.out.println(" ** Press 'end', if you want to exit! ** "); + String str = scanner.nextLine().toUpperCase(); + if (str.equals(end)) throw new InputEndException(); + return str; + } + + // TODO Empty 들어올 경우 + + default void displayMenu(String[] menus) { + System.out.println("==========================================="); + for (int i = 0; i < menus.length; i++) { + System.out.printf(" %d. %s\n", i + 1, menus[i]); + } + System.out.println("==========================================="); + System.out.print("Choose One: "); + + } + + /* + * @nextInt()를 안쓰는 이유 : 문자가 들어오면 한번더 체크 해주는 이슈 + * @NumberFormatException : 잘못된 값 들어온 경우 (문자, 특수문자... etc) + * @InputRangeException : 숫자인데 범위 넘어간 경우 + * */ + default int chooseMenu(String[] menus) { + while (true) { + try { + displayMenu(menus); + int choice = Integer.parseInt(nextLine()); + System.out.println(); + if (choice >= 1 && choice <= menus.length) return choice; + throw new InputRangeException(); + + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + System.out.println(); + + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + System.out.println(); + } + } + } + /* + * @manage() : 서브 메뉴들 관리하는 함수 + * */ + + void manage(); +} \ No newline at end of file diff --git a/src/me/smartstore/menu/SortType.java b/src/me/smartstore/menu/SortType.java new file mode 100644 index 00000000..c32c27ae --- /dev/null +++ b/src/me/smartstore/menu/SortType.java @@ -0,0 +1,13 @@ +package me.smartstore.menu; + +public enum SortType { + BYNAME, BYTIME, BYPAY; + + String sortType = ""; + + SortType(String sortType) { + this.sortType = sortType; + } + + SortType() {} +} diff --git a/src/me/smartstore/menu/SummaryMenu.java b/src/me/smartstore/menu/SummaryMenu.java new file mode 100644 index 00000000..4a7af5eb --- /dev/null +++ b/src/me/smartstore/menu/SummaryMenu.java @@ -0,0 +1,126 @@ +package me.smartstore.menu; + + +import me.smartstore.customers.Customer; +import me.smartstore.customers.Customers; +import me.smartstore.groups.Group; +import me.smartstore.groups.GroupType; +import me.smartstore.groups.Groups; +import me.smartstore.util.Board; +import me.smartstore.util.Message; +import me.smartstore.util.exception.InputEndException; +import me.smartstore.util.exception.InputFormatException; + +import java.util.Comparator; + +import static me.smartstore.groups.GroupType.*; + +public class SummaryMenu implements Menu { + private final Groups allGroups = Groups.getInstance(); + private final Customers allCustomers = Customers.getInstance(); + // singleton + + private static SummaryMenu summaryMenu; + + public static SummaryMenu getInstance() { + if (summaryMenu == null) { + summaryMenu = new SummaryMenu(); + } + return summaryMenu; + } + + private SummaryMenu() {} + + @Override + public void manage() { + while ( true ) { + int choice = chooseMenu(Board.SUMMARY_MENU.getBoard()); + + if (choice == 1) getSummary(allCustomers.initCustomers()); + else if (choice == 2) getSortSummary(SortType.BYNAME); + else if (choice == 3) getSortSummary(SortType.BYTIME); + else if (choice == 4) getSortSummary(SortType.BYPAY); + else break; + } + } + private void getSummary(Customer[] customers) { + allCustomers.refresh(); + GroupType[] groupType = {NONE, GENERAL, VIP, VVIP}; + + for (GroupType type : groupType) { + displaySummary(customers, type); + } + } + private void displaySummary(Customer[] customers, GroupType type) { + Group group = allGroups.find(type); + Integer time = null; + Integer pay = null; + + int count = 1; + if (group != null) { + time = group.getParmeter().getMinTime(); + pay = group.getParmeter().getMinPayment(); + + System.out.println("=============================="); + System.out.printf("Group : %s ( Time : %d, Pay : %d )\n", type, time, pay); + System.out.println("=============================="); + + for (int i = 0; i < allCustomers.size(); i++) { + if (customers[i].getGroup().getGroupType().equals(type)) { + System.out.printf("No. %d => %s\n", count++, customers[i]); + } + } + } + else if (group == null) { + System.out.println("=============================="); + System.out.printf("Group : %s ( Time : %d, Pay : %d )\n", type, time, pay); + System.out.println("=============================="); + System.out.println(group); + } + System.out.println("==============================\n"); + } + + /* + * Comparator comparator + * 따로 구현 enum으로 구현 + * @TODO Refactoring + * */ + private void getSortSummary(SortType sortType) { + while ( true ) { + try { + System.out.println("\nWhich order (ASCENDING (A), DESCENDING (D))?"); + String choice = nextLine(Message.END_MSG); + int positiveNum = 0; + + if (choice.equals("A") || choice.equals("ASCENDING")) { + positiveNum = 1; + } else if (choice.equals("D") || choice.equals("DESCENDING")) { + positiveNum = -1; + } + + if (sortType == SortType.BYNAME) { + getSummary(allCustomers.sortSummary(allCustomers.sortName(positiveNum))); + } + else if (sortType == SortType.BYTIME) { + getSummary(allCustomers.sortSummary(allCustomers.sortTime(positiveNum))); + } + else if (sortType == SortType.BYPAY) { + getSummary(allCustomers.sortSummary(allCustomers.sortPay(positiveNum))); + } + + } catch (InputEndException e) { + System.out.println(e.getMessage()); + break; + + } catch (InputFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_TYPE); + + } catch (IllegalArgumentException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + } + + } + + } + +} diff --git a/src/me/smartstore/util/Board.java b/src/me/smartstore/util/Board.java new file mode 100644 index 00000000..aece9e28 --- /dev/null +++ b/src/me/smartstore/util/Board.java @@ -0,0 +1,63 @@ +package me.smartstore.util; + +public enum Board { + /* + * @parameter String[] 생성하는 과정에서 오류 발생 + * 왜 new 키워드를 사용해서 만들어야 하는지 + * */ + MAIN_MENU(new String[] { + "Parameter", + "Customer Data", + "Classification Summary", + "Quit" + }), + GROUP_MENU(new String[] { + "Set Parameter", + "View Parameter", + "Update Parameter", + "Back" + + }), + + CUSTOMER_MENU(new String[] { + "Add Customer", + "View Customer", + "Update Customer", + "Delete Customer", + "Back" + }), + + SUMMARY_MENU(new String[] { + "Summary", + "Summary (Sorted By Name)", + "Summary (Sorted By Time)", + "Summary (Sorted By Pay)", + "Back" + }), + + PARAMETER_MENU(new String[] { + "Minimum Spent Time", + "Minimum Total Pay", + "Back" + }), + + CUSTOMER_ADD_MENU(new String[] { + "Customer Name", + "Customer ID", + "Customer Spent Time", + "Customer Total Pay", + "Back" + }) + + ; + + private final String[] board; + + Board(String[] board) { + this.board = board; + } + + public String[] getBoard() { + return board; + } +} diff --git a/src/me/smartstore/util/Message.java b/src/me/smartstore/util/Message.java new file mode 100644 index 00000000..1c67d21e --- /dev/null +++ b/src/me/smartstore/util/Message.java @@ -0,0 +1,13 @@ +package me.smartstore.util; + +public interface Message { + String ERR_MSG_INVALID_ARR_EMPTY = "No Customers. Please input one first."; + String ERR_MSG_NULL_ARR_ELEMENT = "Elements in Array has null. Array can't be sorted."; + String ERR_MSG_INVALID_INPUT_NULL = "Null Input. Please input something."; + String ERR_MSG_INVALID_INPUT_EMPTY = "Empty Input. Please input something."; + String ERR_MSG_INVALID_INPUT_RANGE = "Invalid Input. Please try again."; + String ERR_MSG_INVALID_INPUT_TYPE = "Invalid Type for Input. Please try again."; + String ERR_MSG_INVALID_INPUT_FORMAT = "Invalid Format for Input. Please try again."; + String ERR_MSG_INPUT_END = "END is pressed. Exit this menu."; + String END_MSG = "END"; +} diff --git a/src/me/smartstore/util/exception/ElementNotFoundException.java b/src/me/smartstore/util/exception/ElementNotFoundException.java new file mode 100644 index 00000000..4b75a078 --- /dev/null +++ b/src/me/smartstore/util/exception/ElementNotFoundException.java @@ -0,0 +1,23 @@ +package me.smartstore.util.exception; + +public class ElementNotFoundException extends RuntimeException { + public ElementNotFoundException() { + super(); + } + + public ElementNotFoundException(String message) { + super(message); + } + + public ElementNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public ElementNotFoundException(Throwable cause) { + super(cause); + } + + protected ElementNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/me/smartstore/util/exception/EmptyArrayException.java b/src/me/smartstore/util/exception/EmptyArrayException.java new file mode 100644 index 00000000..83ae6615 --- /dev/null +++ b/src/me/smartstore/util/exception/EmptyArrayException.java @@ -0,0 +1,23 @@ +package me.smartstore.util.exception; + +public class EmptyArrayException extends RuntimeException { + public EmptyArrayException() { + super(); + } + + public EmptyArrayException(String message) { + super(message); + } + + public EmptyArrayException(String message, Throwable cause) { + super(message, cause); + } + + public EmptyArrayException(Throwable cause) { + super(cause); + } + + protected EmptyArrayException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/me/smartstore/util/exception/InputEmptyException.java b/src/me/smartstore/util/exception/InputEmptyException.java new file mode 100644 index 00000000..2b3a76bc --- /dev/null +++ b/src/me/smartstore/util/exception/InputEmptyException.java @@ -0,0 +1,25 @@ +package me.smartstore.util.exception; + +import me.smartstore.util.Message; + +public class InputEmptyException extends RuntimeException { + public InputEmptyException() { + super(Message.ERR_MSG_INVALID_INPUT_EMPTY); + } + + public InputEmptyException(String message) { + super(message); + } + + public InputEmptyException(String message, Throwable cause) { + super(message, cause); + } + + public InputEmptyException(Throwable cause) { + super(cause); + } + + protected InputEmptyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/me/smartstore/util/exception/InputEndException.java b/src/me/smartstore/util/exception/InputEndException.java new file mode 100644 index 00000000..05f34d6b --- /dev/null +++ b/src/me/smartstore/util/exception/InputEndException.java @@ -0,0 +1,25 @@ +package me.smartstore.util.exception; + +import me.smartstore.util.Message; + +public class InputEndException extends RuntimeException { + public InputEndException() { + super(Message.ERR_MSG_INPUT_END); + } + + public InputEndException(String message) { + super(message); + } + + public InputEndException(String message, Throwable cause) { + super(message, cause); + } + + public InputEndException(Throwable cause) { + super(cause); + } + + protected InputEndException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/me/smartstore/util/exception/InputFormatException.java b/src/me/smartstore/util/exception/InputFormatException.java new file mode 100644 index 00000000..6fc3c0ff --- /dev/null +++ b/src/me/smartstore/util/exception/InputFormatException.java @@ -0,0 +1,25 @@ +package me.smartstore.util.exception; + +import me.smartstore.util.Message; + +public class InputFormatException extends RuntimeException { + public InputFormatException() { + super(Message.ERR_MSG_INVALID_INPUT_FORMAT); + } + + public InputFormatException(String message) { + super(message); + } + + public InputFormatException(String message, Throwable cause) { + super(message, cause); + } + + public InputFormatException(Throwable cause) { + super(cause); + } + + protected InputFormatException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/me/smartstore/util/exception/InputRangeException.java b/src/me/smartstore/util/exception/InputRangeException.java new file mode 100644 index 00000000..4b692d47 --- /dev/null +++ b/src/me/smartstore/util/exception/InputRangeException.java @@ -0,0 +1,27 @@ +package me.smartstore.util.exception; + +import me.smartstore.util.Message; + +public class InputRangeException extends RuntimeException { + public InputRangeException() { + super(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + + public InputRangeException(String message) { + super(message); + } + + // cause 기존 예외 + // 예외 전환을 위해 Throwable 사용 + public InputRangeException(String message, Throwable cause) { + super(message, cause); + } + + public InputRangeException(Throwable cause) { + super(cause); + } + + protected InputRangeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/me/smartstore/util/exception/NullArgumentException.java b/src/me/smartstore/util/exception/NullArgumentException.java new file mode 100644 index 00000000..eecabe12 --- /dev/null +++ b/src/me/smartstore/util/exception/NullArgumentException.java @@ -0,0 +1,23 @@ +package me.smartstore.util.exception; + +public class NullArgumentException extends RuntimeException { + public NullArgumentException() { + super(); + } + + public NullArgumentException(String message) { + super(message); + } + + public NullArgumentException(String message, Throwable cause) { + super(message, cause); + } + + public NullArgumentException(Throwable cause) { + super(cause); + } + + protected NullArgumentException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +}