diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..e0d52eb7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/out/
+/.idea/
diff --git a/README.md b/README.md
index b0eb52bb..53d0ef47 100644
--- a/README.md
+++ b/README.md
@@ -1,33 +1,9 @@
### 자바 토이프로젝트
-> 제출자 - 최은빈
+> 제출자 - 배종윤
> 출시일 - 23.04.27.
-> 제출일 - 23.05.10.
-
-- [프로젝트 설명서](https://echoiing-fastcampus.notion.site/Smart-Store-47ea8a0b4b084301bd1eefbabe3426af)를 풀어서 제출하시오. 💻
-
-- 파일 이름 작성법 📂
- - ````me.smartstore```` 패키지 생성
-- 제출방법
- - 본인의 이름으로 ````branch````를 생성하여 ````push````후 ````pull request```` 작성
- - 예시
- - branch 이름 - ````FirstNameLastName````
- - commit 메시지 (멘토 리뷰 이전) - [1차 VER1.0...] Java ToyProject upload by FirstNameLastName (labeling도 가능: ````first````)
- - commit 메시지 (멘토 리뷰 이전) - [1차 VER2.0...] Java ToyProject upload by FirstNameLastName (labeling도 가능: ````second````)
- - commit 메시지 (멘토 리뷰 이후) - [2차] Java ToyProject upload by FirstNameLastName (labeling도 가능: ````resubmit````)
- - PR 메시지는 본인이 하고 싶은 말이나 질문을 적어주세요.
- - ````코드리뷰 빡세게 부탁드립니다.```` ````클린한 코드인지 봐주세요.```` ````이 코드의 조금 더 나은 방법이 있을까요.````
- - ````~~번 문제 풀지 못했습니다.```` ````~~번 문제 풀이 방법을 알려주시면 감사하겠습니다.````
- - ````결과는 나왔는데 맞는지 모르겠습니다.````
-- 리뷰관련 [프로세스 🔖](https://quickest-asterisk-75d.notion.site/a8d233d87f0945cbaa8f71300515587d?p=b658d277f52843dd9e1e8322233c9006&pm=s)
- - ```PEER REVIEW``` - 과제 기간동안 본인 과제 완료 후, 다른 수강생들의 PR을 보며 피어리뷰 가능 (댓글 이용)
- - ```MENTOR REVIEW``` - 과제 기간 이후에 멘토진 코드 리뷰 (댓글 이용)
- - 멘토님이 작성한 댓글 이후에는 수강생이 댓글 자제 (혼선 막기 위함)
-- 주의사항 🔥
- - 본인 ```branch``` -> ```main branch``` PR 상태로 제출부탁드립니다.
- - ```main branch```에 본인 ```branch```의 ```commit```을 ```merge``` 하지 마시기 바랍니다.
- - ```git ignore``` 활용 적극 권장 ‼
- - 문제풀이 코드가 아닌 .idea, out과 같은 파일은 제출 하지 마세요 🥲
+> 제출일 - 23.05.15.
+
diff --git a/src/com/smartstore/Main.java b/src/com/smartstore/Main.java
new file mode 100644
index 00000000..90600886
--- /dev/null
+++ b/src/com/smartstore/Main.java
@@ -0,0 +1,8 @@
+package com.smartstore;
+
+public class Main {
+ public static void main(String[] args) {
+ SmartStore.run();
+ //Test.run();
+ }
+}
diff --git a/src/com/smartstore/SmartStore.java b/src/com/smartstore/SmartStore.java
new file mode 100644
index 00000000..62513a3e
--- /dev/null
+++ b/src/com/smartstore/SmartStore.java
@@ -0,0 +1,11 @@
+package com.smartstore;
+
+import com.smartstore.util.Function;
+import com.smartstore.function.mainmenu.MainMenuFunction;
+
+public class SmartStore {
+ public static void run(){
+ //Load Initial Screen
+ Function.of(0, MainMenuFunction.class).run();
+ }
+}
diff --git a/src/com/smartstore/Test.java b/src/com/smartstore/Test.java
new file mode 100644
index 00000000..70fa4bc9
--- /dev/null
+++ b/src/com/smartstore/Test.java
@@ -0,0 +1,35 @@
+package com.smartstore;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.function.membership.set.SetMembershipHandler;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.util.CustomList;
+
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class Test {
+ public static void run() {
+ SetMembershipHandler setMembershipHandler = new SetMembershipHandler() {
+ @Override
+ public void run(T value) {
+
+ }
+ };
+ setMembershipHandler.setMembershipRequirement(MembershipType.GENERAL,3,5);
+ setMembershipHandler.setMembershipRequirement(MembershipType.VIP,3,10);
+ setMembershipHandler.setMembershipRequirement(MembershipType.VVIP,10,15);
+
+ CustomList customerList = Customers.getInstance().getCustomerList();
+ Random random = new Random();
+
+ for(int i = 0 ; i < 28 ; i++ ){
+ String name = String.valueOf(((char)(ThreadLocalRandom.current().nextInt(97, 122+1))));
+ String id = "id"+random.nextInt(100)+1;
+ customerList.add(new Customer(name, id, random.nextInt(28)+1, random.nextInt(28)+1));
+ }
+
+ SmartStore.run();
+ }
+}
diff --git a/src/com/smartstore/customer/Customer.java b/src/com/smartstore/customer/Customer.java
new file mode 100644
index 00000000..c939e37e
--- /dev/null
+++ b/src/com/smartstore/customer/Customer.java
@@ -0,0 +1,111 @@
+package com.smartstore.customer;
+
+import com.smartstore.membership.MembershipRequirement;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.membership.Memberships;
+import com.smartstore.util.CustomEnumMap;
+
+public class Customer {
+ private String customerId;
+ private String customerName;
+
+ private int usageTime;
+ private int paymentAmount;
+ private MembershipType membership;
+
+ public Customer() {
+ }
+
+ public Customer(String customerName, String customerId, int usageTime, int paymentAmount) {
+ this.customerId = customerId;
+ this.customerName = customerName;
+ this.usageTime = usageTime;
+ this.paymentAmount = paymentAmount;
+ setMembership(usageTime, paymentAmount);
+ }
+
+ public void setMembership(int usageTime, int paymentAmount) {
+ Memberships memberships = Memberships.getInstance();
+ MembershipType membership = MembershipType.NONE;
+ //Map is CustomMap
+ CustomEnumMap membershipList = memberships.getMembershipMap();
+ int currentUsageTime;
+ int currentPaymentTime;
+ boolean isUsageLowerThenCurrent;
+ boolean isPaymentLowerThenCurrent;
+ for(MembershipType membershipType : MembershipType.values()){
+ try {
+ currentUsageTime = membershipType == MembershipType.NONE ? 0 : membershipList.get(membershipType).getMinUsageTime();
+ currentPaymentTime = membershipType == MembershipType.NONE ? 0 : membershipList.get(membershipType).getMinPaymentAmount();
+
+ isUsageLowerThenCurrent = usageTime < currentUsageTime;
+ isPaymentLowerThenCurrent = paymentAmount < currentPaymentTime;
+
+ if(!isUsageLowerThenCurrent){
+ if (!isPaymentLowerThenCurrent){
+ membership = membershipType;
+ } else{
+ break;
+ }
+ } else {
+ break;
+ }
+ }catch (NullPointerException e){
+ //Set General(lowers Membership) is not Set yet
+ //Set Membership as null
+ membership = MembershipType.NONE;
+ }
+
+ }
+ this.membership = membership;
+ }
+
+ public void updateMembership(){
+ setMembership(usageTime, paymentAmount);
+ }
+
+ public String getCustomerId() {
+ return customerId;
+ }
+
+ public String getCustomerName() {
+ return customerName;
+ }
+
+ public int getUsageTime() {
+ return usageTime;
+ }
+
+ public int getPaymentAmount() {
+ return paymentAmount;
+ }
+
+ public MembershipType getMembership() {
+ return membership;
+ }
+
+ public void setCustomerId(String customerId) {
+ this.customerId = customerId;
+ }
+
+ public void setCustomerName(String customerName) {
+ this.customerName = customerName;
+ }
+
+ public void setUsageTime(int usageTime) {
+ this.usageTime = usageTime;
+ }
+
+ public void setPaymentAmount(int paymentAmount) {
+ this.paymentAmount = paymentAmount;
+ }
+ @Override
+ public String toString() {
+ return "customerId='" + customerId + '\'' +
+ ", customerName='" + customerName + '\'' +
+ ", usageTime=" + usageTime +
+ ", paymentAmount=" + paymentAmount +
+ ", membership=" + membership +
+ "\n";
+ }
+}
diff --git a/src/com/smartstore/customer/Customers.java b/src/com/smartstore/customer/Customers.java
new file mode 100644
index 00000000..437fbf60
--- /dev/null
+++ b/src/com/smartstore/customer/Customers.java
@@ -0,0 +1,47 @@
+package com.smartstore.customer;
+
+import com.smartstore.util.CustomList;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+public class Customers {
+ private static Customers instance;
+
+ private Customers() {
+
+ }
+
+ public static Customers getInstance(){
+ if(instance == null){
+ instance = new Customers();
+ }
+ return instance;
+ }
+ private final CustomList customerList = new CustomList();
+
+ public CustomList getCustomerList() {
+ return customerList;
+ }
+
+ public Customer getCustomerById(String id){
+ if(customerList.size() == 0){
+ return null;
+ }
+ Optional customerOptional = Arrays.stream(customerList.toArray(new Customer[customerList.size()]))
+ .filter(customer -> id.equals(customer.getCustomerId()))
+ .findFirst();
+ return customerOptional.orElse(null);
+ }
+
+ public void updateMembership(){
+ if(customerList.size() == 0){
+ return;
+ }
+ Customer[] customerArray = customerList.toArray(new Customer[customerList.size()]);
+ for(Customer customer : customerArray){
+ customer.setMembership(customer.getUsageTime(), customer.getPaymentAmount());
+ }
+ }
+
+}
diff --git a/src/com/smartstore/function/Back.java b/src/com/smartstore/function/Back.java
new file mode 100644
index 00000000..b7cdb0ee
--- /dev/null
+++ b/src/com/smartstore/function/Back.java
@@ -0,0 +1,41 @@
+package com.smartstore.function;
+
+
+import com.smartstore.util.Handleable;
+import com.smartstore.util.HandleableParam;
+import com.smartstore.util.Handler;
+
+public class Back implements Handler, HandleableParam, Handleable {
+ private static Back instance;
+
+ private Back(){
+
+ }
+
+ public static Back getInstance() {
+ if(instance == null){
+ instance = new Back();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run() {
+
+ }
+
+ @Override
+ public boolean handleChoice(String menuNumber) {
+ return false;
+ }
+
+ @Override
+ public int getCurrentMenuNumber() {
+ return 0;
+ }
+
+ @Override
+ public void run(T value) {
+
+ }
+}
diff --git a/src/com/smartstore/function/customer/CustomerFunction.java b/src/com/smartstore/function/customer/CustomerFunction.java
new file mode 100644
index 00000000..36384114
--- /dev/null
+++ b/src/com/smartstore/function/customer/CustomerFunction.java
@@ -0,0 +1,43 @@
+package com.smartstore.function.customer;
+
+import com.smartstore.util.Function;
+import com.smartstore.util.Handleable;
+import com.smartstore.function.Back;
+import com.smartstore.function.customer.add.AddCustomer;
+import com.smartstore.function.customer.delete.DeleteCustomer;
+import com.smartstore.function.customer.update.UpdateCustomer;
+import com.smartstore.function.customer.view.ViewCustomer;
+
+public enum CustomerFunction implements Function {
+ ADD(1, AddCustomer.getInstance(), "Add Customer Data"),
+ VIEW(2, ViewCustomer.getInstance(), "View Customer Data"),
+ UPDATE(3, UpdateCustomer.getInstance(), "Update Customer Data"),
+ DELETE(4, DeleteCustomer.getInstance(), "Delete Customer Data"),
+ BACK(5, Back.getInstance(), "Return to Prev Menu");
+
+ private final int menuNumber;
+ private final Handleable handler;
+
+ private final String menuText;
+ CustomerFunction(int menuNumber, Handleable handler, String menuText) {
+ this.menuNumber = menuNumber;
+ this.handler = handler;
+ this.menuText = menuText;
+ }
+
+ @Override
+ public String getMenuText() {
+ return menuText;
+ }
+
+ @Override
+ public int getMenuNumber() {
+ return this.menuNumber;
+ }
+
+ @Override
+ public Handleable getMenuHandler() {
+ return this.handler;
+ }
+
+}
diff --git a/src/com/smartstore/function/customer/CustomerMenuHandler.java b/src/com/smartstore/function/customer/CustomerMenuHandler.java
new file mode 100644
index 00000000..3dd993a2
--- /dev/null
+++ b/src/com/smartstore/function/customer/CustomerMenuHandler.java
@@ -0,0 +1,50 @@
+package com.smartstore.function.customer;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.function.customer.update.UpdateCustomerFunction;
+import com.smartstore.function.mainmenu.MainMenuFunction;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.util.EnumValueProvider;
+import com.smartstore.util.Handler;
+import com.smartstore.util.Printer;
+import com.smartstore.util.Validator;
+
+public interface CustomerMenuHandler extends EnumValueProvider, Handler {
+
+ default void run() {
+ boolean isExit = false;
+ while (!isExit){
+ //get values from enum by string array
+ Printer.printMenu(getMenuListFromEnum(MembershipType.class));
+
+ isExit = handleChoice(Validator.getMenuNumber(new String[]{}));
+ }
+ }
+
+ @Override
+ default boolean handleChoice(String id){
+ if(!"end".equalsIgnoreCase(id)){
+ //run each function's method
+ boolean isExit = false;
+ Customer selected;
+ selected = Customers.getInstance().getCustomerById(id);
+ if(selected == null){
+ System.out.printf("There is No User : %s\n", id);
+ return false;
+ }
+ System.out.printf("Current Customer Info\n%s", selected);
+ while (!isExit){
+ Printer.printMenu(getMenuListFromEnum(UpdateCustomerFunction.class));
+ //get menu number from user until valid menu number
+ isExit = handleChoice(Validator.getMenuNumber(getMenuListFromEnum(UpdateCustomerFunction.class)));
+ }
+ }
+ return true;
+ }
+
+ @Override
+ default int getCurrentMenuNumber(){
+ return MainMenuFunction.CUSTOMER_MANAGEMENT.getMenuNumber();
+ }
+}
diff --git a/src/com/smartstore/function/customer/add/AddCustomer.java b/src/com/smartstore/function/customer/add/AddCustomer.java
new file mode 100644
index 00000000..9511091f
--- /dev/null
+++ b/src/com/smartstore/function/customer/add/AddCustomer.java
@@ -0,0 +1,66 @@
+package com.smartstore.function.customer.add;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.function.customer.CustomerMenuHandler;
+import com.smartstore.util.DuplicateChecker;
+import com.smartstore.util.Validator;
+
+public class AddCustomer implements CustomerMenuHandler {
+
+ private static AddCustomer instance;
+
+ private AddCustomer(){
+
+ }
+
+ public static AddCustomer getInstance() {
+ if(instance == null){
+ return new AddCustomer();
+ }
+ return instance;
+ }
+
+ @Override
+ public boolean handleChoice(String numberOfUser) {
+ if(!"end".equalsIgnoreCase(numberOfUser)){
+ String name;
+ String id;
+ int usageTime;
+ int paymentAmount;
+ Customers customers = Customers.getInstance();
+ //get name & id from user, usage_time&payment_amount is optional
+ for(int i = 0 ; i < Integer.parseInt(numberOfUser) ; i++){
+ while (true){
+ id = Validator.getUserData(true, "Input User ID : ");
+ //id duplication Check
+ if(!DuplicateChecker.isIdDuplicated(id)){
+ break;
+ }
+ System.out.printf("User id %s already Exist Try Other id\n", id);
+ }
+
+ name = Validator.getUserData(true, "Input User Name : ");
+ if(!Validator.isAnswerYes("Do you Want Set Optional Info?")){
+ usageTime = 0;
+ paymentAmount = 0;
+ }else {
+ String value = Validator.getValueOrEnd("Input Usage Time\nWait for Input Type 'end' or '0' will set as 0 : ", Integer.class);
+ usageTime = ("end".equalsIgnoreCase(String.valueOf(value))) ? 0 : Integer.parseInt(value);
+ value = Validator.getValueOrEnd("Input Payment Amount\nWait for Input Type 'end' or '0' will set as 0 : ", Integer.class);
+ paymentAmount = ("end".equalsIgnoreCase(String.valueOf(value))) ? 0 : Integer.parseInt(value);
+ }
+ customers.getCustomerList().add(new Customer(name, id, usageTime, paymentAmount));
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void run() {
+ boolean isExit = false;
+ while (!isExit){
+ isExit = handleChoice(String.valueOf(Validator.getValueOrEnd("How many Customers to Input ? | type 'end' or '0' to cancel ...", Integer.class)));
+ }
+ }
+}
diff --git a/src/com/smartstore/function/customer/delete/DeleteCustomer.java b/src/com/smartstore/function/customer/delete/DeleteCustomer.java
new file mode 100644
index 00000000..6b8ad740
--- /dev/null
+++ b/src/com/smartstore/function/customer/delete/DeleteCustomer.java
@@ -0,0 +1,43 @@
+package com.smartstore.function.customer.delete;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.util.Validator;
+import com.smartstore.function.customer.CustomerMenuHandler;
+
+public class DeleteCustomer implements CustomerMenuHandler {
+ private static DeleteCustomer instance;
+
+ private Customer selected;
+
+ private DeleteCustomer(){
+
+ }
+
+ public static DeleteCustomer getInstance() {
+ if(instance == null){
+ return new DeleteCustomer();
+ }
+ return instance;
+ }
+ @Override
+ public void run(){
+ String id;
+ boolean isExit = false;
+ id = Validator.getValueOrEnd("Type User Id to Delete : ", String.class);
+ if("end".equalsIgnoreCase(id)){
+ return;
+ }
+ selected = Customers.getInstance().getCustomerById(id);
+ if(selected == null){
+ System.out.printf("There is no User %s\n", id);
+ return;
+ }
+ System.out.println("Selected Customer's Info");
+ System.out.println(selected.toString());
+ if(Validator.isAnswerYes("Did you Really Want to Delete This User? | y or n")){
+ Customers.getInstance().getCustomerList().remove(selected);
+ System.out.printf("User %s Successfully Deleted\n", id);
+ }
+ }
+}
diff --git a/src/com/smartstore/function/customer/update/SetId.java b/src/com/smartstore/function/customer/update/SetId.java
new file mode 100644
index 00000000..75fd1ac7
--- /dev/null
+++ b/src/com/smartstore/function/customer/update/SetId.java
@@ -0,0 +1,39 @@
+package com.smartstore.function.customer.update;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.util.DuplicateChecker;
+import com.smartstore.util.Validator;
+
+public class SetId implements UpdateCustomerHandler {
+ private static SetId instance;
+
+ private SetId(){
+
+ }
+
+ public static SetId getInstance(){
+ if(instance == null){
+ return new SetId();
+ }
+ return instance;
+ }
+
+
+ @Override
+ public void run(T value) {
+ String id;
+ while (true){
+ id = Validator.getValueOrEnd("Input New Id\n Wait for input... 'end' to exit", String.class);
+ if(id.isBlank() || "end".equals(id)){
+ System.out.println("Change not saved");
+ break;
+ }
+ if(DuplicateChecker.isIdDuplicated(id)){
+ ((Customer) value).setCustomerId(id);
+ System.out.println("Change Successfully Saved");
+ break;
+ }
+ System.out.printf("User Id %s already Exist Try Other Id\n", id);
+ }
+ }
+}
diff --git a/src/com/smartstore/function/customer/update/SetName.java b/src/com/smartstore/function/customer/update/SetName.java
new file mode 100644
index 00000000..37fc1da7
--- /dev/null
+++ b/src/com/smartstore/function/customer/update/SetName.java
@@ -0,0 +1,32 @@
+package com.smartstore.function.customer.update;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.util.Validator;
+
+public class SetName implements UpdateCustomerHandler {
+ private static SetName instance;
+
+ private SetName(){
+
+ }
+
+ public static SetName getInstance(){
+ if(instance == null){
+ return new SetName();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run(T value) {
+ String name;
+ Customer customer = (Customer) value;
+ name = Validator.getValueOrEnd("Input New Name\n Wait for input... 'end' to exit", String.class);
+ if(name.isBlank() || "end".equals(name)){
+ System.out.println("Change not saved");
+ return;
+ }
+ customer.setCustomerName(name);
+ System.out.println("Change Successfully Saved");
+ }
+}
diff --git a/src/com/smartstore/function/customer/update/SetPaymentAmount.java b/src/com/smartstore/function/customer/update/SetPaymentAmount.java
new file mode 100644
index 00000000..3d7ec95e
--- /dev/null
+++ b/src/com/smartstore/function/customer/update/SetPaymentAmount.java
@@ -0,0 +1,33 @@
+package com.smartstore.function.customer.update;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.util.Validator;
+
+public class SetPaymentAmount implements UpdateCustomerHandler {
+ private static SetPaymentAmount instance;
+
+ private SetPaymentAmount(){
+
+ }
+
+ public static SetPaymentAmount getInstance(){
+ if(instance == null){
+ return new SetPaymentAmount();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run(T value) {
+ String paymentAmount;
+ paymentAmount = Validator.getValueOrEnd("Input New PaymentAmount\n Wait for input... 'end' to exit", Integer.class);
+ if(paymentAmount.isBlank() || "end".equals(paymentAmount)){
+ System.out.println("Change not saved");
+ return;
+ }
+ ((Customer) value).setPaymentAmount(Integer.parseInt(paymentAmount));
+ //update membership
+ ((Customer) value).updateMembership();
+ System.out.println("Change Successfully Saved");
+ }
+}
diff --git a/src/com/smartstore/function/customer/update/SetUsageTime.java b/src/com/smartstore/function/customer/update/SetUsageTime.java
new file mode 100644
index 00000000..b6d070c2
--- /dev/null
+++ b/src/com/smartstore/function/customer/update/SetUsageTime.java
@@ -0,0 +1,33 @@
+package com.smartstore.function.customer.update;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.util.Validator;
+
+public class SetUsageTime implements UpdateCustomerHandler {
+ private static SetUsageTime instance;
+
+ private SetUsageTime(){
+
+ }
+
+ public static SetUsageTime getInstance(){
+ if(instance == null){
+ return new SetUsageTime();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run(T value) {
+ String usageTime;
+ usageTime = Validator.getValueOrEnd("Input New UsageTime\n Wait for input... 'end' to exit", Integer.class);
+ if(usageTime.isBlank() || "end".equals(usageTime)){
+ System.out.println("Change not saved");
+ return;
+ }
+ ((Customer) value).setUsageTime(Integer.parseInt(usageTime));
+ //update membership
+ ((Customer) value).updateMembership();
+ System.out.println("Change Successfully Saved");
+ }
+}
diff --git a/src/com/smartstore/function/customer/update/UpdateCustomer.java b/src/com/smartstore/function/customer/update/UpdateCustomer.java
new file mode 100644
index 00000000..279ab4d1
--- /dev/null
+++ b/src/com/smartstore/function/customer/update/UpdateCustomer.java
@@ -0,0 +1,60 @@
+package com.smartstore.function.customer.update;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.function.customer.CustomerMenuHandler;
+import com.smartstore.util.Function;
+import com.smartstore.util.Printer;
+import com.smartstore.util.Validator;
+
+
+public class UpdateCustomer implements CustomerMenuHandler {
+
+ private static UpdateCustomer instance;
+
+ private UpdateCustomer(){
+
+ }
+
+ private Customer selected;
+
+ public static UpdateCustomer getInstance() {
+ if(instance == null){
+ return new UpdateCustomer();
+ }
+ return instance;
+ }
+
+ @Override
+ public boolean handleChoice(String menuNumber) {
+ if(Integer.parseInt(menuNumber) == UpdateCustomerFunction.BACK.getMenuNumber()) {
+ return true;
+ }
+ //call Menu with menuNumber
+ Function.of(Integer.parseInt(menuNumber), UpdateCustomerFunction.class).run(selected);
+ return false;
+ }
+
+ @Override
+ public void run(){
+ String id;
+ boolean isExit = false;
+ id = Validator.getValueOrEnd("Type User Id to Update : ", String.class);
+ if("end".equalsIgnoreCase(id)){
+ return;
+ }
+ selected = Customers.getInstance().getCustomerById(id);
+ if(selected == null){
+ System.out.printf("There is no User %s\n", id);
+ return;
+ }
+ System.out.println("Selected Customer's Info");
+ System.out.println(selected.toString());
+ System.out.println();
+ while (!isExit){
+ Printer.printMenu(getMenuListFromEnum(UpdateCustomerFunction.class));
+ isExit = handleChoice(Validator.getMenuNumber(getMenuListFromEnum(UpdateCustomerFunction.class)));
+ }
+
+ }
+}
diff --git a/src/com/smartstore/function/customer/update/UpdateCustomerFunction.java b/src/com/smartstore/function/customer/update/UpdateCustomerFunction.java
new file mode 100644
index 00000000..d604198f
--- /dev/null
+++ b/src/com/smartstore/function/customer/update/UpdateCustomerFunction.java
@@ -0,0 +1,40 @@
+package com.smartstore.function.customer.update;
+
+import com.smartstore.function.Back;
+import com.smartstore.util.Function;
+import com.smartstore.util.HandleableParam;
+
+public enum UpdateCustomerFunction implements Function {
+
+ NAME(1, SetName.getInstance(), "Set Name"),
+ ID(2, SetId.getInstance(), "Set ID"),
+ USAGE_TIME(3, SetUsageTime.getInstance(), "Set Usage Time"),
+ PAYMENT_AMOUNT(4, SetPaymentAmount.getInstance(), "Set Payment Amount"),
+ BACK(5, Back.getInstance(), "Return to prev Menu");
+
+
+ private final int menuNumber;
+ private final HandleableParam handler;
+ private final String menuText;
+ UpdateCustomerFunction(int menuNumber, HandleableParam handler, String menuText) {
+ this.menuNumber = menuNumber;
+ this.handler = handler;
+ this.menuText = menuText;
+ }
+
+ @Override
+ public String getMenuText() {
+ return menuText;
+ }
+
+ @Override
+ public int getMenuNumber() {
+ return this.menuNumber;
+ }
+
+ @Override
+ public HandleableParam getMenuHandler() {
+ return this.handler;
+ }
+
+}
diff --git a/src/com/smartstore/function/customer/update/UpdateCustomerHandler.java b/src/com/smartstore/function/customer/update/UpdateCustomerHandler.java
new file mode 100644
index 00000000..18ec12a7
--- /dev/null
+++ b/src/com/smartstore/function/customer/update/UpdateCustomerHandler.java
@@ -0,0 +1,7 @@
+package com.smartstore.function.customer.update;
+
+import com.smartstore.util.HandleableParam;
+
+public interface UpdateCustomerHandler extends HandleableParam {
+
+}
\ No newline at end of file
diff --git a/src/com/smartstore/function/customer/view/ViewCustomer.java b/src/com/smartstore/function/customer/view/ViewCustomer.java
new file mode 100644
index 00000000..a0e16063
--- /dev/null
+++ b/src/com/smartstore/function/customer/view/ViewCustomer.java
@@ -0,0 +1,46 @@
+package com.smartstore.function.customer.view;
+
+import com.smartstore.function.customer.CustomerMenuHandler;
+import com.smartstore.util.Function;
+import com.smartstore.util.Handleable;
+import com.smartstore.util.Printer;
+import com.smartstore.util.Validator;
+
+public class ViewCustomer implements CustomerMenuHandler, Handleable {
+
+ private static ViewCustomer instance;
+
+ private ViewCustomer(){
+
+ }
+
+ public static ViewCustomer getInstance() {
+ if(instance == null){
+ return new ViewCustomer();
+ }
+ return instance;
+ }
+ @Override
+ public void run() {
+ boolean isExit = false;
+
+ while (!isExit){
+ Printer.printMenu(getMenuListFromEnum(ViewCustomerFunction.class));
+ //get menu number from user until valid menu number
+ isExit = handleChoice(Validator.getMenuNumber(getMenuListFromEnum(ViewCustomerFunction.class)));
+ }
+ }
+
+
+
+ @Override
+ public boolean handleChoice(String menuNumber) {
+ if(Integer.parseInt(menuNumber) == ViewCustomerFunction.BACK.getMenuNumber()) {
+ return true;
+ }
+ //call Menu with menuNumber
+ Function.of(Integer.parseInt(menuNumber), ViewCustomerFunction.class).run();
+ return true;
+ }
+
+}
diff --git a/src/com/smartstore/function/customer/view/ViewCustomerAll.java b/src/com/smartstore/function/customer/view/ViewCustomerAll.java
new file mode 100644
index 00000000..1ac897d7
--- /dev/null
+++ b/src/com/smartstore/function/customer/view/ViewCustomerAll.java
@@ -0,0 +1,36 @@
+package com.smartstore.function.customer.view;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.util.Handleable;
+import com.smartstore.util.List;
+
+public class ViewCustomerAll implements Handleable {
+
+ private static ViewCustomerAll instance;
+
+ private ViewCustomerAll(){
+
+ }
+
+ public static ViewCustomerAll getInstance() {
+ if(instance == null){
+ return new ViewCustomerAll();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run() {
+ Customers customers = Customers.getInstance();
+ List customerList = customers.getCustomerList();
+ if (customerList.size() == 0){
+ System.out.println("No Customer Data");
+ return;
+ }
+ System.out.println("List of Customers");
+ System.out.println("======================================");
+ System.out.println(customerList);
+ System.out.println("======================================");
+ }
+}
diff --git a/src/com/smartstore/function/customer/view/ViewCustomerById.java b/src/com/smartstore/function/customer/view/ViewCustomerById.java
new file mode 100644
index 00000000..dda29c83
--- /dev/null
+++ b/src/com/smartstore/function/customer/view/ViewCustomerById.java
@@ -0,0 +1,40 @@
+package com.smartstore.function.customer.view;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.util.Handleable;
+import com.smartstore.util.Validator;
+
+public class ViewCustomerById implements Handleable {
+
+ private static ViewCustomerById instance;
+
+ private ViewCustomerById(){
+
+ }
+
+ public static ViewCustomerById getInstance() {
+ if(instance == null){
+ return new ViewCustomerById();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run() {
+ Customers customers = Customers.getInstance();
+ Customer customer;
+ String value = Validator.getValueOrEnd("Type User Id to Find | 'end' to cancel : ", String.class);
+ String msg="";
+
+ if(!"end".equalsIgnoreCase(value)){
+ customer = customers.getCustomerById(value);
+ if(customer == null){
+ msg = "There is No User : " + value;
+ }else {
+ msg = customer.toString();
+ }
+ }
+ System.out.println(msg);
+ }
+}
diff --git a/src/com/smartstore/function/customer/view/ViewCustomerByPaging.java b/src/com/smartstore/function/customer/view/ViewCustomerByPaging.java
new file mode 100644
index 00000000..ca9521fd
--- /dev/null
+++ b/src/com/smartstore/function/customer/view/ViewCustomerByPaging.java
@@ -0,0 +1,59 @@
+package com.smartstore.function.customer.view;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.util.*;
+
+public class ViewCustomerByPaging implements Handleable {
+
+ private static ViewCustomerByPaging instance;
+
+ private ViewCustomerByPaging(){
+
+ }
+
+ public static ViewCustomerByPaging getInstance() {
+ if(instance == null){
+ return new ViewCustomerByPaging();
+ }
+ return instance;
+ }
+
+ private boolean indexRangeCheck(int sizeOfList, int index){
+ return index + Define.PAGING <= sizeOfList;
+ }
+
+ @Override
+ public void run() {
+ Customers customers = Customers.getInstance();
+ List customerList = customers.getCustomerList();
+ if (customerList.size() == 0){
+ System.out.println("No Customer Data");
+ return;
+ }
+ int listSize = customers.getCustomerList().size();
+ int fromIndex=0;
+ int toIndex;
+ if(listSize > Define.PAGING){
+ while (true){
+ toIndex = indexRangeCheck(listSize, fromIndex) ? fromIndex + Define.PAGING -1 : listSize-1;
+ System.out.println("======================================");
+ System.out.printf("List of Customers %d - %d / %d\n",fromIndex+1,toIndex+1 > listSize ? listSize : toIndex +1, listSize);
+ System.out.print(customerList.subList(fromIndex, toIndex).toString());
+ fromIndex = toIndex + 1;
+ if(fromIndex >= listSize){
+ break;
+ }
+ if(!Validator.isAnswerYes("Continue To See Customer list, Type 'Y'")){
+ break;
+ }
+ }
+ }else{
+ System.out.printf("List of Customers %d - %d\n",1,listSize);
+ System.out.println("======================================");
+ System.out.print(customerList);
+ }
+
+ System.out.println("======================================\n\n");
+ }
+}
diff --git a/src/com/smartstore/function/customer/view/ViewCustomerFunction.java b/src/com/smartstore/function/customer/view/ViewCustomerFunction.java
new file mode 100644
index 00000000..50443407
--- /dev/null
+++ b/src/com/smartstore/function/customer/view/ViewCustomerFunction.java
@@ -0,0 +1,37 @@
+package com.smartstore.function.customer.view;
+
+import com.smartstore.function.Back;
+import com.smartstore.util.Function;
+import com.smartstore.util.Handleable;
+
+public enum ViewCustomerFunction implements Function {
+
+ ALL(1, ViewCustomerAll.getInstance(), "ALL Customer List"),
+ PAGING(2, ViewCustomerByPaging.getInstance(), "Customer List By Paging"),
+ BY_ID(3, ViewCustomerById.getInstance(), "Find Customer by Id"),
+ BACK(4, Back.getInstance(), "Return to Prev Menu");
+
+
+ private final int menuNumber;
+ private final Handleable handler;
+ private final String menuText;
+ ViewCustomerFunction(int menuNumber, Handleable handler, String menuText) {
+ this.menuNumber = menuNumber;
+ this.handler = handler;
+ this.menuText = menuText;
+ }
+
+ @Override
+ public int getMenuNumber() {
+ return this.menuNumber;
+ }
+
+ @Override
+ public String getMenuText() { return this.menuText; }
+
+ @Override
+ public Handleable getMenuHandler() {
+ return this.handler;
+ }
+
+}
diff --git a/src/com/smartstore/function/mainmenu/CustomerMenu.java b/src/com/smartstore/function/mainmenu/CustomerMenu.java
new file mode 100644
index 00000000..ff955d21
--- /dev/null
+++ b/src/com/smartstore/function/mainmenu/CustomerMenu.java
@@ -0,0 +1,36 @@
+package com.smartstore.function.mainmenu;
+
+import com.smartstore.util.Function;
+import com.smartstore.function.customer.CustomerFunction;
+import com.smartstore.util.Printer;
+import com.smartstore.util.Validator;
+
+public class CustomerMenu implements MainMenuHandler {
+ public static CustomerMenu getInstance() {
+ if(instance == null){
+ instance = new CustomerMenu();
+ }
+ return instance;
+ }
+
+ private static CustomerMenu instance;
+
+ @Override
+ public void run() {
+ boolean isExit = false;
+ while (!isExit){
+ Printer.printMenu(getMenuListFromEnum(CustomerFunction.class));
+ //get menu number from user until valid menu number
+ isExit = handleChoice(Validator.getMenuNumber(getMenuListFromEnum(CustomerFunction.class)));
+ }
+ }
+
+ @Override
+ public boolean handleChoice(String menuNumber) {
+ if(Integer.parseInt(menuNumber) == CustomerFunction.BACK.getMenuNumber()) {
+ return true;
+ }
+ Function.of(Integer.parseInt(menuNumber), CustomerFunction.class).run();
+ return false;
+ }
+}
diff --git a/src/com/smartstore/function/mainmenu/MainMenu.java b/src/com/smartstore/function/mainmenu/MainMenu.java
new file mode 100644
index 00000000..b0a9b73b
--- /dev/null
+++ b/src/com/smartstore/function/mainmenu/MainMenu.java
@@ -0,0 +1,42 @@
+package com.smartstore.function.mainmenu;
+
+import com.smartstore.util.Define;
+import com.smartstore.util.Function;
+import com.smartstore.util.PrettyTerminal;
+
+public class MainMenu implements MainMenuHandler {
+ private static MainMenu instance;
+ public static MainMenu getInstance() {
+ if(instance == null){
+ instance = new MainMenu();
+ }
+ return instance;
+ }
+
+ private MainMenu(){
+
+ }
+
+ private void printSplashScreen(){
+ System.out.println(Define.SPLASHSCREEN);
+ }
+
+ @Override
+ public boolean handleChoice(String menuNumber) {
+ if(Integer.parseInt(menuNumber) == MainMenuFunction.QUIT.getMenuNumber()) {
+ System.out.println("Okay By...e");
+ return true;
+ }
+ //call Menu with menuNumber
+ Function.of(Integer.parseInt(menuNumber), MainMenuFunction.class).run(Integer.parseInt(menuNumber));
+ PrettyTerminal.cls();
+ return false;
+ }
+
+ @Override
+ public void run() {
+ printSplashScreen();
+ MainMenuHandler.super.run();
+ }
+
+}
diff --git a/src/com/smartstore/function/mainmenu/MainMenuFunction.java b/src/com/smartstore/function/mainmenu/MainMenuFunction.java
new file mode 100644
index 00000000..1cc2a531
--- /dev/null
+++ b/src/com/smartstore/function/mainmenu/MainMenuFunction.java
@@ -0,0 +1,43 @@
+package com.smartstore.function.mainmenu;
+
+import com.smartstore.function.*;
+import com.smartstore.util.Function;
+import com.smartstore.util.Handleable;
+
+public enum MainMenuFunction implements Function {
+ MAIN_MENU(0, MainMenu.getInstance(), "Main Menu"),
+ MEMBERSHIP_MANAGEMENT(1, MembershipMenu.getInstance(), "Membership Management"),
+ CUSTOMER_MANAGEMENT(2, CustomerMenu.getInstance(), "Customer Management"),
+ REPORT_MANAGEMENT(3, SummaryMenu.getInstance(), "Report"),
+ QUIT(4, Back.getInstance(), "Quit");
+
+ private final int menuNumber;
+ private final Handleable handler;
+
+ private final String menuText;
+
+ MainMenuFunction(int menuNumber, Handleable handler, String menuText) {
+ this.menuNumber = menuNumber;
+ this.handler = handler;
+ this.menuText = menuText;
+ }
+
+ @Override
+ public String getMenuText() {
+ return menuText;
+ }
+
+ @Override
+ public int getMenuNumber() {
+ return menuNumber;
+ }
+
+ public Handleable getMenuHandler() {
+ return handler;
+ }
+
+ @Override
+ public void run(T value) {
+ getMenuHandler().run();
+ }
+}
diff --git a/src/com/smartstore/function/mainmenu/MainMenuHandler.java b/src/com/smartstore/function/mainmenu/MainMenuHandler.java
new file mode 100644
index 00000000..514147a1
--- /dev/null
+++ b/src/com/smartstore/function/mainmenu/MainMenuHandler.java
@@ -0,0 +1,34 @@
+package com.smartstore.function.mainmenu;
+
+import com.smartstore.util.*;
+
+public interface MainMenuHandler extends EnumValueProvider, Handler, HandleableParam {
+
+ default void run() {
+ boolean isExit = false;
+ while (!isExit) {
+ Printer.printMenu(getMenuListFromEnum(MainMenuFunction.class, MainMenuFunction.MEMBERSHIP_MANAGEMENT.getMenuNumber(), MainMenuFunction.QUIT.getMenuNumber()));
+ //get menu number from user until valid menu number
+ isExit = handleChoice(Validator.getMenuNumber(getMenuListFromEnum(MainMenuFunction.class, MainMenuFunction.MEMBERSHIP_MANAGEMENT.getMenuNumber(), MainMenuFunction.QUIT.getMenuNumber())));
+
+ }
+
+ }
+
+ @Override
+ default void run(T value) {
+ boolean isExit = false;
+ while (!isExit){
+ Printer.printMenu(getMenuListFromEnum(MainMenuFunction.class, MainMenuFunction.MEMBERSHIP_MANAGEMENT.getMenuNumber(), MainMenuFunction.QUIT.getMenuNumber()));
+ //get menu number from user until valid menu number
+ isExit = handleChoice(String.valueOf(value));
+ }
+ }
+
+
+ @Override
+ default int getCurrentMenuNumber(){
+ return MainMenuFunction.MAIN_MENU.getMenuNumber();
+ }
+
+}
diff --git a/src/com/smartstore/function/mainmenu/MembershipMenu.java b/src/com/smartstore/function/mainmenu/MembershipMenu.java
new file mode 100644
index 00000000..7e953930
--- /dev/null
+++ b/src/com/smartstore/function/mainmenu/MembershipMenu.java
@@ -0,0 +1,40 @@
+package com.smartstore.function.mainmenu;
+
+import com.smartstore.function.membership.MembershipFunction;
+import com.smartstore.util.Function;
+import com.smartstore.util.Printer;
+import com.smartstore.util.Validator;
+
+public class MembershipMenu implements MainMenuHandler {
+ private static MembershipMenu instance;
+ public static MembershipMenu getInstance() {
+ if(instance == null){
+ instance = new MembershipMenu();
+ }
+ return instance;
+ }
+ private MembershipMenu(){
+
+ }
+
+ @Override
+ public void run() {
+ boolean isExit = false;
+ while (!isExit){
+ Printer.printMenu(getMenuListFromEnum(MembershipFunction.class));
+ //get menu number from user until valid menu number
+ isExit = handleChoice(Validator.getMenuNumber(getMenuListFromEnum(MembershipFunction.class)));
+ }
+ }
+
+ @Override
+ public boolean handleChoice(String menuNumber) {
+ if(Integer.parseInt(menuNumber) == MembershipFunction.BACK.getMenuNumber()) {
+ return true;
+ }
+ Function.of(Integer.parseInt(menuNumber), MembershipFunction.class).run();
+ return false;
+ }
+
+}
+
diff --git a/src/com/smartstore/function/mainmenu/SummaryMenu.java b/src/com/smartstore/function/mainmenu/SummaryMenu.java
new file mode 100644
index 00000000..8bedf55c
--- /dev/null
+++ b/src/com/smartstore/function/mainmenu/SummaryMenu.java
@@ -0,0 +1,52 @@
+package com.smartstore.function.mainmenu;
+
+import com.smartstore.function.sorting.SortFunction;
+import com.smartstore.function.sorting.SortHandler;
+import com.smartstore.util.*;
+
+
+public class SummaryMenu implements SortHandler, Handler, HandleableParam {
+
+ private static SummaryMenu instance;
+
+ private SummaryMenu(){
+
+ }
+
+ public static SummaryMenu getInstance() {
+ if(instance == null){
+ return new SummaryMenu();
+ }
+ return instance;
+ }
+
+ @Override
+ public boolean handleChoice(String menuNumber) {
+ if(Integer.parseInt(menuNumber) == SortFunction.BACK.getMenuNumber()) {
+ return true;
+ }
+ //call Menu with menuNumber
+ Function.of(Integer.parseInt(menuNumber), SortFunction.class).run();
+ return false;
+ }
+
+ @Override
+ public int getCurrentMenuNumber() {
+ return MainMenuFunction.REPORT_MANAGEMENT.getMenuNumber();
+ }
+
+ @Override
+ public void run(){
+ boolean isExit = false;
+ while (!isExit){
+ Printer.printMenu(getMenuListFromEnum(SortFunction.class));
+ isExit = handleChoice(Validator.getMenuNumber(getMenuListFromEnum(SortFunction.class)));
+ }
+
+ }
+
+ @Override
+ public void run(T value) {
+ run();
+ }
+}
diff --git a/src/com/smartstore/function/membership/MembershipFunction.java b/src/com/smartstore/function/membership/MembershipFunction.java
new file mode 100644
index 00000000..a9658408
--- /dev/null
+++ b/src/com/smartstore/function/membership/MembershipFunction.java
@@ -0,0 +1,42 @@
+package com.smartstore.function.membership;
+
+import com.smartstore.function.Back;
+import com.smartstore.util.Function;
+import com.smartstore.util.Handleable;
+import com.smartstore.function.membership.set.SetMembershipRequirement;
+import com.smartstore.function.membership.update.UpdateMembershipRequirement;
+import com.smartstore.function.membership.view.ViewMembershipRequirement;
+
+public enum MembershipFunction implements Function {
+ SET(1, SetMembershipRequirement.getInstance(), "Set Membership Requirement"),
+ VIEW(2, ViewMembershipRequirement.getInstance(), "View Membership Requirement"),
+ UPDATE(3, UpdateMembershipRequirement.getInstance(), "Update Membership Requirement"),
+
+ BACK(4, Back.getInstance(), "Return to Prev Menu");
+
+
+ private final int menuNumber;
+ private final Handleable handler;
+ private final String menuText;
+ MembershipFunction(int menuNumber, Handleable handler, String menuText) {
+ this.menuNumber = menuNumber;
+ this.handler = handler;
+ this.menuText = menuText;
+ }
+
+
+ @Override
+ public int getMenuNumber() {
+ return this.menuNumber;
+ }
+
+ @Override
+ public Handleable getMenuHandler() {
+ return this.handler;
+ }
+
+ @Override
+ public String getMenuText() {
+ return this.menuText;
+ }
+}
diff --git a/src/com/smartstore/function/membership/MembershipMenuHandler.java b/src/com/smartstore/function/membership/MembershipMenuHandler.java
new file mode 100644
index 00000000..43b934ca
--- /dev/null
+++ b/src/com/smartstore/function/membership/MembershipMenuHandler.java
@@ -0,0 +1,51 @@
+package com.smartstore.function.membership;
+
+import com.smartstore.function.mainmenu.MainMenuFunction;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.util.*;
+
+import java.util.NoSuchElementException;
+
+public interface MembershipMenuHandler extends EnumValueProvider, Handler, HandleableParam {
+
+ default void run() {
+ boolean isExit = false;
+ while (!isExit){
+ //get values from enum by string array
+ Printer.printSelectable(getMenuListFromEnum(MembershipType.class, MembershipType.GENERAL.ordinal(), MembershipType.VVIP.ordinal()));
+
+ isExit = handleChoice(Validator.getParameter(getMenuListFromEnum(MembershipType.class)));
+ }
+ }
+
+ default MembershipType getMembershipType(String membershipNames){
+ String[] values = getMenuListFromEnum(MembershipType.class);
+ for (String membershipName : values) {
+ try{
+ if (MembershipType.valueOf(membershipName.toUpperCase()).findByName(membershipNames)) {
+ return MembershipType.valueOf(membershipName.toUpperCase());
+ }
+ }catch (NoSuchElementException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+ return null;
+ }
+
+ @Override
+ default boolean handleChoice(String membershipName){
+ if(!"end".equalsIgnoreCase(membershipName)){
+ //get enum_value using string from MembershipType
+ MembershipType membershipType = getMembershipType(membershipName);
+ //run each function's method
+ run(membershipType);
+ }
+ return true;
+ }
+
+ @Override
+ default int getCurrentMenuNumber(){
+ return MainMenuFunction.MEMBERSHIP_MANAGEMENT.getMenuNumber();
+ }
+
+}
diff --git a/src/com/smartstore/function/membership/set/SetMembershipHandler.java b/src/com/smartstore/function/membership/set/SetMembershipHandler.java
new file mode 100644
index 00000000..f5a8d83c
--- /dev/null
+++ b/src/com/smartstore/function/membership/set/SetMembershipHandler.java
@@ -0,0 +1,70 @@
+package com.smartstore.function.membership.set;
+
+import com.smartstore.customer.Customers;
+import com.smartstore.membership.MembershipRequirement;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.membership.Memberships;
+import com.smartstore.util.Handleable;
+import com.smartstore.util.HandleableParam;
+import com.smartstore.util.Validator;
+
+public interface SetMembershipHandler extends HandleableParam, Handleable {
+ @Override
+ default void run() {
+
+ }
+
+ default void setMembershipRequirement(MembershipType membershipType){
+ setMembershipRequirement(membershipType, false, false);
+ }
+
+ default void setMembershipRequirement(MembershipType membershipType, boolean isUpdateUsageTime, boolean isUpdatePaymentAmount){
+ int minUsageTime;
+ int minPaymentAmount;
+ boolean isValidUsage;
+ boolean isValidPaymentAmount;
+
+ while (true) {
+ minUsageTime = Memberships.getInstance().findByType(membershipType) == null && isUpdateUsageTime ? Validator.getInteger("Input minUsageTime : ") : Memberships.getInstance().findByType(membershipType).getMinUsageTime();
+ isValidUsage = Validator.isValidMinUsage(membershipType, minUsageTime);
+ minPaymentAmount = Memberships.getInstance().findByType(membershipType) == null && isUpdatePaymentAmount ? Validator.getInteger("Input minPaymentAmount : ") : Memberships.getInstance().findByType(membershipType).getMinPaymentAmount();
+ isValidPaymentAmount = Validator.isValidMinPayment(membershipType, minPaymentAmount);
+
+ if(membershipType != MembershipType.values()[0] && membershipType != MembershipType.values()[1]){
+ //if current memberShip requirement equals prevMembership requirement -> false
+ MembershipRequirement prevRequirement = Memberships.getInstance().findByType(MembershipType.values()[membershipType.ordinal()-1]);
+ if(minUsageTime == prevRequirement.getMinUsageTime() && minPaymentAmount == prevRequirement.getMinPaymentAmount()) {
+ System.out.println("Usage Time & Payment Amount Can't be Same of Lower Membership");
+ isValidUsage = false;
+ isValidUsage = false;
+ }
+ }
+ /*
+ isValidUsageTime -> prev Membership's minUsageTime <= minUsageTime
+ isValidPaymentAmount -> prev Membership's minPaymentAmount <= minPaymentAmount
+ isValidUsage & isValidPaymentAmount Must Satisfy the AND Operation
+
+ ex) set VIP
+ General (1,5), VIP(2,9) -> T,T OK
+ General (1,5), VIP(1,6) -> T,T OK
+ General (1,3), VIP(1,3) -> T,T but not satisfy condition(equals not allowed)
+ General (1,3), VIP(1,1) -> T,F Fail
+ General (1,1), VIP(0,4) -> F,T Fail
+ General (1,3), VIP(0,0) -> F,F Fail
+ */
+ if (isValidUsage && isValidPaymentAmount) {
+ break;
+ }
+ System.out.println("Check Input Data Again");
+
+ System.out.printf("isValidUsage & isValidPaymentAmount Must Satisfy the AND Operation. Current Situation : %s, %s\n",isValidUsage, isValidPaymentAmount);
+ }
+ setMembershipRequirement(membershipType, minUsageTime, minPaymentAmount);
+ }
+
+ default void setMembershipRequirement(MembershipType membershipType, int minUsage, int minPaymentAmount){
+ Memberships.getInstance().getMembershipMap().put(membershipType, new MembershipRequirement(minUsage, minPaymentAmount));
+ //update membership
+ Customers.getInstance().updateMembership();
+ }
+}
diff --git a/src/com/smartstore/function/membership/set/SetMembershipRequirement.java b/src/com/smartstore/function/membership/set/SetMembershipRequirement.java
new file mode 100644
index 00000000..44876ce3
--- /dev/null
+++ b/src/com/smartstore/function/membership/set/SetMembershipRequirement.java
@@ -0,0 +1,52 @@
+package com.smartstore.function.membership.set;
+
+import com.smartstore.function.membership.MembershipMenuHandler;
+import com.smartstore.membership.MembershipRequirement;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.membership.Memberships;
+
+public class SetMembershipRequirement implements MembershipMenuHandler, SetMembershipHandler {
+ private static SetMembershipRequirement instance;
+
+ private SetMembershipRequirement(){
+
+ }
+
+ public static SetMembershipRequirement getInstance() {
+ if(instance == null){
+ return new SetMembershipRequirement();
+ }
+ return instance;
+ }
+
+ boolean isPrevMembershipExist(MembershipType membershipType){
+ if(membershipType == MembershipType.values()[0] || membershipType == MembershipType.values()[1]){
+ return true;
+ } else{
+ return Memberships.getInstance().findByType(MembershipType.values()[membershipType.ordinal() - 1]) != null;
+ }
+ }
+
+ @Override
+ public void run(T value) {
+ MembershipType membershipType = (MembershipType) value;
+ MembershipRequirement requirement = Memberships.getInstance().getMembershipMap().get(membershipType);
+ if(requirement == null){
+ if(isPrevMembershipExist(membershipType)){
+ setMembershipRequirement(membershipType,true,true);
+ System.out.printf("Set %s Successfully\n\n\n",membershipType.name());
+ }
+ else {
+ System.out.printf("Define %s first to right Sort\n", MembershipType.values()[membershipType.ordinal()-1]);
+ }
+
+ }else {
+ System.out.printf("Membership '%s' Already Defined\n", membershipType.name());
+ }
+ }
+
+ @Override
+ public void run() {
+ MembershipMenuHandler.super.run();
+ }
+}
diff --git a/src/com/smartstore/function/membership/update/UpdateMembershipRequirement.java b/src/com/smartstore/function/membership/update/UpdateMembershipRequirement.java
new file mode 100644
index 00000000..d4b846ba
--- /dev/null
+++ b/src/com/smartstore/function/membership/update/UpdateMembershipRequirement.java
@@ -0,0 +1,74 @@
+package com.smartstore.function.membership.update;
+
+import com.smartstore.function.membership.MembershipMenuHandler;
+import com.smartstore.membership.MembershipRequirement;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.membership.Memberships;
+import com.smartstore.util.Function;
+import com.smartstore.util.Printer;
+import com.smartstore.util.Validator;
+
+
+public class UpdateMembershipRequirement implements MembershipMenuHandler {
+ private static UpdateMembershipRequirement instance;
+ private MembershipType selected;
+
+ private UpdateMembershipRequirement(){
+
+ }
+
+ public static UpdateMembershipRequirement getInstance() {
+ if(instance == null){
+ return new UpdateMembershipRequirement();
+ }
+ return instance;
+ }
+
+ @Override
+ public boolean handleChoice(String menuNumber) {
+ if(Integer.parseInt(menuNumber) == UpdateMembershipRequirementFunction.BACK.getMenuNumber()) {
+ return true;
+ }
+ //call Menu with MembershipType
+ Function.of(Integer.parseInt(menuNumber), UpdateMembershipRequirementFunction.class).run(selected);
+ return false;
+ }
+
+ @Override
+ public void run(){
+ boolean isExit = false;
+
+ while (!isExit){
+ if(Memberships.getInstance().getMembershipMap().size() != MembershipType.values().length-1){
+ System.out.println("Please Set All Membership Info First");
+ break;
+ }
+ Printer.printSelectable(getMenuListFromEnum(MembershipType.class, MembershipType.GENERAL.ordinal(), MembershipType.VVIP.ordinal()));
+ //get menu number from user until valid menu number
+ isExit = MembershipMenuHandler.super.handleChoice(Validator.getParameter(getMenuListFromEnum(MembershipType.class)));
+ }
+ }
+
+
+ @Override
+ public void run(T value) {
+ MembershipType membershipType = (MembershipType) value;
+ MembershipRequirement requirement = Memberships.getInstance().getMembershipMap().get(membershipType);
+
+ boolean isExit = false;
+
+ if(requirement == null ){
+ System.out.printf("Membership '%s' Not Defined Yet\n", membershipType.name());
+ }else{
+ System.out.printf("Current %s Info\n", membershipType.name());
+ System.out.printf("Min Usage time : %d\n", requirement.getMinUsageTime());
+ System.out.printf("Min Payment Amount: %d\n\n", requirement.getMinPaymentAmount());
+ selected = membershipType;
+ while (!isExit){
+ Printer.printMenu(getMenuListFromEnum(UpdateMembershipRequirementFunction.class));
+ //get menu number from user until valid menu number
+ isExit = handleChoice(Validator.getMenuNumber(getMenuListFromEnum(UpdateMembershipRequirementFunction.class)));
+ }
+ }
+ }
+}
diff --git a/src/com/smartstore/function/membership/update/UpdateMembershipRequirementFunction.java b/src/com/smartstore/function/membership/update/UpdateMembershipRequirementFunction.java
new file mode 100644
index 00000000..bb14d8bb
--- /dev/null
+++ b/src/com/smartstore/function/membership/update/UpdateMembershipRequirementFunction.java
@@ -0,0 +1,37 @@
+package com.smartstore.function.membership.update;
+
+import com.smartstore.function.Back;
+import com.smartstore.util.Function;
+import com.smartstore.util.HandleableParam;
+
+public enum UpdateMembershipRequirementFunction implements Function {
+
+ SET_MIN_USAGE(1, UpdateMinUsage.getInstance(), "Set Min Usage"),
+ SET_MIN_PAYMENT_AMOUNT(2, UpdateMinPaymentAmount.getInstance(), "Set Min Payment Amount"),
+ BACK(3, Back.getInstance(), "Return to Prev Menu");
+
+ private final int menuNumber;
+ private final HandleableParam handler;
+ private final String menuText;
+ UpdateMembershipRequirementFunction(int menuNumber, HandleableParam handler, String menuText) {
+ this.menuNumber = menuNumber;
+ this.handler = handler;
+ this.menuText = menuText;
+ }
+
+ @Override
+ public String getMenuText() {
+ return menuText;
+ }
+
+ @Override
+ public int getMenuNumber() {
+ return this.menuNumber;
+ }
+
+ @Override
+ public HandleableParam getMenuHandler() {
+ return this.handler;
+ }
+
+}
diff --git a/src/com/smartstore/function/membership/update/UpdateMinPaymentAmount.java b/src/com/smartstore/function/membership/update/UpdateMinPaymentAmount.java
new file mode 100644
index 00000000..d1f04aa9
--- /dev/null
+++ b/src/com/smartstore/function/membership/update/UpdateMinPaymentAmount.java
@@ -0,0 +1,35 @@
+package com.smartstore.function.membership.update;
+
+import com.smartstore.function.membership.set.SetMembershipHandler;
+import com.smartstore.membership.MembershipRequirement;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.membership.Memberships;
+
+public class UpdateMinPaymentAmount implements SetMembershipHandler {
+ private static UpdateMinPaymentAmount instance;
+
+ private UpdateMinPaymentAmount(){
+
+ }
+
+ public static UpdateMinPaymentAmount getInstance() {
+ if(instance == null){
+ return new UpdateMinPaymentAmount();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run(T value) {
+ MembershipType membershipType = (MembershipType) value;
+ MembershipRequirement requirement = Memberships.getInstance().getMembershipMap().get(membershipType);
+
+ if(requirement != null){
+ setMembershipRequirement(membershipType, false, true);
+ System.out.printf("Set %s Minimum Payment Amount Successfully\n\n\n",membershipType.name());
+ }else {
+ System.out.printf("Membership '%s' Defined Yet\n", membershipType.name());
+ }
+ }
+
+}
diff --git a/src/com/smartstore/function/membership/update/UpdateMinUsage.java b/src/com/smartstore/function/membership/update/UpdateMinUsage.java
new file mode 100644
index 00000000..5c0db7e9
--- /dev/null
+++ b/src/com/smartstore/function/membership/update/UpdateMinUsage.java
@@ -0,0 +1,33 @@
+package com.smartstore.function.membership.update;
+
+import com.smartstore.function.membership.set.SetMembershipHandler;
+import com.smartstore.membership.MembershipRequirement;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.membership.Memberships;
+
+public class UpdateMinUsage implements SetMembershipHandler {
+ private static UpdateMinUsage instance;
+
+ private UpdateMinUsage(){
+
+ }
+
+ public static UpdateMinUsage getInstance() {
+ if(instance == null){
+ return new UpdateMinUsage();
+ }
+ return instance;
+ }
+ @Override
+ public void run(T value) {
+ MembershipType membershipType = (MembershipType) value;
+ MembershipRequirement requirement = Memberships.getInstance().getMembershipMap().get(membershipType);
+
+ if(requirement != null){
+ setMembershipRequirement(membershipType, true, false);
+ System.out.printf("Set %s Minimum Usage Successfully\n\n\n",membershipType.name());
+ }else {
+ System.out.printf("Membership '%s' Defined Yet\n", membershipType.name());
+ }
+ }
+}
diff --git a/src/com/smartstore/function/membership/view/ViewMembershipRequirement.java b/src/com/smartstore/function/membership/view/ViewMembershipRequirement.java
new file mode 100644
index 00000000..a34f2f94
--- /dev/null
+++ b/src/com/smartstore/function/membership/view/ViewMembershipRequirement.java
@@ -0,0 +1,35 @@
+package com.smartstore.function.membership.view;
+
+import com.smartstore.function.membership.MembershipMenuHandler;
+import com.smartstore.membership.MembershipRequirement;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.membership.Memberships;
+
+public class ViewMembershipRequirement implements MembershipMenuHandler {
+ private static ViewMembershipRequirement instance;
+
+ private ViewMembershipRequirement(){
+
+ }
+
+ public static ViewMembershipRequirement getInstance() {
+ if(instance == null){
+ return new ViewMembershipRequirement();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run(T value) {
+ MembershipType membershipType = (MembershipType) value;
+ MembershipRequirement requirement = Memberships.getInstance().getMembershipMap().get(membershipType);
+
+ if(requirement == null ){
+ System.out.printf("Membership '%s' Not Defined Yet\n", membershipType.name());
+ } else{
+ System.out.printf("%s Info\n", membershipType.name());
+ System.out.printf("Min Usage time : %d\n",requirement.getMinUsageTime());
+ System.out.printf("Min Payment Amount: %d\n\n",requirement.getMinPaymentAmount());
+ }
+ }
+}
diff --git a/src/com/smartstore/function/sorting/SortByMembership.java b/src/com/smartstore/function/sorting/SortByMembership.java
new file mode 100644
index 00000000..82b6c880
--- /dev/null
+++ b/src/com/smartstore/function/sorting/SortByMembership.java
@@ -0,0 +1,60 @@
+package com.smartstore.function.sorting;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.util.CustomEnumMap;
+import com.smartstore.util.CustomList;
+import com.smartstore.util.MergeSort;
+import com.smartstore.util.Validator;
+
+import java.util.Arrays;
+
+public class SortByMembership implements SortHandler, MergeSort {
+ private static SortByMembership instance;
+
+ private SortByMembership(){
+
+ }
+
+ public static SortByMembership getInstance(){
+ if(instance == null){
+ return new SortByMembership();
+ }
+ return instance;
+ }
+ private CustomEnumMap sortedCustomerMap = new CustomEnumMap<>(MembershipType.class);
+
+ public CustomEnumMap getSortedCustomersMap() {
+ updateSortedData();
+ return sortedCustomerMap;
+ }
+
+ public void updateSortedData() {
+ CustomList customerList = Customers.getInstance().getCustomerList();
+ if(customerList.size() == 0){
+ return;
+ }
+
+ Customer[] customersSortByMembership = mergeSort(customerList.toArray(new Customer[customerList.size()]));
+ int index = 0;
+ for(MembershipType membershipType : MembershipType.values()){
+ for(int j = 0 ; j < customersSortByMembership.length ; j++){
+ if(customersSortByMembership[j].getMembership() != membershipType){
+ index = j;
+ break;
+ }
+ //copy and add to list of Customers Group by membership
+ }
+ if(index == 0){
+ sortedCustomerMap.put(membershipType, customersSortByMembership);
+ break;
+ }
+ sortedCustomerMap.put(membershipType, Arrays.copyOfRange(customersSortByMembership,0, index-1));
+ //resize sorted Arr
+ customersSortByMembership = Arrays.copyOfRange(customersSortByMembership, index, customersSortByMembership.length-1);
+ index=0;
+ }
+
+ }
+}
diff --git a/src/com/smartstore/function/sorting/SortByName.java b/src/com/smartstore/function/sorting/SortByName.java
new file mode 100644
index 00000000..8f313256
--- /dev/null
+++ b/src/com/smartstore/function/sorting/SortByName.java
@@ -0,0 +1,53 @@
+package com.smartstore.function.sorting;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.util.MergeSort;
+
+public class SortByName implements SortHandler, MergeSort {
+ private static SortByName instance;
+
+ private SortByName(){
+
+ }
+
+ public static SortByName getInstance(){
+ if(instance == null){
+ return new SortByName();
+ }
+ return instance;
+ }
+
+ @Override
+ public Customer[] mergeSort(Customer[] leftArr, Customer[] rightArr, boolean ascending) {
+ int leftLen = leftArr.length;
+ int rightLen = rightArr.length;
+ int i = 0, j = 0, k = 0;
+ Customer[] mergedArr = new Customer[leftLen + rightLen];
+
+ while (i < leftLen && j < rightLen) {
+ if ((ascending && leftArr[i].getCustomerName().compareTo(rightArr[j].getCustomerName()) <= 0) ||
+ (!ascending && leftArr[i].getCustomerName().compareTo(rightArr[j].getCustomerName()) >= 0)) {
+ mergedArr[k] = leftArr[i];
+ i++;
+ } else {
+ mergedArr[k] = rightArr[j];
+ j++;
+ }
+ k++;
+ }
+
+ while (i < leftLen) {
+ mergedArr[k] = leftArr[i];
+ i++;
+ k++;
+ }
+
+ while (j < rightLen) {
+ mergedArr[k] = rightArr[j];
+ j++;
+ k++;
+ }
+
+ return mergedArr;
+ }
+}
diff --git a/src/com/smartstore/function/sorting/SortByPaymentAmount.java b/src/com/smartstore/function/sorting/SortByPaymentAmount.java
new file mode 100644
index 00000000..021886f3
--- /dev/null
+++ b/src/com/smartstore/function/sorting/SortByPaymentAmount.java
@@ -0,0 +1,54 @@
+package com.smartstore.function.sorting;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.util.MergeSort;
+
+public class SortByPaymentAmount implements SortHandler, MergeSort {
+ private static SortByPaymentAmount instance;
+
+ private SortByPaymentAmount(){
+
+ }
+
+ public static SortByPaymentAmount getInstance(){
+ if(instance == null){
+ return new SortByPaymentAmount();
+ }
+ return instance;
+ }
+
+
+ @Override
+ public Customer[] mergeSort(Customer[] leftArr, Customer[] rightArr, boolean ascending) {
+ int leftLen = leftArr.length;
+ int rightLen = rightArr.length;
+ int i = 0, j = 0, k = 0;
+ Customer[] mergedArr = new Customer[leftLen + rightLen];
+
+ while (i < leftLen && j < rightLen) {
+ if ((ascending && leftArr[i].getPaymentAmount() <= rightArr[j].getPaymentAmount()) ||
+ (!ascending && leftArr[i].getPaymentAmount() >= rightArr[j].getPaymentAmount())) {
+ mergedArr[k] = leftArr[i];
+ i++;
+ } else {
+ mergedArr[k] = rightArr[j];
+ j++;
+ }
+ k++;
+ }
+
+ while (i < leftLen) {
+ mergedArr[k] = leftArr[i];
+ i++;
+ k++;
+ }
+
+ while (j < rightLen) {
+ mergedArr[k] = rightArr[j];
+ j++;
+ k++;
+ }
+
+ return mergedArr;
+ }
+}
diff --git a/src/com/smartstore/function/sorting/SortByUsageTime.java b/src/com/smartstore/function/sorting/SortByUsageTime.java
new file mode 100644
index 00000000..1aedb6e6
--- /dev/null
+++ b/src/com/smartstore/function/sorting/SortByUsageTime.java
@@ -0,0 +1,53 @@
+package com.smartstore.function.sorting;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.util.MergeSort;
+
+public class SortByUsageTime implements SortHandler, MergeSort {
+ private static SortByUsageTime instance;
+
+ private SortByUsageTime(){
+
+ }
+
+ public static SortByUsageTime getInstance(){
+ if(instance == null){
+ return new SortByUsageTime();
+ }
+ return instance;
+ }
+
+ @Override
+ public Customer[] mergeSort(Customer[] leftArr, Customer[] rightArr, boolean ascending) {
+ int leftLen = leftArr.length;
+ int rightLen = rightArr.length;
+ int i = 0, j = 0, k = 0;
+ Customer[] mergedArr = new Customer[leftLen + rightLen];
+
+ while (i < leftLen && j < rightLen) {
+ if ((ascending && leftArr[i].getUsageTime() <= rightArr[j].getUsageTime()) ||
+ (!ascending && leftArr[i].getUsageTime() >= rightArr[j].getUsageTime())) {
+ mergedArr[k] = leftArr[i];
+ i++;
+ } else {
+ mergedArr[k] = rightArr[j];
+ j++;
+ }
+ k++;
+ }
+
+ while (i < leftLen) {
+ mergedArr[k] = leftArr[i];
+ i++;
+ k++;
+ }
+
+ while (j < rightLen) {
+ mergedArr[k] = rightArr[j];
+ j++;
+ k++;
+ }
+
+ return mergedArr;
+ }
+}
diff --git a/src/com/smartstore/function/sorting/SortFunction.java b/src/com/smartstore/function/sorting/SortFunction.java
new file mode 100644
index 00000000..5e0c8706
--- /dev/null
+++ b/src/com/smartstore/function/sorting/SortFunction.java
@@ -0,0 +1,40 @@
+package com.smartstore.function.sorting;
+
+import com.smartstore.function.Back;
+import com.smartstore.util.Function;
+import com.smartstore.util.Handleable;
+
+public enum SortFunction implements Function {
+
+ BY_MEMBERSHIP(1, SortByMembership.getInstance(), "Summary GroupBy Membership"),
+ BY_NAME(2, SortByName.getInstance(), "Summary GroupBy Membership[Name]"),
+ BY_USAGE_TIME(3, SortByUsageTime.getInstance(), "Summary GroupBy Membership[Usage Time]"),
+ BY_PAYMENT_AMOUNT(4, SortByPaymentAmount.getInstance(), "Summary GroupBy Membership[Payment Amount]"),
+ BACK(5, Back.getInstance(), "Return to prev Menu");
+
+
+ private final int menuNumber;
+ private final Handleable handler;
+ private final String menuText;
+ SortFunction(int menuNumber, Handleable handler, String menuText) {
+ this.menuNumber = menuNumber;
+ this.handler = handler;
+ this.menuText = menuText;
+ }
+
+ @Override
+ public String getMenuText() {
+ return menuText;
+ }
+
+ @Override
+ public int getMenuNumber() {
+ return this.menuNumber;
+ }
+
+ @Override
+ public Handleable getMenuHandler() {
+ return this.handler;
+ }
+
+}
diff --git a/src/com/smartstore/function/sorting/SortHandler.java b/src/com/smartstore/function/sorting/SortHandler.java
new file mode 100644
index 00000000..660702de
--- /dev/null
+++ b/src/com/smartstore/function/sorting/SortHandler.java
@@ -0,0 +1,69 @@
+package com.smartstore.function.sorting;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+import com.smartstore.membership.MembershipType;
+import com.smartstore.util.*;
+
+import java.util.Arrays;
+
+public interface SortHandler extends EnumValueProvider, Handleable, MergeSort {
+ @Override
+ default void run() {
+ String answer = "A";
+ CustomList customerList = Customers.getInstance().getCustomerList();
+
+ if(! (this instanceof SortByMembership)){
+ answer = Validator.isAscendingOrEnd();
+ }
+
+ if("end".equalsIgnoreCase(answer)){
+ return;
+ }
+ if(customerList.size() == 0){
+ System.out.println("There is No Data Yet");
+ return;
+ }
+ for(MembershipType membershipType : MembershipType.values()){
+ System.out.println(membershipType.toString());
+ System.out.println("==========================");
+ System.out.println(Arrays.toString(mergeSort(SortByMembership.getInstance().getSortedCustomersMap().get(membershipType),"A".equalsIgnoreCase(answer))));
+ }
+
+
+ }
+
+ @Override
+ default Customer[] mergeSort(Customer[] leftArr, Customer[] rightArr, boolean ascending) {
+ int leftLen = leftArr.length;
+ int rightLen = rightArr.length;
+ int i = 0, j = 0, k = 0;
+ Customer[] mergedArr = new Customer[leftLen + rightLen];
+
+ while (i < leftLen && j < rightLen) {
+ if ((ascending && leftArr[i].getMembership().compareTo(rightArr[j].getMembership()) <= 0) ||
+ (!ascending && leftArr[i].getMembership().compareTo(rightArr[j].getMembership()) >= 0)) {
+ mergedArr[k] = leftArr[i];
+ i++;
+ } else {
+ mergedArr[k] = rightArr[j];
+ j++;
+ }
+ k++;
+ }
+
+ while (i < leftLen) {
+ mergedArr[k] = leftArr[i];
+ i++;
+ k++;
+ }
+
+ while (j < rightLen) {
+ mergedArr[k] = rightArr[j];
+ j++;
+ k++;
+ }
+
+ return mergedArr;
+ }
+}
\ No newline at end of file
diff --git a/src/com/smartstore/membership/MembershipRequirement.java b/src/com/smartstore/membership/MembershipRequirement.java
new file mode 100644
index 00000000..f601f47c
--- /dev/null
+++ b/src/com/smartstore/membership/MembershipRequirement.java
@@ -0,0 +1,40 @@
+package com.smartstore.membership;
+
+import java.util.Objects;
+
+public class MembershipRequirement {
+ private final int minUsageTime;
+ private final int minPaymentAmount;
+
+ public MembershipRequirement(int minUsageTime, int minPaymentAmount) {
+ this.minUsageTime = minUsageTime;
+ this.minPaymentAmount = minPaymentAmount;
+ }
+
+ //for unregister customer
+ public MembershipRequirement() {
+ this.minUsageTime = 0;
+ this.minPaymentAmount = 0;
+ }
+
+ public int getMinUsageTime() {
+ return minUsageTime;
+ }
+
+ public int getMinPaymentAmount() {
+ return minPaymentAmount;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof MembershipRequirement)) return false;
+ MembershipRequirement that = (MembershipRequirement) o;
+ return minUsageTime == that.minUsageTime && minPaymentAmount == that.minPaymentAmount;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(minUsageTime, minPaymentAmount);
+ }
+}
diff --git a/src/com/smartstore/membership/MembershipType.java b/src/com/smartstore/membership/MembershipType.java
new file mode 100644
index 00000000..f69695f2
--- /dev/null
+++ b/src/com/smartstore/membership/MembershipType.java
@@ -0,0 +1,41 @@
+
+package com.smartstore.membership;
+
+import com.smartstore.util.MenuProvider;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+public enum MembershipType implements MenuProvider {
+ NONE (new String[] {"NONE, N, 비회원"}, "None"),
+ GENERAL(new String[] {"G", "GENERAL", "일반"}, "General"),
+ VIP(new String[] {"V", "VIP", "우수"}, "VIP"),
+ VVIP(new String[] {"VV", "VVIP", "최우수"}, "VVIP");
+
+ private final String[] membershipNames;
+ private final String menuText;
+ MembershipType(String[] membershipNames, String menuText) {
+ this.membershipNames = membershipNames;
+ this.menuText = menuText;
+ }
+
+ public String getMenuText() {
+ return menuText;
+ }
+
+ public String[] getMembership() {
+ return membershipNames;
+ }
+
+ public boolean isMatchedName(String membershipName){
+ return Arrays.stream(membershipNames)
+ .anyMatch(name -> name.equalsIgnoreCase(membershipName));
+ }
+
+ public boolean findByName(String membershipName){
+ Optional membershipOpt = Arrays.stream(membershipNames)
+ .filter(name -> name.equalsIgnoreCase(membershipName))
+ .findFirst();
+ return (membershipOpt.isPresent());
+ }
+}
diff --git a/src/com/smartstore/membership/Memberships.java b/src/com/smartstore/membership/Memberships.java
new file mode 100644
index 00000000..23602327
--- /dev/null
+++ b/src/com/smartstore/membership/Memberships.java
@@ -0,0 +1,32 @@
+package com.smartstore.membership;
+
+import com.smartstore.util.CustomEnumMap;
+import com.smartstore.util.Readable;
+
+public class Memberships implements Readable {
+ private final CustomEnumMap membershipMap = new CustomEnumMap<>(MembershipType.class);
+ private static Memberships instance;
+
+ public static Memberships getInstance(){
+ if(instance == null){
+ instance = new Memberships();
+ }
+ return instance;
+ }
+
+ private Memberships(){
+
+ }
+
+ public CustomEnumMap getMembershipMap() {
+ return membershipMap;
+ }
+
+ public MembershipRequirement findByType(MembershipType membershipType) {
+ if (membershipMap.size() == 0) {
+ return null;
+ }
+ return membershipMap.get(membershipType);
+ }
+
+}
diff --git a/src/com/smartstore/util/CustomEnumMap.java b/src/com/smartstore/util/CustomEnumMap.java
new file mode 100644
index 00000000..d1b0e108
--- /dev/null
+++ b/src/com/smartstore/util/CustomEnumMap.java
@@ -0,0 +1,76 @@
+package com.smartstore.util;
+
+import java.util.Arrays;
+
+public class CustomEnumMap, V> implements Map{
+
+ //type of key
+ //keyType must be Enum
+ private final Class keyType;
+
+ private final Object[] values;
+
+ private int size = 0;
+
+ //if key == null, throw nullPointException
+ public CustomEnumMap(Class keyType) {
+ this.keyType = keyType;
+ K[] keys = keyType.getEnumConstants();
+ values = new Object[keys.length];
+ }
+
+ @Override
+ public void put(K key, V value) {
+ if(isValidKey(key)){
+ int index = key.ordinal();
+ if(values[index] == null){
+ size++;
+ }
+ values[index] = value;
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public V get( K key) {
+ if(isValidKey(key)){
+ return (V) values[key.ordinal()];
+ }
+ return null;
+ }
+
+ @Override
+ public boolean remove(K key) {
+ if(isValidKey(key)){
+ int index = key.ordinal();
+ if(values[index] != null){
+ size--;
+ }
+ values[index] = null;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int size() {
+ return this.size;
+ }
+
+ private boolean isValidKey(K key){
+ if(key == null){
+ return false;
+ }
+ //check is key proper type
+ return key.getClass() == keyType || key.getClass().getSuperclass() == keyType;
+ }
+
+ @Override
+ public String toString() {
+ return "CustomEnumMap{" +
+ "keys=" + Arrays.toString(keyType.getEnumConstants()) +
+ ", values=" + Arrays.toString(values) +
+ '}';
+ }
+
+}
diff --git a/src/com/smartstore/util/CustomHashMap.java b/src/com/smartstore/util/CustomHashMap.java
new file mode 100644
index 00000000..e7a338c0
--- /dev/null
+++ b/src/com/smartstore/util/CustomHashMap.java
@@ -0,0 +1,204 @@
+package com.smartstore.util;
+// TODO: 2023-05-02 implement resize method
+public class CustomHashMap implements Map {
+ private class Node implements Entry {
+ //Key is unmodifiable
+ private final K key;
+ private V value;
+ private Node next;
+
+ public Node(K key, V value){
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public K getKey() {
+ return this.key;
+ }
+
+ @Override
+ public V getValue() {
+ return this.value;
+ }
+
+ @Override
+ public void setValue(V value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ Node e = this;
+ while (e != null){
+ sb.append("\t").append("[").append(" key : ").append(e.getKey()).append(", value : ").append(e.getValue()).append(" ]\n");
+ e = e.next;
+ }
+ return sb.toString();
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("CustomHashMap { \n");
+ for (Node entry : entries) {
+ if (entry != null) {
+ sb.append(entry);
+ }
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /*
+ entries[] (if size = 5)
+ +----------+---------+----------+----------+-----------+----------------+
+ | | 0 | 1 | 2 | 3 | 4 |
+ |entries | Entry | Entry2 | Entry3 | Entry... | Entry.size-1 |
+ | | (Head1) | (Head2) | (Head3) | (Head...) | (Head.size-1) |
+ +----------+---------+----------+----------+-----------+----------------+
+ ⬇️⬇️
+ +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+
+ | Head1 index 0 | Head2 index 1 | Head3 index 2 | ... | Head4 index 4 |
+ | key.hashcode() % CA_SIZE | key.hashcode() % CA_SIZE | key.hashcode() % CA_SIZE | key.hashcode() % CA_SIZE | key.hashcode() % CA_SIZE |
+ +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+
+ | 1: [key, value] | | | 1: [key, value] | 1: [key, value] |
+ | 2: [key, value] (1.next) | | | 2: [key, value] (1.next) | 2: [key, value] (1.next) |
+ | | | | | 3: [key, value] (2.next) |
+ | 1,2,3... is not index | | | 1,2,3... is not index | 1,2,3... is not index |
+ +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+
+ Too big SIZE have chance to increasing wasted memory usage
+ Too small Size have chance to increasing Hash collisions, negative affect to performance
+ ideal size is expected entries * 0.75
+ key Not allowed null, value allowed null
+ */
+ private final Node[] entries;
+
+ //The default initial capacity - MUST be a power of two.
+ //use bitwise to code readability
+ //1 << 4 = 16
+ private static final int CAPACITY = 1 << 4;
+ private static final float DEFAULT_LOAD_FACTOR = 0.75f;
+ private int size;
+
+ public CustomHashMap(){
+ entries = new Node[Math.round(CAPACITY*DEFAULT_LOAD_FACTOR)];
+ }
+ @Override
+ public void put(K key, V value){
+ if(key == null){
+ return;
+ }
+
+ //Get Entries index from hash code 0 to size-1
+ int hash = key.hashCode() % CAPACITY;
+ Node e = entries[hash];
+
+ //if entries[hash] is not exists
+ if(e == null){
+ //create new Entry
+ entries[hash] = new Node(key, value);
+ size++;
+ }
+ else{
+ //loop until e.next is not null
+ while (e.next != null){
+ //if key exists, set value as new value, key is Unique
+ if (e.getKey().equals(key)){
+ e.setValue(value);
+ return;
+ }
+ e = e.next;
+ }
+ //if key == final entry's key, set value, key is Unique
+ if(e.getKey().equals(key)){
+ e.setValue(value);
+ return;
+ }
+
+ //if key doesn't exist
+ //add new Entry end of the entries[hash]
+ e.next = new Node(key, value);
+ size++;
+ }
+
+ }
+
+ @Override
+ public V get(K key){
+ if (key == null){
+ return null;
+ }
+ int hash = key.hashCode() % CAPACITY;
+ Node e = entries[hash];
+
+ //if entries[hash] is not exists, return null
+ if (e == null) {
+ return null;
+ }
+
+ //loop until e.next is not null
+ while (e != null){
+ //if key exists, return value
+ if(e.getKey().equals(key)){
+ return e.getValue();
+ }
+ e = e.next;
+ }
+ //if key doesn't exist, return null
+ return null;
+ }
+
+ @Override
+ public boolean remove(K key){
+ if(key == null){
+ return false;
+ }
+ int hash = key.hashCode() % CAPACITY;
+ Node e = entries[hash];
+
+ //if entries[hash] is not exists, return false
+ if (e == null){
+ return false;
+ }
+
+ //if first Entry's e.key equals key
+ if(e.getKey().equals(key)){
+ //shift second Entry to first(remove)
+ entries[hash] = e.next;
+ e.next = null;
+ size--;
+ return true;
+ }
+
+ Node prev = e;
+ e = e.next;
+
+ //loop until e is not null
+ while (e != null){
+ if (e.getKey().equals(key)) {
+ //shift next Entry to current(remove)
+ prev.next = e.next;
+ e.next = null;
+ size--;
+ return true;
+ }
+ prev = e;
+ e = e.next;
+ }
+
+ //if key not exists, return false
+ return false;
+ }
+
+ @Override
+ public int size() {return this.size;}
+
+ public boolean isEmpty() {
+ return this.size == 0;
+ }
+
+
+}
diff --git a/src/com/smartstore/util/CustomList.java b/src/com/smartstore/util/CustomList.java
new file mode 100644
index 00000000..584df6fa
--- /dev/null
+++ b/src/com/smartstore/util/CustomList.java
@@ -0,0 +1,174 @@
+package com.smartstore.util;
+
+import java.util.Arrays;
+
+
+public class CustomList implements List {
+ @Override
+ public int size() {
+ return this.size;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T get(T object) {
+ return (T) elements[findIndex(object)];
+ }
+
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T get(int index) {
+ isValidIndex(index);
+ return (T) elements[index];
+ }
+
+ @Override
+ public void set(int index, T object) {
+ isValidIndex(index);
+
+ if(elements[index] != null){
+ elements[index] = object;
+ }
+ }
+
+ @Override
+ public int indexOf(T object) {
+ return findIndex(object);
+ }
+
+ private int findIndex(Object o){
+ if(o == null){
+ throw new IllegalArgumentException("Null Can't be found");
+ }
+ for(int i = 0 ; i< size ; i++){
+ if (o.equals(elements[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ @SuppressWarnings("unchked")
+ public T[] toArray(T[] type){
+ return (T[]) Arrays.copyOf(elements, size, type.getClass());
+ }
+
+ @Override
+ @SuppressWarnings("unchked")
+ public T[] toArray(){
+ return (T[]) Arrays.copyOf(elements, size);
+ }
+ @Override
+ public void add(T object) {
+ if(size == elements.length){
+ resize(size+1);
+ }
+ elements[size++] = object;
+ }
+
+ @Override
+ public void add(int index, T object) {
+ isValidIndex(index);
+ if(size == elements.length){
+ resize(size+1);
+ }
+ fastCopy(index, index + 1, elements.length - index);
+ elements[index] = object;
+ }
+
+ @Override
+ public boolean remove(int index) {
+ isValidIndex(index);
+ fastCopy(index + 1, index, elements.length - index - 1);
+ resize(elements.length - 1);
+ size--;
+ return true;
+ }
+
+ @Override
+ public boolean remove(T object) {
+ if(object != null){
+ int index = indexOf(object);
+ if (index < 0){
+ return false;
+ }
+ if(remove(index)){
+ return true;
+ }
+ }
+ throw new IllegalArgumentException("Null Can't be found");
+ }
+
+ public void addAll(int index, CustomList extends T> newElements){
+ isValidIndex(index);
+ Object[] e = newElements.toArray();
+ int newSize = e.length;
+ if(newSize == 0){
+ return;
+ }
+
+ final int currentSize = this.elements.length;
+ if(newSize > currentSize - size){
+ resize(currentSize + newSize );
+ }
+
+ int movedIndex = currentSize - index;
+ if(movedIndex > 0){
+ fastCopy(index, index + newSize, movedIndex);
+ }
+ System.arraycopy(e, 0, elements, index, newSize);
+ size = currentSize + newSize;
+ }
+
+ public CustomList subList(int fromIndex, int toIndex){
+ CustomList subList = new CustomList<>();
+ for(int i = fromIndex ; i <= toIndex ; i++){
+ subList.add((T)elements[i]);
+ }
+ return subList;
+ }
+
+ private void fastCopy(int index, int desPosition, int movedIndex){
+ System.arraycopy(elements, index, elements, desPosition, movedIndex);
+ }
+ private void resize(int newLength){
+ //if requested size is overflow
+ if(elements.length + newLength < 0){
+ throw new OutOfMemoryError("Can't Resize Array.\n Integer overflow in requested size.\n");
+ }
+ elements = Arrays.copyOf(elements, newLength);
+ }
+
+ private void isValidIndex(int index){
+ if(index < 0 || index >= size){
+ throw new ArrayIndexOutOfBoundsException("Invalid Index");
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (elements == null)
+ return "";
+
+ int iMax = elements.length - 1;
+ if (iMax == -1)
+ return "";
+
+ StringBuilder b = new StringBuilder();
+ for (int i = 0; ; i++) {
+ b.append(elements[i]);
+ if (i == iMax)
+ return b.toString();
+ }
+ }
+
+ private int size;
+
+ private Object[] elements;
+
+ public CustomList() {
+ this.elements = new Object[]{};
+ }
+}
diff --git a/src/com/smartstore/util/Define.java b/src/com/smartstore/util/Define.java
new file mode 100644
index 00000000..9c31b6b4
--- /dev/null
+++ b/src/com/smartstore/util/Define.java
@@ -0,0 +1,25 @@
+package com.smartstore.util;
+
+public class Define {
+ public static final int PAGING = 5;
+ public static final String SPLASHSCREEN=
+ PrettyTerminal.CYAN.getAttribute()+PrettyTerminal.BOLD.getAttribute()+
+ " __ ,. -;z_\n" +
+ " __ヽ. `' `ヽ.\n" +
+ " ,> ` l\n" +
+ " ∠- ,.ヘ、、 | / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\\n" +
+ ". /イ./ ,4/ュ r_ニゝ、_ | l 비긴 걸로 l\n" +
+ " lイ/l=。ァ f'。 ラ|fr} | \하지 않을래?!/\n" +
+ " l:`/ _、二ノ |レ' ヽ. ノヘ._____/\n" +
+ " ハヾニニフ ,イ |\_ヽ\n" +
+ " ,、-‐ '\"7ヽ. ー ./ l / l `''ー- 、.._\n" +
+ ". / l / トヽイ レイ l l ハ\n" +
+ " / l / _⊥.|:ヽ.__,ノ:|⊥._ l l ヽ\n" +
+ " 〉 !  ̄ o.l::::::::::::::| - ,二..___ ! l、\n" +
+ ". / \ l |::::::::::::::| l L_o_」 l| | / ヽ\n" +
+ " j.\ `| o|:::::::::::::::l - 「 ̄  ̄l ! /.l\n" +
+ ". l \ | l:::::::::::::::::l. \___/ |/ ヽ\n" +
+ " L.____ハ o|::::::::::::::::::ヽ.- |___,.. イ\n" +
+ ". | _ l } l:::::::::::::::::::::::\ __ | |\n"+
+"By JY_B\n\n" + PrettyTerminal.RESET.getAttribute();
+}
diff --git a/src/com/smartstore/util/DuplicateChecker.java b/src/com/smartstore/util/DuplicateChecker.java
new file mode 100644
index 00000000..7e756045
--- /dev/null
+++ b/src/com/smartstore/util/DuplicateChecker.java
@@ -0,0 +1,17 @@
+package com.smartstore.util;
+
+import com.smartstore.customer.Customer;
+import com.smartstore.customer.Customers;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+public class DuplicateChecker {
+ public static boolean isIdDuplicated(String id){
+ CustomList customerList = Customers.getInstance().getCustomerList();
+ Optional customerOptional = Arrays.stream(customerList.toArray(new Customer[customerList.size()]))
+ .filter(customer -> id.equalsIgnoreCase(customer.getCustomerName()))
+ .findFirst();
+ return customerOptional.isPresent();
+ }
+}
diff --git a/src/com/smartstore/util/Entry.java b/src/com/smartstore/util/Entry.java
new file mode 100644
index 00000000..92785bcc
--- /dev/null
+++ b/src/com/smartstore/util/Entry.java
@@ -0,0 +1,7 @@
+package com.smartstore.util;
+
+public interface Entry{
+ K getKey();
+ V getValue();
+ void setValue(V value);
+}
diff --git a/src/com/smartstore/util/EnumValueProvider.java b/src/com/smartstore/util/EnumValueProvider.java
new file mode 100644
index 00000000..005c6a2f
--- /dev/null
+++ b/src/com/smartstore/util/EnumValueProvider.java
@@ -0,0 +1,27 @@
+package com.smartstore.util;
+
+import java.util.Arrays;
+
+public interface EnumValueProvider & MenuProvider> {
+
+ default String[] getMenuListFromEnum(Class type){
+ T[] enumConstants = type.getEnumConstants();
+ String[] menus = new String[enumConstants.length];
+ for (int i = 0; i < enumConstants.length; i++) {
+ menus[i] = enumConstants[i].getMenuText();
+ }
+ return menus;
+ }
+ default String[] getMenuListFromEnum(Class type, int fromIndex, int toIndex){
+ T[] enumConstants = type.getEnumConstants();
+ String[] menus = new String[enumConstants.length];
+ int count = 0;
+ for (int i = fromIndex; i <= toIndex; i++) {
+ menus[count] = enumConstants[i].getMenuText();
+ count++;
+ }
+ menus = Arrays.copyOf(menus,count);
+ return menus;
+ }
+
+}
\ No newline at end of file
diff --git a/src/com/smartstore/util/Function.java b/src/com/smartstore/util/Function.java
new file mode 100644
index 00000000..05164dba
--- /dev/null
+++ b/src/com/smartstore/util/Function.java
@@ -0,0 +1,30 @@
+package com.smartstore.util;
+
+import java.util.Arrays;
+
+public interface Function extends MenuProvider, Handleable, HandleableParam {
+ static & Function> E of(int menuNumber, Class enumClass){
+
+ return Arrays.stream(enumClass.getEnumConstants())
+ .filter(enumValue -> enumValue.isMatchedMenuNumber(menuNumber))
+ .findFirst().orElseThrow(() -> new IllegalArgumentException("Can't Find Function"));
+ }
+
+ int getMenuNumber();
+
+ T getMenuHandler();
+
+ default boolean isMatchedMenuNumber(int menuNumber){
+ return getMenuNumber() == menuNumber;
+ }
+
+ @Override
+ default void run() {
+ ((Handleable) getMenuHandler()).run();
+ }
+
+ @Override
+ default void run(T value) {
+ ((HandleableParam) getMenuHandler()).run(value);
+ }
+}
diff --git a/src/com/smartstore/util/Handleable.java b/src/com/smartstore/util/Handleable.java
new file mode 100644
index 00000000..660e73e6
--- /dev/null
+++ b/src/com/smartstore/util/Handleable.java
@@ -0,0 +1,5 @@
+package com.smartstore.util;
+
+public interface Handleable {
+ void run();
+}
diff --git a/src/com/smartstore/util/HandleableParam.java b/src/com/smartstore/util/HandleableParam.java
new file mode 100644
index 00000000..0bcd841e
--- /dev/null
+++ b/src/com/smartstore/util/HandleableParam.java
@@ -0,0 +1,5 @@
+package com.smartstore.util;
+
+public interface HandleableParam {
+ void run(T value);
+}
diff --git a/src/com/smartstore/util/Handler.java b/src/com/smartstore/util/Handler.java
new file mode 100644
index 00000000..0b5258d9
--- /dev/null
+++ b/src/com/smartstore/util/Handler.java
@@ -0,0 +1,7 @@
+package com.smartstore.util;
+
+public interface Handler extends Readable, Handleable {
+ boolean handleChoice(String menuNumber);
+ int getCurrentMenuNumber();
+
+}
diff --git a/src/com/smartstore/util/List.java b/src/com/smartstore/util/List.java
new file mode 100644
index 00000000..bac99a9d
--- /dev/null
+++ b/src/com/smartstore/util/List.java
@@ -0,0 +1,19 @@
+package com.smartstore.util;
+
+public interface List {
+ int size();
+ T get(T object);
+ T get(int index);
+ void set(int index, T object);
+ int indexOf(T object);
+ void add(T object);
+ void add(int index, T object);
+ boolean remove(int index);
+ boolean remove(T object);
+ CustomList subList(int fromIndex, int toIndex);
+
+ @SuppressWarnings("unchked")
+ T[] toArray(T[] type);
+
+ Object[] toArray();
+}
diff --git a/src/com/smartstore/util/Map.java b/src/com/smartstore/util/Map.java
new file mode 100644
index 00000000..53ecadb0
--- /dev/null
+++ b/src/com/smartstore/util/Map.java
@@ -0,0 +1,24 @@
+package com.smartstore.util;
+
+public interface Map {
+
+ void put(K key, V value);
+
+ V get(K key);
+
+ boolean remove(K key);
+
+ default V getOrDefault(K key, V defaultValue){
+ V value = get(key);
+ //if key is not exists, return defaultValue
+ if(value == null){
+ return defaultValue;
+ }
+ return value;
+ }
+
+ int size();
+
+
+
+}
diff --git a/src/com/smartstore/util/MenuProvider.java b/src/com/smartstore/util/MenuProvider.java
new file mode 100644
index 00000000..fa86a769
--- /dev/null
+++ b/src/com/smartstore/util/MenuProvider.java
@@ -0,0 +1,5 @@
+package com.smartstore.util;
+
+public interface MenuProvider {
+ String getMenuText();
+}
diff --git a/src/com/smartstore/util/MergeSort.java b/src/com/smartstore/util/MergeSort.java
new file mode 100644
index 00000000..658dc325
--- /dev/null
+++ b/src/com/smartstore/util/MergeSort.java
@@ -0,0 +1,35 @@
+package com.smartstore.util;
+
+import com.smartstore.customer.Customer;
+
+import java.util.Arrays;
+
+public interface MergeSort {
+
+ //default -> ascending
+ default Customer[] mergeSort(Customer[] arr){
+ return mergeSort(arr, true);
+ }
+
+
+ default Customer[] mergeSort(Customer[] arr, boolean ascending){
+ //Already Sorted
+ if(arr == null || arr.length <= 1){
+ return arr;
+ }
+ return mergeSort(arr, 0, arr.length -1, ascending);
+ }
+
+ default Customer[] mergeSort(Customer[] arr, int left, int right, boolean ascending){
+ if (left String getValueOrEnd(String msg, Class type){
+ String value;
+ while (true){
+ try {
+ System.out.println(msg);
+ value = br.readLine();
+ if("end".equalsIgnoreCase(java.lang.String.valueOf(value))){
+ break;
+ }
+ if(Number.class.isAssignableFrom(type) && Integer.parseInt(value) < 0){
+ throw new IllegalArgumentException();
+ }else {
+ break;
+ }
+ } catch (IOException | IllegalArgumentException e) {
+ System.out.println("Input valid Integer Data 1 ~ Integer.Max");
+ }
+ }
+ return value;
+ }
+
+
+ /**
+ *
+ * @param isRequired : is Data Required
+ * @return input value from user
+ */
+ public static String getUserData(boolean isRequired, String msg){
+ String value = null;
+ while (true){
+ try {
+ System.out.print(msg);
+ value = br.readLine();
+ } catch (IOException e) {
+ System.out.println("Please Input Validate Data");
+ }
+
+ if(isRequired && !value.isBlank()){
+ break;
+ }
+ System.out.println("Please Input Validate Data, This Element Can't be Empty or Black");
+ }
+ return value;
+ }
+
+ public static String getParameter(String[] values) {
+ String valueName="";
+ boolean isExit = false;
+ if(values.length > 0) {
+ while (!isExit) {
+ try {
+ System.out.print("Input : ");
+ valueName = br.readLine();
+ if("end".equals(valueName)){
+ break;
+ }
+ for (String membershipName : values) {
+ if (MembershipType.valueOf(membershipName.toUpperCase()).isMatchedName(valueName)) {
+ isExit = true;
+ break;
+ }
+ }
+ if(!isExit){
+ throw new IllegalArgumentException();
+ }
+ } catch (IOException | IllegalArgumentException | NullPointerException e) {
+ System.out.println("Invalid Parameter");
+ }
+ }
+ }
+ return valueName;
+ }
+
+ public static String getMenuNumber(String[] values) {
+ int menu;
+ while (true){
+ try {
+ System.out.print("Wait for Input : ");
+ menu = Integer.parseInt(br.readLine());
+ if (menu <= 0 || menu > values.length) {
+ throw new NumberFormatException();
+ }
+ break;
+
+ } catch (IOException | NumberFormatException e) {
+ System.out.println("Input valid Menu Number 1 ~ " + (values.length));
+ }
+ }
+ return String.valueOf(menu);
+ }
+
+ public static boolean isAnswerYes(String msg){
+ System.out.println(msg);
+ String value = "";
+ while (true){
+ try {
+ System.out.print("Wait for Input Y or N: ");
+ value = br.readLine();
+ } catch (IOException e) {
+ System.out.println("Please Input Y or N");
+ }
+ if("y".equalsIgnoreCase(value)){
+ return true;
+ }
+ if("n".equalsIgnoreCase(value)){
+ return false;
+ }
+ System.out.println("Please Input Y or N");
+ }
+ }
+
+ public static int getInteger(String msg){
+ int value;
+ while (true){
+ try {
+ System.out.print(msg);
+ value = Integer.parseInt(br.readLine());
+ //check value overflowed or negative
+ if (value < 0) {
+ throw new NumberFormatException("");
+ }
+ break;
+
+ } catch (IOException | NumberFormatException e) {
+ System.out.println("Invalid Range of Input try 0 ~ Integer.Max");
+ }
+ }
+ return value;
+ }
+
+ public static boolean isValidMinUsage(MembershipType membershipType, int value){
+ int prevMinUsageTime;
+ int nextMinUsageTime;
+ MembershipRequirement requirement;
+ CustomEnumMap membershipMap = Memberships.getInstance().getMembershipMap();
+
+ //if current membershipType is The Highest Membership
+ if(membershipType == MembershipType.values()[MembershipType.values().length-1]){
+ nextMinUsageTime = Integer.MAX_VALUE;
+ } else {
+ MembershipType nextMembershipType = MembershipType.values()[membershipType.ordinal()+1];
+ requirement = membershipMap.get(nextMembershipType);
+ nextMinUsageTime = (requirement == null) ? Integer.MAX_VALUE : requirement.getMinUsageTime();
+ }
+
+ //if current membershipType is The Lowest Membership or Next of Lowest
+ if(membershipType == MembershipType.values()[0] || membershipType == MembershipType.values()[1]){
+ prevMinUsageTime = 0;
+ } else {
+ MembershipType prevMembershipType = MembershipType.values()[membershipType.ordinal()-1];
+ requirement = membershipMap.get(prevMembershipType);
+ prevMinUsageTime = (requirement == null) ? 0 : requirement.getMinUsageTime();
+ }
+
+
+ return value <= nextMinUsageTime && value >= prevMinUsageTime;
+ }
+
+ public static boolean isValidMinPayment(MembershipType membershipType, int value){
+ int prevMinPayment;
+ int nextMinPayment;
+ MembershipRequirement requirement;
+ CustomEnumMap membershipMap = Memberships.getInstance().getMembershipMap();
+
+ //if current membershipType is The Highest Membership
+ if(membershipType == MembershipType.values()[MembershipType.values().length-1]){
+ nextMinPayment = Integer.MAX_VALUE;
+ } else {
+ MembershipType nextMembershipType = MembershipType.values()[membershipType.ordinal()+1];
+ requirement = membershipMap.get(nextMembershipType);
+ //if next is not exist, 0
+ nextMinPayment = (requirement == null) ? Integer.MAX_VALUE : requirement.getMinPaymentAmount();
+ }
+
+ //if current membershipType is The Lowest Membership or Next of Lowest
+ if(membershipType == MembershipType.values()[0] || membershipType == MembershipType.values()[1]){
+ prevMinPayment = 0;
+ } else {
+ MembershipType prevMembershipType = MembershipType.values()[membershipType.ordinal()-1];
+ requirement = membershipMap.get(prevMembershipType);
+ prevMinPayment = (requirement == null) ? 0 : requirement.getMinPaymentAmount();
+ }
+
+
+ return value <= nextMinPayment && value >= prevMinPayment;
+ }
+
+ public static String isAscendingOrEnd(){
+ System.out.println(PrettyTerminal.BLUE.getAttribute() + "Ascending" + PrettyTerminal.RESET.getAttribute() + " or " + PrettyTerminal.RED.getAttribute() +"Descending?" + PrettyTerminal.RESET.getAttribute());
+ String value = "";
+ while (true){
+ try {
+ System.out.print("Wait for Input A or D " + PrettyTerminal.RED.getAttribute() + "end" + PrettyTerminal.RESET.getAttribute() + " to exit :");
+ value = br.readLine();
+ } catch (IOException e) {
+ System.out.println("Please Input A or D");
+ }
+
+ if("A".equalsIgnoreCase(value) || "D".equalsIgnoreCase(value) || "end".equalsIgnoreCase(value)){
+ return value;
+ }
+
+ System.out.println("Please Input A or D or end");
+ }
+ }
+
+}