diff --git a/src/me/smartstore/AppException.java b/src/me/smartstore/AppException.java new file mode 100644 index 00000000..696f73dc --- /dev/null +++ b/src/me/smartstore/AppException.java @@ -0,0 +1,7 @@ +package me.smartstore; + +public class AppException extends Exception { + public AppException(String msg) { super(msg); } + public AppException(Exception e) { super(e); } + public AppException(String msg, Exception e) { super(msg, e); } +} diff --git a/src/me/smartstore/Main.java b/src/me/smartstore/Main.java new file mode 100644 index 00000000..8cd59151 --- /dev/null +++ b/src/me/smartstore/Main.java @@ -0,0 +1,8 @@ +package me.smartstore; + +public class Main { + public static void main(String[] args) { + SmartStoreApp.getInstance().test().run(); +// SmartStoreApp.getInstance().run(); + } +} diff --git a/src/me/smartstore/SmartStoreApp.java b/src/me/smartstore/SmartStoreApp.java new file mode 100644 index 00000000..15563d25 --- /dev/null +++ b/src/me/smartstore/SmartStoreApp.java @@ -0,0 +1,60 @@ +package me.smartstore; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.group.Group; +import me.smartstore.group.GroupParameter; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.StartMenu; + +public class SmartStoreApp { + + private static final SmartStoreApp INSTANCE = new SmartStoreApp(); + private SmartStoreApp() {} + public static SmartStoreApp getInstance() { return INSTANCE; } + + public SmartStoreApp test() { + Integer[][] groupParameters = new Integer[][] { + {10, 100_000}, + {20, 200_000}, + {30, 300_000} + }; + CustomerRepository repository = CustomerRepository.getInstance(); + + Group[] groups = Group.getUsedGroups(); + for (int i = 0; i < groups.length; i++) { + Group group = groups[i]; + Integer[] param = groupParameters[i]; + group.setGroupParameter(param); + for (int j = 0; j < 10; j++) { + repository.resetTempCustomer(); + + String id = String.format("%s_%02d", group.name(), j); + repository.setTempId(id); + + String name = (char) ('a'+j) + "zzz"; + repository.setTempName(name); + + Integer spentHours = (int) (Math.random() * 10) + param[0]; + repository.setTempSpentHours(spentHours); + + Integer totalPaidAmount = (int) (Math.random() * 100_000) + param[1]; + repository.setTempTotalPaidAmount(totalPaidAmount); + + repository.updateGroupOfTempCustomer(); + repository.addTempIntoRepository(); + } + } + return this; + } + + public void run() { + Menu menu = StartMenu.getInstance(); + do { + Menu nextMenu = menu.printAndInputAndGetNextMenu(); + if (nextMenu == null) + return; + nextMenu.setPrevMenu(menu); + menu = nextMenu; + } while (true); + } +} diff --git a/src/me/smartstore/customer/Customer.java b/src/me/smartstore/customer/Customer.java new file mode 100644 index 00000000..0a0c2883 --- /dev/null +++ b/src/me/smartstore/customer/Customer.java @@ -0,0 +1,107 @@ +package me.smartstore.customer; + +import me.smartstore.customer.exception.InvalidCustomerIdException; +import me.smartstore.customer.exception.InvalidCustomerNameException; +import me.smartstore.group.Group; + +public class Customer { + + public static final String ID_FORMAT = + "ID Format: 4~16 letters consisting of alphabets, digits, underscore(_)"; + public static final String NAME_FORMAT = + "Name Format: [1,4] space separated chuck(s) of alphabets of [2,32] lengths."; + private static final String ID_PATTERN = "^[0-9a-zA-Z_]{4,16}$"; + private static final String NAME_CHUCK = "[a-z]{2,32}"; + private static final String NAME_PATTERN = '^' + NAME_CHUCK + "( " + NAME_CHUCK + "){0,3}$"; + private static final int DEFAULT_SPENT_HOURS = 0; + private static final int DEFAULT_TOTAL_PAID_AMOUNT = 0; + private static final Group DEFAULT_GROUP = Group.NONE; + + private String id; + private String name; + private Integer spentHours; + private Integer totalPaidAmount; + private Group group; + + public Customer(String id, String name) { + this(id, name, DEFAULT_SPENT_HOURS, DEFAULT_TOTAL_PAID_AMOUNT, DEFAULT_GROUP); + } + + public Customer(String id, String name, Integer spentHours, Integer totalPaidAmount, Group group) { + this.id = id; + this.name = name; + this.spentHours = spentHours; + this.totalPaidAmount = totalPaidAmount; + this.group = group; + } + + public Customer(Customer e) { copy(e); } + + public void copy(Customer e) { + id = e.id; + name = e.name; + spentHours = e.spentHours; + totalPaidAmount = e.totalPaidAmount; + group = e.group; + } + + public String getId() { return id; } + + public void setId(String id, boolean checked) throws InvalidCustomerIdException { + if (!checked) + checkIfIdIsValid(id); + this.id = id; + } + + public static void checkIfIdIsValid(String id) throws InvalidCustomerIdException { + if (!isValidId(id)) + throw new InvalidCustomerIdException("Invalid ID input.\n"); + } + + private static boolean isValidId(String id) { + throwIfNull(id, "ID"); + return id.matches(ID_PATTERN); + } + + public String getName() { return name; } + + public void setName(String name) throws InvalidCustomerNameException { + checkIfNameIsValid(name); + this.name = name; + } + + public static void checkIfNameIsValid(String name) throws InvalidCustomerNameException { + if (!isValidName(name)) + throw new InvalidCustomerNameException("Invalid Name input.\n"); + } + + private static boolean isValidName(String name) { + throwIfNull(name, "Name"); + return name.matches(NAME_PATTERN); + } + + private static void throwIfNull(Object o, String title) { + if (o == null) + throw new IllegalArgumentException(title + " cannot be null.\n"); + } + + public Integer getSpentHours() { return spentHours; } + + public void setSpentHours(Integer spentHours) { this.spentHours = spentHours; } + + public Integer getTotalPaidAmount() { return totalPaidAmount; } + + public void setTotalPaidAmount(Integer totalPaidAmount) { this.totalPaidAmount = totalPaidAmount; } + + public Group getGroup() { return group; } + + public void updateGroup() { + group = Group.getGroupByParameter(spentHours, totalPaidAmount); + } + + @Override + public String toString() { + return String.format("Customer{id='%s', name='%s', spentHours=%d, totalAmountPaid=%d, group=%s}", + id, name, spentHours, totalPaidAmount, group.name()); + } +} diff --git a/src/me/smartstore/customer/CustomerRepository.java b/src/me/smartstore/customer/CustomerRepository.java new file mode 100644 index 00000000..989d9bbd --- /dev/null +++ b/src/me/smartstore/customer/CustomerRepository.java @@ -0,0 +1,109 @@ +package me.smartstore.customer; + +import me.smartstore.customer.exception.DuplicateCustomerIdException; +import me.smartstore.customer.exception.InvalidCustomerIdException; +import me.smartstore.customer.exception.InvalidCustomerNameException; +import me.smartstore.group.Group; + +public class CustomerRepository extends List { + + private static class InstanceHolder { + private static final CustomerRepository INSTANCE = new CustomerRepository(); + } + public static CustomerRepository getInstance() { return InstanceHolder.INSTANCE; } + private CustomerRepository() {} + + private Customer tempCustomer; + private int tempIdx; + + public void resetTempCustomer() { tempCustomer = new Customer(null, null); } + + public void checkIfHasNoDuplicate(String id) throws DuplicateCustomerIdException { + if (hasCustomerWithId(id)) + throw new DuplicateCustomerIdException("The customer already exists which has same id."); + } + + private boolean hasCustomerWithId(String id) { + assert id != null; + for (Customer customer : this) + if (id.equals(customer.getId())) + return true; + return false; + } + + public void setTempId(String id) throws InvalidCustomerIdException, DuplicateCustomerIdException { + Customer.checkIfIdIsValid(id); + checkIfHasNoDuplicate(id); + tempCustomer.setId(id, true); + } + + public void setTempName(String name) throws InvalidCustomerNameException { + tempCustomer.setName(name); + } + + public void setTempSpentHours(Integer spentHours) { tempCustomer.setSpentHours(spentHours); } + + public void setTempTotalPaidAmount(Integer totalPaidAmount) { tempCustomer.setTotalPaidAmount(totalPaidAmount); } + + public String getTempInfo() { + updateGroupOfTempCustomer(); + return tempCustomer.toString(); + } + + public void addTempIntoRepository() { + // app logic에 따라 다음 두 구문이 true 임을 보장합니다. + assert tempCustomer != null; + assert !isReachedMaxCapacity(); + + add(tempCustomer); + tempCustomer = null; + } + + public boolean isTempIdNull() {return tempCustomer.getId() == null; } + + public String deleteAndGetInfoOf(int num) { + int idx = num - 1; + return remove(idx).toString(); + } + + public String setTempAndGetInfoOf(int num) { + int idx = num - 1; + Customer updatingCustomer = get(idx); + tempCustomer = new Customer(updatingCustomer); + tempIdx = idx; + return updatingCustomer.toString(); + } + + public void updateTempInRepository() { get(tempIdx).copy(tempCustomer); } + + public String getUpdateBeforeAndAfterInfo() { + Customer before = get(tempIdx); + Customer after = tempCustomer; + updateGroupOfTempCustomer(); + return String.format("\nNo. %2d\n", tempIdx) + + "Before: " + before + '\n'+ + "After : " + after; + } + + public void updateGroupOfTempCustomer() { tempCustomer.updateGroup(); } + + public void updateGroupIn(Group group) { + Group[] groups = Group.values(); + int idx = 0; + while (groups[idx] != group) + idx++; + assert idx > 0; + Group rightLowGroup = groups[idx - 1]; + for (Customer customer : this) { + Group g = customer.getGroup(); + if (g == group || g == rightLowGroup) + customer.updateGroup(); + } + } + + @Override + public String toString() { + if (isEmpty()) return "No Customers." + " Please input one first.\n"; + return super.toString(); + } +} diff --git a/src/me/smartstore/customer/List.java b/src/me/smartstore/customer/List.java new file mode 100644 index 00000000..c32e521e --- /dev/null +++ b/src/me/smartstore/customer/List.java @@ -0,0 +1,149 @@ +package me.smartstore.customer; + + +import me.smartstore.customer.exception.MaxCapacityReachedException; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.function.Consumer; + +public class List implements Iterable { + + private static final int DEFAULT_CAPACITY = 16; + private static final int MAX_CAPACITY = 100; + private static final int MIN_CAPACITY = 16; + + private E[] list; + private int size = 0; + private int reduceCapacityThreshold; + + List() { this(DEFAULT_CAPACITY); } + + @SuppressWarnings("unchecked") + List(int initCapacity) { + if (initCapacity > MAX_CAPACITY) + initCapacity = MAX_CAPACITY; + list = (E[]) new Object[initCapacity]; + reduceCapacityThreshold = initCapacity >>> 2; + } + + class ListIterator implements Iterator { + private int idx = 0; + + @Override + public boolean hasNext() { + return idx < size; + } + + @Override + public E next() { + return list[idx++]; + } + } + + public void checkIfReachedMaxCapacity() throws MaxCapacityReachedException { + if (isReachedMaxCapacity()) + throw new MaxCapacityReachedException("The maximum capable number of elements was reached.\n"); + } + + public boolean isReachedMaxCapacity() { return size == MAX_CAPACITY; } + + public boolean isEmpty() { return size == 0; } + + public int size() { return size; } + + public E get(int idx) throws ArrayIndexOutOfBoundsException { + checkIfOutOfBounds(idx); + return list[idx]; + } + + public void add(E e) throws IllegalArgumentException, MaxCapacityReachedException { + checkIfNull(e); + checkIfReachedMaxCapacity(); + if (isFull()) + increaseCapacity(); + list[size++] = e; + } + + private void checkIfNull(E e) { + if (e == null) + throw new IllegalArgumentException("Input element is null"); + } + + private boolean isFull() { return size == list.length; } + + private void increaseCapacity() { + int newLength = Math.min(MAX_CAPACITY, list.length << 1); + list = Arrays.copyOf(list, newLength); + } + + public E remove(int idx) throws ArrayIndexOutOfBoundsException { + checkIfOutOfBounds(idx); + + E ret = list[idx]; + if (size - 1 <= reduceCapacityThreshold) { + reduceCapacity(idx); + } else { + System.arraycopy(list, idx + 1, list, idx, size - idx); + size--; + } + return ret; + } + + private void reduceCapacity(int idx) { + int newCapacity = Math.max(MIN_CAPACITY, list.length >>> 1); + @SuppressWarnings("unchecked") + E[] newList = (E[]) new Object[newCapacity]; + System.arraycopy(list, 0, newList, 0, idx); + System.arraycopy(list, idx + 1, newList, idx, size - 1 - idx); + list = newList; + size--; + reduceCapacityThreshold = newCapacity >>> 2; + } + + private void checkIfOutOfBounds(int idx) { + if (idx < 0 || idx >= size) { + String msg = String.format("Acceptable range: (0~%d), but input: %d", size - 1, idx); + throw new ArrayIndexOutOfBoundsException(msg); + } + } + + public void sort(Comparator comparator) { + for (int i = 1; i < size; ++i) { + int j = i; + E src = list[j--]; + while (j >= 0 && comparator.compare(list[j], src) > 0) { + list[j + 1] = list[j]; + j--; + } + list[j + 1] = src; + } + } + + @Override + public Iterator iterator() { + return new ListIterator(); + } + + @Override + public void forEach(Consumer action) { + Iterable.super.forEach(action); + } + + @Override + public Spliterator spliterator() { + return Iterable.super.spliterator(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("======= Stored Customers Info. =======\n"); + for (int i = 0; i < size; ++i) { + String line = String.format("No. %2d => %s\n", i + 1, list[i].toString()); + sb.append(line); + } + return sb.toString(); + } +} diff --git a/src/me/smartstore/customer/exception/DuplicateCustomerIdException.java b/src/me/smartstore/customer/exception/DuplicateCustomerIdException.java new file mode 100644 index 00000000..f6da1835 --- /dev/null +++ b/src/me/smartstore/customer/exception/DuplicateCustomerIdException.java @@ -0,0 +1,5 @@ +package me.smartstore.customer.exception; + +public class DuplicateCustomerIdException extends IllegalStateException { + public DuplicateCustomerIdException(String msg) { super(msg); } +} diff --git a/src/me/smartstore/customer/exception/InvalidCustomerIdException.java b/src/me/smartstore/customer/exception/InvalidCustomerIdException.java new file mode 100644 index 00000000..8db2d20e --- /dev/null +++ b/src/me/smartstore/customer/exception/InvalidCustomerIdException.java @@ -0,0 +1,5 @@ +package me.smartstore.customer.exception; + +public class InvalidCustomerIdException extends IllegalArgumentException { + public InvalidCustomerIdException(String msg) { super(msg); } +} diff --git a/src/me/smartstore/customer/exception/InvalidCustomerNameException.java b/src/me/smartstore/customer/exception/InvalidCustomerNameException.java new file mode 100644 index 00000000..879d4d5e --- /dev/null +++ b/src/me/smartstore/customer/exception/InvalidCustomerNameException.java @@ -0,0 +1,5 @@ +package me.smartstore.customer.exception; + +public class InvalidCustomerNameException extends IllegalArgumentException { + public InvalidCustomerNameException(String msg) { super(msg); } +} diff --git a/src/me/smartstore/customer/exception/MaxCapacityReachedException.java b/src/me/smartstore/customer/exception/MaxCapacityReachedException.java new file mode 100644 index 00000000..5d0c61bf --- /dev/null +++ b/src/me/smartstore/customer/exception/MaxCapacityReachedException.java @@ -0,0 +1,5 @@ +package me.smartstore.customer.exception; + +public class MaxCapacityReachedException extends IllegalStateException { + public MaxCapacityReachedException(String msg) { super(msg); } +} diff --git a/src/me/smartstore/group/Group.java b/src/me/smartstore/group/Group.java new file mode 100644 index 00000000..fc759a1a --- /dev/null +++ b/src/me/smartstore/group/Group.java @@ -0,0 +1,104 @@ +package me.smartstore.group; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.exception.InvalidGroupNameException; + +import java.util.Arrays; + +public enum Group { + + NONE("N"), + GENERAL("G"), + VIP("V"), + VVIP("VV"); + + private final String shortcut; + private final GroupParameter groupParameter; + + Group(String shortcut) { + this.shortcut = shortcut; + this.groupParameter = new GroupParameter(); + } + + private static final Group[] USED_GROUPS = { GENERAL, VIP, VVIP }; + + private static GroupParameter tempParameter; + private static Group tempGroup; + + public static Group[] getUsedGroups() { return USED_GROUPS; } + + public static Group getGroupByString(String s) throws InvalidGroupNameException { + Group[] groups = Group.getUsedGroups(); + return Arrays.stream(groups) + .filter(group -> group.isName(s)) + .findAny() + .orElseThrow(() -> new InvalidGroupNameException("\nInvalid Group Name for Input. Please try again.\n")); + } + + private boolean isName(String s) { + return this.shortcut.equalsIgnoreCase(s) || this.name().equalsIgnoreCase(s); + } + + // only for test + public void setGroupParameter(Integer[] groupParameterArguments) { + this.groupParameter.setMinSpentHours(groupParameterArguments[0]); + this.groupParameter.setMinTotalPaidAmount(groupParameterArguments[1]); + } + + public static Group getGroupByParameter(Integer spentHours, Integer totalPaidAmount) { + Group ret = NONE; + for (Group group : getUsedGroups()) { + GroupParameter param = group.groupParameter; + Integer minSpentHours = param.getMinSpentHours(); + Integer minTotalPaidAmount = param.getMinTotalPaidAmount(); + if (minSpentHours == null && minTotalPaidAmount == null) + continue; + if (minSpentHours != null) + if (spentHours == null || spentHours < minSpentHours) break; + if (minTotalPaidAmount != null) + if (totalPaidAmount == null || totalPaidAmount < minTotalPaidAmount) break; + ret = group; + } + return ret; + } + + public static void setTempMinSpentHours(Integer minSpentHours) { + tempParameter.setMinSpentHours(minSpentHours); + } + + public static void setTempMinTotalPaidAmount(Integer minTotalPaidAmount) { + tempParameter.setMinTotalPaidAmount(minTotalPaidAmount); + } + + public static void setTempParameter(Group group) { + GroupParameter param = group.groupParameter; + tempParameter = new GroupParameter(param.getMinSpentHours(), param.getMinTotalPaidAmount()); + tempGroup = group; + } + + public static String getUpdateBeforeAndAfterInfo() { + String before = tempGroup.groupParameter.toString(); + String after = tempParameter.toString(); + return getGroupNameInfo(tempGroup) + + "Before: " + before + '\n'+ + "After : " + after; + } + + public static void updateGroupParameter() { + GroupParameter param = tempGroup.groupParameter; + param.setMinSpentHours(tempParameter.getMinSpentHours()); + param.setMinTotalPaidAmount(tempParameter.getMinTotalPaidAmount()); + + CustomerRepository.getInstance().updateGroupIn(tempGroup); + } + + @Override + public String toString() { + return getGroupNameInfo(this) + + "Parameter: " + this.groupParameter + '\n'; + } + + public static String getGroupNameInfo(Group group) { + return '\n' + "Group: " + group.name() + '\n'; + } +} diff --git a/src/me/smartstore/group/GroupParameter.java b/src/me/smartstore/group/GroupParameter.java new file mode 100644 index 00000000..4bf3aafb --- /dev/null +++ b/src/me/smartstore/group/GroupParameter.java @@ -0,0 +1,31 @@ +package me.smartstore.group; + +public class GroupParameter { + private Integer minSpentHours; + private Integer minTotalPaidAmount; + + public GroupParameter() {} + + public GroupParameter(Integer minSpentHours, Integer minTotalPaidAmount) { + this.minSpentHours = minSpentHours; + this.minTotalPaidAmount = minTotalPaidAmount; + } + + public void setMinSpentHours(Integer minSpentHours) { + this.minSpentHours = minSpentHours; + } + + public void setMinTotalPaidAmount(Integer minTotalPaidAmount) { + this.minTotalPaidAmount = minTotalPaidAmount; + } + + public Integer getMinSpentHours() { return minSpentHours; } + + public Integer getMinTotalPaidAmount() { return minTotalPaidAmount; } + + @Override + public String toString() { + return String.format("Parameter{minSpentHours=%d, minTotalPaidAmount=%d}", + minSpentHours, minTotalPaidAmount); + } +} diff --git a/src/me/smartstore/menu/InputHandlerMenu.java b/src/me/smartstore/menu/InputHandlerMenu.java new file mode 100644 index 00000000..313b5b61 --- /dev/null +++ b/src/me/smartstore/menu/InputHandlerMenu.java @@ -0,0 +1,4 @@ +package me.smartstore.menu; + +public abstract class InputHandlerMenu extends Menu { +} diff --git a/src/me/smartstore/menu/Menu.java b/src/me/smartstore/menu/Menu.java new file mode 100644 index 00000000..3e873d27 --- /dev/null +++ b/src/me/smartstore/menu/Menu.java @@ -0,0 +1,77 @@ +package me.smartstore.menu; + +import me.smartstore.menu.exception.InputIsEndException; + +import java.util.InputMismatchException; + +public abstract class Menu { + + private static final Reader reader = Reader.getInstance(); + private static final Printer printer = Printer.getInstance(); + protected static final String END_INPUT = "** Press 'end', if you want to exit! **\n"; + + private Menu[] nextMenus; + private Menu BACK_MENU; + private Menu prevMenu; + + protected Menu() {} + + public abstract Menu printAndInputAndGetNextMenu(); + + protected abstract void setNextMenus(); + + protected final Menu getNextMenu(int idx) { return nextMenus[idx]; } + + protected final Menu getBackMenu() { return BACK_MENU; } + + public final void setNextMenus(Menu... nextMenus) { + int len = nextMenus.length; + if (this.nextMenus == null) + this.nextMenus = new Menu[len]; + System.arraycopy(nextMenus, 0, this.nextMenus, 0, len); + BACK_MENU = this.nextMenus[len - 1]; + } + + public final void setPrevMenu(Menu menu) { this.prevMenu = menu; } + + protected final Menu getPrevMenu() { return this.prevMenu; } + + protected void print(Object s) { + printer.print(s.toString()); + } + + protected int inputMenuIdx() throws InputMismatchException { + int menu = inputIntegerRanged(1, nextMenus.length); + return menu - 1; + } + + protected final String inputStringOrEnd() throws InputIsEndException { + String s = reader.inputString(); + checkIfInputIsEnd(s); + return s; + } + + protected void checkIfInputIsEnd(String s) throws InputIsEndException { + if (s.equalsIgnoreCase("end")) + throw new InputIsEndException("'end' is pressed. Exit this menu.\n\n"); + } + + protected Integer inputZeroOrPositiveIntegerOrEnd() throws InputIsEndException, InputMismatchException { + String s = inputStringOrEnd(); + try { + int i = Integer.parseInt(s); + if (i < 0) + throw new InputMismatchException("Invalid Input. Please try again.\n"); + return i; + } catch (NumberFormatException e) { + throw new InputMismatchException("Invalid Format for Input. Please try again.\n"); + } + } + + protected int inputIntegerRanged(int fromInclusive, int toInclusive) throws InputMismatchException { + int i = reader.inputInteger(); + if (i < fromInclusive || i > toInclusive) + throw new InputMismatchException("Invalid Input. Please try again.\n"); + return i; + } +} diff --git a/src/me/smartstore/menu/Printer.java b/src/me/smartstore/menu/Printer.java new file mode 100644 index 00000000..0bbb7f23 --- /dev/null +++ b/src/me/smartstore/menu/Printer.java @@ -0,0 +1,21 @@ +package me.smartstore.menu; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; + +public class Printer { + private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); + private static final Printer INSTANCE = new Printer(); + private Printer() {} + public static Printer getInstance() { return INSTANCE; } + + public void print(String str) throws RuntimeException { + try { + bw.write(str); + bw.flush(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/me/smartstore/menu/QuitMenu.java b/src/me/smartstore/menu/QuitMenu.java new file mode 100644 index 00000000..8cf54be5 --- /dev/null +++ b/src/me/smartstore/menu/QuitMenu.java @@ -0,0 +1,17 @@ +package me.smartstore.menu; + +public class QuitMenu extends Menu { + + private static final QuitMenu INSTANCE = new QuitMenu(); + private QuitMenu() {} + public static QuitMenu getInstance() { return INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + Printer.getInstance().print("\nProgram Finished.\n"); + return null; + } + + @Override + protected void setNextMenus() {} +} diff --git a/src/me/smartstore/menu/Reader.java b/src/me/smartstore/menu/Reader.java new file mode 100644 index 00000000..a017ef77 --- /dev/null +++ b/src/me/smartstore/menu/Reader.java @@ -0,0 +1,35 @@ +package me.smartstore.menu; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.InputMismatchException; +import java.util.StringTokenizer; + +public class Reader { + private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + private static final Reader INSTANCE = new Reader(); + private Reader() {} + public static Reader getInstance() { return INSTANCE; } + + public int inputInteger() throws InputMismatchException { + StringTokenizer st = new StringTokenizer(nextLine()); + try { + return Integer.parseInt(st.nextToken()); + } catch (NumberFormatException e) { + throw new InputMismatchException("Invalid Format for Input." + " Please try again.\n"); + } + } + + public String inputString() { + return nextLine(); + } + + private String nextLine() throws RuntimeException { + try { + return br.readLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/me/smartstore/menu/customer/AddCustomerConfirmMenu.java b/src/me/smartstore/menu/customer/AddCustomerConfirmMenu.java new file mode 100644 index 00000000..c947f905 --- /dev/null +++ b/src/me/smartstore/menu/customer/AddCustomerConfirmMenu.java @@ -0,0 +1,57 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.AddCustomerMenu; + +import java.util.InputMismatchException; + +public class AddCustomerConfirmMenu extends Menu { + + private static final String ADD_CUSTOMER_CONFIRM_OUTPUT = + '\n' + + "==== Add Customer Confirm ====" + '\n' + + " 1. " + "Yes (Add)" + '\n' + + " 2. " + "No (Back)" + '\n' + + "==============================" + '\n' + + "Choose One: "; + + private static class InstanceHolder { + private static final AddCustomerConfirmMenu INSTANCE = new AddCustomerConfirmMenu(); + } + private AddCustomerConfirmMenu() { super(); } + public static AddCustomerConfirmMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + setNextMenus(); + String tempCustomerInfo = getTempCustomerInfo(); + while (true) { + try { + print('\n' + tempCustomerInfo); + if (isTempCustomerIdNull()) { + print("\nID input must be required.\n"); + return getBackMenu(); + } + print(ADD_CUSTOMER_CONFIRM_OUTPUT); + int menuIdx = inputMenuIdx(); + return getNextMenu(menuIdx); + } catch (InputMismatchException e) { + print(e.getMessage()); + } + } + } + + @Override + protected void setNextMenus() { + setNextMenus(AddCustomerIntoRepositoryMenu.getInstance(), AddCustomerMenu.getInstance()); + } + + private String getTempCustomerInfo() { + return CustomerRepository.getInstance().getTempInfo(); + } + + private boolean isTempCustomerIdNull() { + return CustomerRepository.getInstance().isTempIdNull(); + } +} diff --git a/src/me/smartstore/menu/customer/AddCustomerIntoRepositoryMenu.java b/src/me/smartstore/menu/customer/AddCustomerIntoRepositoryMenu.java new file mode 100644 index 00000000..93c19759 --- /dev/null +++ b/src/me/smartstore/menu/customer/AddCustomerIntoRepositoryMenu.java @@ -0,0 +1,30 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.CustomerIntroMenu; + +public class AddCustomerIntoRepositoryMenu extends Menu { + + private static class InstanceHolder { + private static final AddCustomerIntoRepositoryMenu INSTANCE = new AddCustomerIntoRepositoryMenu(); + } + private AddCustomerIntoRepositoryMenu() {} + public static AddCustomerIntoRepositoryMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + setNextMenus(); + addTempCustomerIntoRepository(); + return getBackMenu(); + } + + @Override + protected void setNextMenus() { + setNextMenus(CustomerIntroMenu.getInstance()); + } + + private void addTempCustomerIntoRepository() { + CustomerRepository.getInstance().addTempIntoRepository(); + } +} diff --git a/src/me/smartstore/menu/customer/DeleteCustomerMenu.java b/src/me/smartstore/menu/customer/DeleteCustomerMenu.java new file mode 100644 index 00000000..dc56f107 --- /dev/null +++ b/src/me/smartstore/menu/customer/DeleteCustomerMenu.java @@ -0,0 +1,41 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.CustomerIntroMenu; + +import java.util.InputMismatchException; + +public class DeleteCustomerMenu extends Menu { + + private static class InstanceHolder { + private static final DeleteCustomerMenu INSTANCE = new DeleteCustomerMenu(); + } + private DeleteCustomerMenu() {} + public static DeleteCustomerMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + setNextMenus(); + CustomerRepository repository = CustomerRepository.getInstance(); + int size = repository.size(); + print('\n' + repository.toString()); + final String NUM_TO_DELETE_INPUT = "Which customer ( 1 ~ " + size + " )? "; + while (true) { + print(NUM_TO_DELETE_INPUT); + try { + int num = inputIntegerRanged(1, size); + String deletedCustomerInfo = repository.deleteAndGetInfoOf(num); + print("\nDelete\n No. " + num + ' ' + deletedCustomerInfo + "\n\n" + repository); + return getBackMenu(); + } catch (InputMismatchException e) { + print(e.getMessage()); + } + } + } + + @Override + protected void setNextMenus() { + setNextMenus(CustomerIntroMenu.getInstance()); + } +} diff --git a/src/me/smartstore/menu/customer/InputCustomerIdMenu.java b/src/me/smartstore/menu/customer/InputCustomerIdMenu.java new file mode 100644 index 00000000..7178c557 --- /dev/null +++ b/src/me/smartstore/menu/customer/InputCustomerIdMenu.java @@ -0,0 +1,31 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.customer.exception.DuplicateCustomerIdException; +import me.smartstore.customer.exception.InvalidCustomerIdException; +import me.smartstore.menu.exception.InputIsEndException; + +import static me.smartstore.customer.Customer.ID_FORMAT; + +public class InputCustomerIdMenu extends InputCustomerPropertyMenu { + + private static final String ID_INPUT = + "Input " + "Customer" + "'s " + "ID" + ":\n" + + ID_FORMAT; + + private static class InstanceHolder { + private static final InputCustomerIdMenu INSTANCE = new InputCustomerIdMenu(); + } + private InputCustomerIdMenu() { super(ID_INPUT); } + public static InputCustomerIdMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected Object inputProperty() throws InputIsEndException { + return inputStringOrEnd(); + } + + @Override + protected void setTempProperty(Object property) throws InvalidCustomerIdException, DuplicateCustomerIdException { + CustomerRepository.getInstance().setTempId((String) property); + } +} diff --git a/src/me/smartstore/menu/customer/InputCustomerNameMenu.java b/src/me/smartstore/menu/customer/InputCustomerNameMenu.java new file mode 100644 index 00000000..f4bf7e44 --- /dev/null +++ b/src/me/smartstore/menu/customer/InputCustomerNameMenu.java @@ -0,0 +1,30 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.customer.exception.InvalidCustomerNameException; +import me.smartstore.menu.exception.InputIsEndException; + +import static me.smartstore.customer.Customer.NAME_FORMAT; + +public class InputCustomerNameMenu extends InputCustomerPropertyMenu { + + private static final String NAME_INPUT = + "Input " + "Customer" + "'s " + "Name" + ":\n" + + NAME_FORMAT; + + private static class InstanceHolder { + private static final InputCustomerNameMenu INSTANCE = new InputCustomerNameMenu(); + } + private InputCustomerNameMenu() { super(NAME_INPUT); } + public static InputCustomerNameMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected String inputProperty() throws InputIsEndException { + return inputStringOrEnd(); + } + + @Override + protected void setTempProperty(Object property) throws InvalidCustomerNameException { + CustomerRepository.getInstance().setTempName((String) property); + } +} diff --git a/src/me/smartstore/menu/customer/InputCustomerPropertyMenu.java b/src/me/smartstore/menu/customer/InputCustomerPropertyMenu.java new file mode 100644 index 00000000..96f35859 --- /dev/null +++ b/src/me/smartstore/menu/customer/InputCustomerPropertyMenu.java @@ -0,0 +1,47 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.Menu; +import me.smartstore.menu.exception.InputIsEndException; + +import java.util.InputMismatchException; + +public abstract class InputCustomerPropertyMenu extends Menu { + + private final String PROPERTY_INPUT; + + InputCustomerPropertyMenu(String msg) { + PROPERTY_INPUT = msg + '\n' + END_INPUT; + } + + @Override + public Menu printAndInputAndGetNextMenu() { + if (getPrevMenu() == UpdateCustomerMenu.getInstance()) + CustomerRepository.getInstance().resetTempCustomer(); + inputPropertyAndSetItIntoTemp(); + return getBackMenu(); + } + + @Override + protected void setNextMenus() {} + + protected void inputPropertyAndSetItIntoTemp() { + while (true) { + print(PROPERTY_INPUT); + try { + Object property = inputProperty(); + setTempProperty(property); + return; + } catch (InputIsEndException | InputMismatchException | + IllegalArgumentException | IllegalStateException e) { + print(e.getMessage()); + if (e instanceof InputIsEndException) + return; + } + } + } + + protected abstract Object inputProperty() throws InputIsEndException, InputMismatchException; + + protected abstract void setTempProperty(Object property) throws IllegalArgumentException, IllegalStateException; +} diff --git a/src/me/smartstore/menu/customer/InputCustomerSpentHoursMenu.java b/src/me/smartstore/menu/customer/InputCustomerSpentHoursMenu.java new file mode 100644 index 00000000..7902bfb7 --- /dev/null +++ b/src/me/smartstore/menu/customer/InputCustomerSpentHoursMenu.java @@ -0,0 +1,28 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.exception.InputIsEndException; + +import java.util.InputMismatchException; + +public class InputCustomerSpentHoursMenu extends InputCustomerPropertyMenu { + + private static final String SPENT_HOURS_INPUT = + "Input " + "Customer" + "'s " + "Spent Hours" + ':'; + + private static class InstanceHolder { + private static final InputCustomerSpentHoursMenu INSTANCE = new InputCustomerSpentHoursMenu(); + } + private InputCustomerSpentHoursMenu() { super(SPENT_HOURS_INPUT); } + public static InputCustomerSpentHoursMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected Object inputProperty() throws InputIsEndException, InputMismatchException { + return inputZeroOrPositiveIntegerOrEnd(); + } + + @Override + protected void setTempProperty(Object property) throws IllegalArgumentException, IllegalStateException { + CustomerRepository.getInstance().setTempSpentHours((Integer) property); + } +} diff --git a/src/me/smartstore/menu/customer/InputCustomerTotalPaidAmountMenu.java b/src/me/smartstore/menu/customer/InputCustomerTotalPaidAmountMenu.java new file mode 100644 index 00000000..f2281ac8 --- /dev/null +++ b/src/me/smartstore/menu/customer/InputCustomerTotalPaidAmountMenu.java @@ -0,0 +1,28 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.exception.InputIsEndException; + +import java.util.InputMismatchException; + +public class InputCustomerTotalPaidAmountMenu extends InputCustomerPropertyMenu { + + private static final String TOTAL_PAID_AMOUNT_INPUT = + "Input " + "Customer" + "'s " + "Total Amount Paid" + ':'; + + private static class InstanceHolder { + private static final InputCustomerTotalPaidAmountMenu INSTANCE = new InputCustomerTotalPaidAmountMenu(); + } + private InputCustomerTotalPaidAmountMenu() { super(TOTAL_PAID_AMOUNT_INPUT); } + public static InputCustomerTotalPaidAmountMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected Object inputProperty() throws InputIsEndException, InputMismatchException { + return inputZeroOrPositiveIntegerOrEnd(); + } + + @Override + protected void setTempProperty(Object property) throws IllegalArgumentException, IllegalStateException { + CustomerRepository.getInstance().setTempTotalPaidAmount((Integer) property); + } +} diff --git a/src/me/smartstore/menu/customer/UpdateCustomerConfirmMenu.java b/src/me/smartstore/menu/customer/UpdateCustomerConfirmMenu.java new file mode 100644 index 00000000..eaf1c176 --- /dev/null +++ b/src/me/smartstore/menu/customer/UpdateCustomerConfirmMenu.java @@ -0,0 +1,44 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.Menu; + +import java.util.InputMismatchException; + +public class UpdateCustomerConfirmMenu extends Menu { + + private static final String UPDATE_CUSTOMER_CONFIRM_OUTPUT = + '\n' + + "==== Update Customer Confirm ====" + '\n' + + " 1. " + "Yes (Update)" + '\n' + + " 2. " + "No (Back)" + '\n' + + "==============================" + '\n' + + "Choose One: "; + + private static class InstanceHolder { + private static final UpdateCustomerConfirmMenu INSTANCE = new UpdateCustomerConfirmMenu(); + } + private UpdateCustomerConfirmMenu() {} + public static UpdateCustomerConfirmMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + setNextMenus(); + final String updateBeforeAndAfterInfo = CustomerRepository.getInstance().getUpdateBeforeAndAfterInfo(); + while (true) { + try { + print(updateBeforeAndAfterInfo); + print(UPDATE_CUSTOMER_CONFIRM_OUTPUT); + int menuIdx = inputMenuIdx(); + return getNextMenu(menuIdx); + } catch (InputMismatchException e) { + print(e.getMessage()); + } + } + } + + @Override + protected void setNextMenus() { + setNextMenus(UpdateCustomerIntoRepositoryMenu.getInstance(), UpdateCustomerMenu.getInstance()); + } +} diff --git a/src/me/smartstore/menu/customer/UpdateCustomerIntoRepositoryMenu.java b/src/me/smartstore/menu/customer/UpdateCustomerIntoRepositoryMenu.java new file mode 100644 index 00000000..d8fec3f3 --- /dev/null +++ b/src/me/smartstore/menu/customer/UpdateCustomerIntoRepositoryMenu.java @@ -0,0 +1,30 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.CustomerIntroMenu; + +public class UpdateCustomerIntoRepositoryMenu extends Menu { + + private static class InstanceHolder { + private static final UpdateCustomerIntoRepositoryMenu INSTANCE = new UpdateCustomerIntoRepositoryMenu(); + } + private UpdateCustomerIntoRepositoryMenu() {} + public static UpdateCustomerIntoRepositoryMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + setNextMenus(); + updateTempCustomerInRepository(); + return getBackMenu(); + } + + @Override + protected void setNextMenus() { + setNextMenus(CustomerIntroMenu.getInstance()); + } + + private void updateTempCustomerInRepository() { + CustomerRepository.getInstance().updateTempInRepository(); + } +} diff --git a/src/me/smartstore/menu/customer/UpdateCustomerMenu.java b/src/me/smartstore/menu/customer/UpdateCustomerMenu.java new file mode 100644 index 00000000..bf61bf5d --- /dev/null +++ b/src/me/smartstore/menu/customer/UpdateCustomerMenu.java @@ -0,0 +1,42 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.CustomerIntroMenu; +import me.smartstore.menu.topic.UpdateCustomerSelectPropertyMenu; + +import java.util.InputMismatchException; + +public class UpdateCustomerMenu extends Menu { + + private static class InstanceHolder { + private static final UpdateCustomerMenu INSTANCE = new UpdateCustomerMenu(); + } + private UpdateCustomerMenu() {} + public static UpdateCustomerMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + setNextMenus(); + CustomerRepository repository = CustomerRepository.getInstance(); + int size = repository.size(); + print('\n' + repository.toString()); + final String NUM_TO_UPDATE_INPUT = "Which customer ( 1 ~ " + size + " )? "; + while (true) { + print(NUM_TO_UPDATE_INPUT); + try { + int num = inputIntegerRanged(1, size); + String updatingCustomerInfo = repository.setTempAndGetInfoOf(num); + print("======= Updating Customer Info. =======\n" + updatingCustomerInfo + '\n'); + return UpdateCustomerSelectPropertyMenu.getInstance(); + } catch (InputMismatchException e) { + print(e.getMessage()); + } + } + } + + @Override + protected void setNextMenus() { + setNextMenus(CustomerIntroMenu.getInstance()); + } +} diff --git a/src/me/smartstore/menu/customer/ViewCustomerMenu.java b/src/me/smartstore/menu/customer/ViewCustomerMenu.java new file mode 100644 index 00000000..0c7df663 --- /dev/null +++ b/src/me/smartstore/menu/customer/ViewCustomerMenu.java @@ -0,0 +1,26 @@ +package me.smartstore.menu.customer; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.CustomerIntroMenu; + +public class ViewCustomerMenu extends Menu { + + private static class InstanceHolder { + private static final ViewCustomerMenu INSTANCE = new ViewCustomerMenu(); + } + private ViewCustomerMenu() {} + public static ViewCustomerMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + print(CustomerRepository.getInstance()); + setNextMenus(); + return getBackMenu(); + } + + @Override + protected void setNextMenus() { + setNextMenus(CustomerIntroMenu.getInstance()); + } +} diff --git a/src/me/smartstore/menu/exception/InputIsEndException.java b/src/me/smartstore/menu/exception/InputIsEndException.java new file mode 100644 index 00000000..b50d4b1d --- /dev/null +++ b/src/me/smartstore/menu/exception/InputIsEndException.java @@ -0,0 +1,10 @@ +package me.smartstore.menu.exception; + +import me.smartstore.AppException; + +public class InputIsEndException extends AppException { + + public InputIsEndException(String s) { + super(s); + } +} diff --git a/src/me/smartstore/menu/exception/InvalidGroupNameException.java b/src/me/smartstore/menu/exception/InvalidGroupNameException.java new file mode 100644 index 00000000..5d061d27 --- /dev/null +++ b/src/me/smartstore/menu/exception/InvalidGroupNameException.java @@ -0,0 +1,8 @@ +package me.smartstore.menu.exception; + +public class InvalidGroupNameException extends IllegalArgumentException { + + public InvalidGroupNameException(String s) { + super(s); + } +} diff --git a/src/me/smartstore/menu/group/GroupParameterMenu.java b/src/me/smartstore/menu/group/GroupParameterMenu.java new file mode 100644 index 00000000..627f2f93 --- /dev/null +++ b/src/me/smartstore/menu/group/GroupParameterMenu.java @@ -0,0 +1,41 @@ +package me.smartstore.menu.group; + +import me.smartstore.group.Group; +import me.smartstore.menu.Menu; +import me.smartstore.menu.exception.InputIsEndException; +import me.smartstore.menu.exception.InvalidGroupNameException; +import me.smartstore.menu.topic.GroupIntroMenu; + +public abstract class GroupParameterMenu extends Menu { + + private static final String GROUP_OUTPUT = + '\n' + + "Which group (GENERAL (G), VIP (V), VVIP (VV))?\n" + + END_INPUT; + private Group groupCache; + + @Override + public Menu printAndInputAndGetNextMenu() { + if (getPrevMenu() == GroupIntroMenu.getInstance()) { + while (true) { + print(GROUP_OUTPUT); + try { + String groupName = inputStringOrEnd(); + groupCache = Group.getGroupByString(groupName); + break; + } catch (InputIsEndException e) { + print(e.getMessage()); + return GroupIntroMenu.getInstance(); + } catch (InvalidGroupNameException e) { + print(e.getMessage()); + } + } + } + return handleAndMoveToNextMenu(groupCache); + } + + @Override + protected void setNextMenus() {} + + protected abstract Menu handleAndMoveToNextMenu(Group group); +} diff --git a/src/me/smartstore/menu/group/InputGroupParmeterMenu.java b/src/me/smartstore/menu/group/InputGroupParmeterMenu.java new file mode 100644 index 00000000..d11bebad --- /dev/null +++ b/src/me/smartstore/menu/group/InputGroupParmeterMenu.java @@ -0,0 +1,35 @@ +package me.smartstore.menu.group; + +import me.smartstore.menu.Menu; +import me.smartstore.menu.exception.InputIsEndException; + +import java.util.InputMismatchException; + +public abstract class InputGroupParmeterMenu extends Menu { + + private final String PARAMETER_INPUT; + + InputGroupParmeterMenu(String PARAMETER_INPUT) { this.PARAMETER_INPUT = PARAMETER_INPUT; } + + @Override + public Menu printAndInputAndGetNextMenu() { + while (true) { + print(PARAMETER_INPUT); + try { + Integer property = inputZeroOrPositiveIntegerOrEnd(); + setTempProperty(property); + return getPrevMenu(); + } catch (InputMismatchException e) { + print(e.getMessage()); + } catch (InputIsEndException e) { + print(e.getMessage()); + return getPrevMenu(); + } + } + } + + @Override + protected void setNextMenus() {} + + protected abstract void setTempProperty(Integer property); +} diff --git a/src/me/smartstore/menu/group/InputMinSpentHoursMenu.java b/src/me/smartstore/menu/group/InputMinSpentHoursMenu.java new file mode 100644 index 00000000..a138f229 --- /dev/null +++ b/src/me/smartstore/menu/group/InputMinSpentHoursMenu.java @@ -0,0 +1,23 @@ +package me.smartstore.menu.group; + +import me.smartstore.group.Group; + +public class InputMinSpentHoursMenu extends InputGroupParmeterMenu { + + private static final String MIN_SPENT_HOURS_INPUT = + '\n' + "Input " + "Minimum " + "Spent Hours" + ":\n" + END_INPUT; + + private static class InstanceHolder { + private static final InputMinSpentHoursMenu INSTANCE = new InputMinSpentHoursMenu(); + } + private InputMinSpentHoursMenu() { super(MIN_SPENT_HOURS_INPUT); } + + public static InputMinSpentHoursMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected void setNextMenus() {} + + protected void setTempProperty(Integer property) { + Group.setTempMinSpentHours(property); + } +} diff --git a/src/me/smartstore/menu/group/InputMinTotalPaidAmountMenu.java b/src/me/smartstore/menu/group/InputMinTotalPaidAmountMenu.java new file mode 100644 index 00000000..72b1da40 --- /dev/null +++ b/src/me/smartstore/menu/group/InputMinTotalPaidAmountMenu.java @@ -0,0 +1,23 @@ +package me.smartstore.menu.group; + +import me.smartstore.group.Group; + +public class InputMinTotalPaidAmountMenu extends InputGroupParmeterMenu { + + private static final String MIN_SPENT_HOURS_INPUT = + '\n' + "Input " + "Minimum " + "Total Paid Amount" + ":\n" + END_INPUT; + + private static class InstanceHolder { + private static final InputMinTotalPaidAmountMenu INSTANCE = new InputMinTotalPaidAmountMenu(); + } + private InputMinTotalPaidAmountMenu() { super(MIN_SPENT_HOURS_INPUT); } + + public static InputMinTotalPaidAmountMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected void setNextMenus() {} + + protected void setTempProperty(Integer property) { + Group.setTempMinTotalPaidAmount(property); + } +} diff --git a/src/me/smartstore/menu/group/UpdateGroupParameterConfirmMenu.java b/src/me/smartstore/menu/group/UpdateGroupParameterConfirmMenu.java new file mode 100644 index 00000000..0721ffa8 --- /dev/null +++ b/src/me/smartstore/menu/group/UpdateGroupParameterConfirmMenu.java @@ -0,0 +1,47 @@ +package me.smartstore.menu.group; + +import me.smartstore.group.Group; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.GroupIntroMenu; + +import java.util.InputMismatchException; + +public class UpdateGroupParameterConfirmMenu extends Menu { + + private static final String UPDATE_CUSTOMER_CONFIRM_OUTPUT = + '\n' + + "= Update Parameter Confirm ===" + '\n' + + " 1. " + "Yes (Update)" + '\n' + + " 2. " + "No (Back)" + '\n' + + "==============================" + '\n' + + "Choose One: "; + + private static class InstanceHolder { + private static final UpdateGroupParameterConfirmMenu INSTANCE = new UpdateGroupParameterConfirmMenu(); + } + private UpdateGroupParameterConfirmMenu() { super(); } + public static UpdateGroupParameterConfirmMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + setNextMenus(); + final String updateBeforeAndAfterInfo = Group.getUpdateBeforeAndAfterInfo(); + while (true) { + try { + print(updateBeforeAndAfterInfo); + print(UPDATE_CUSTOMER_CONFIRM_OUTPUT); + int menuIdx = inputMenuIdx(); + if (menuIdx == 0) + Group.updateGroupParameter(); + return getNextMenu(menuIdx); + } catch (InputMismatchException e) { + print(e.getMessage()); + } + } + } + + @Override + protected void setNextMenus() { + setNextMenus(GroupIntroMenu.getInstance(), UpdateParameterMenu.getInstance()); + } +} diff --git a/src/me/smartstore/menu/group/UpdateParameterMenu.java b/src/me/smartstore/menu/group/UpdateParameterMenu.java new file mode 100644 index 00000000..f1a535c4 --- /dev/null +++ b/src/me/smartstore/menu/group/UpdateParameterMenu.java @@ -0,0 +1,56 @@ +package me.smartstore.menu.group; + +import me.smartstore.group.Group; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.GroupIntroMenu; + +import java.util.InputMismatchException; + +public class UpdateParameterMenu extends GroupParameterMenu { + + private static final String UPDATE_PARAMETER_INPUT = + '\n' + + "======= Update Parameter =====" + '\n' + + " 1. " + "Minimum " + "Spent Hours" + '\n' + + " 2. " + "Minimum " + "Total Paid Amount" + '\n' + + " 3. " + "Confirm" + '\n' + + " 4. " + "Cancel(Back)" + '\n' + + "==============================" + '\n' + + "Choose One: "; + + private static class InstanceHolder { + private static final UpdateParameterMenu INSTANCE = new UpdateParameterMenu(); + } + + private UpdateParameterMenu() {} + + public static UpdateParameterMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public void setNextMenus() { + setNextMenus( + InputMinSpentHoursMenu.getInstance(), + InputMinTotalPaidAmountMenu.getInstance(), + UpdateGroupParameterConfirmMenu.getInstance(), + GroupIntroMenu.getInstance() + ); + } + + @Override + protected Menu handleAndMoveToNextMenu(Group group) { + if (getPrevMenu() == GroupIntroMenu.getInstance()) { + setNextMenus(); + print(group); + Group.setTempParameter(group); + } + while (true) { + try { + print(UPDATE_PARAMETER_INPUT); + int menuIdx = inputMenuIdx(); + return getNextMenu(menuIdx); + } catch (InputMismatchException e) { + print(e.getMessage()); + } + } + } +} diff --git a/src/me/smartstore/menu/group/ViewParameterMenu.java b/src/me/smartstore/menu/group/ViewParameterMenu.java new file mode 100644 index 00000000..e191e883 --- /dev/null +++ b/src/me/smartstore/menu/group/ViewParameterMenu.java @@ -0,0 +1,23 @@ +package me.smartstore.menu.group; + +import me.smartstore.group.Group; +import me.smartstore.menu.Menu; +import me.smartstore.menu.topic.GroupIntroMenu; + +public class ViewParameterMenu extends GroupParameterMenu { + + private static class InstanceHolder { + private static final ViewParameterMenu INSTANCE = new ViewParameterMenu(); + } + private ViewParameterMenu() {} + public static ViewParameterMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected void setNextMenus() {} + + @Override + protected Menu handleAndMoveToNextMenu(Group group) { + print(group); + return GroupIntroMenu.getInstance(); + } +} diff --git a/src/me/smartstore/menu/summary/SummaryByNameMenu.java b/src/me/smartstore/menu/summary/SummaryByNameMenu.java new file mode 100644 index 00000000..66077c01 --- /dev/null +++ b/src/me/smartstore/menu/summary/SummaryByNameMenu.java @@ -0,0 +1,18 @@ +package me.smartstore.menu.summary; + +import me.smartstore.summary.Order; +import me.smartstore.summary.SummaryByName; + +public class SummaryByNameMenu extends SummaryMenu { + + private static class InstanceHolder { + private static final SummaryByNameMenu INSTANCE = new SummaryByNameMenu(); + } + private SummaryByNameMenu() {} + public static SummaryByNameMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected String getSummary(Order order) { + return SummaryByName.getInstance().get(order); + } +} diff --git a/src/me/smartstore/menu/summary/SummaryBySpentHoursMenu.java b/src/me/smartstore/menu/summary/SummaryBySpentHoursMenu.java new file mode 100644 index 00000000..0b5ca8de --- /dev/null +++ b/src/me/smartstore/menu/summary/SummaryBySpentHoursMenu.java @@ -0,0 +1,18 @@ +package me.smartstore.menu.summary; + +import me.smartstore.summary.Order; +import me.smartstore.summary.SummaryBySpentHours; + +public class SummaryBySpentHoursMenu extends SummaryMenu { + + private static class InstanceHolder { + private static final SummaryBySpentHoursMenu INSTANCE = new SummaryBySpentHoursMenu(); + } + private SummaryBySpentHoursMenu() {} + public static SummaryBySpentHoursMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected String getSummary(Order order) { + return SummaryBySpentHours.getInstance().get(order); + } +} diff --git a/src/me/smartstore/menu/summary/SummaryByTotalPaidAmountMenu.java b/src/me/smartstore/menu/summary/SummaryByTotalPaidAmountMenu.java new file mode 100644 index 00000000..dc1ef70b --- /dev/null +++ b/src/me/smartstore/menu/summary/SummaryByTotalPaidAmountMenu.java @@ -0,0 +1,18 @@ +package me.smartstore.menu.summary; + +import me.smartstore.summary.Order; +import me.smartstore.summary.SummaryByTotalPaidAmount; + +public class SummaryByTotalPaidAmountMenu extends SummaryMenu { + + private static class InstanceHolder { + private static final SummaryByTotalPaidAmountMenu INSTANCE = new SummaryByTotalPaidAmountMenu(); + } + private SummaryByTotalPaidAmountMenu() {} + public static SummaryByTotalPaidAmountMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected String getSummary(Order order) { + return SummaryByTotalPaidAmount.getInstance().get(order); + } +} diff --git a/src/me/smartstore/menu/summary/SummaryDefaultMenu.java b/src/me/smartstore/menu/summary/SummaryDefaultMenu.java new file mode 100644 index 00000000..b5453789 --- /dev/null +++ b/src/me/smartstore/menu/summary/SummaryDefaultMenu.java @@ -0,0 +1,22 @@ +package me.smartstore.menu.summary; + +import me.smartstore.summary.Summary; +import me.smartstore.menu.Menu; + +public class SummaryDefaultMenu extends Menu { + + private static class InstanceHolder { + private static final SummaryDefaultMenu INSTANCE = new SummaryDefaultMenu(); + } + private SummaryDefaultMenu() {} + public static SummaryDefaultMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + print(Summary.get()); + return getPrevMenu(); + } + + @Override + protected void setNextMenus() {} +} diff --git a/src/me/smartstore/menu/summary/SummaryMenu.java b/src/me/smartstore/menu/summary/SummaryMenu.java new file mode 100644 index 00000000..968decf1 --- /dev/null +++ b/src/me/smartstore/menu/summary/SummaryMenu.java @@ -0,0 +1,38 @@ +package me.smartstore.menu.summary; + +import me.smartstore.summary.Order; +import me.smartstore.menu.Menu; +import me.smartstore.menu.exception.InputIsEndException; + +import java.util.InputMismatchException; + +import static me.smartstore.summary.Order.getOrderByName; + +public abstract class SummaryMenu extends Menu { + private static final String ORDER_INPUT = + "Which order (ASCENDING (A), DESCENDING (D))?\n" + + END_INPUT; + + @Override + public Menu printAndInputAndGetNextMenu() { + while (true) { + print(ORDER_INPUT); + try { + String orderName = inputStringOrEnd(); + Order order = getOrderByName(orderName); + print(getSummary(order)); + return getPrevMenu(); + } catch (InputIsEndException e) { + print(e.getMessage()); + return getPrevMenu(); + } catch (InputMismatchException e) { + print(e.getMessage()); + } + } + } + + @Override + protected void setNextMenus() {} + + protected abstract String getSummary(Order order); +} diff --git a/src/me/smartstore/menu/topic/AddCustomerMenu.java b/src/me/smartstore/menu/topic/AddCustomerMenu.java new file mode 100644 index 00000000..5d24a474 --- /dev/null +++ b/src/me/smartstore/menu/topic/AddCustomerMenu.java @@ -0,0 +1,59 @@ +package me.smartstore.menu.topic; + +import me.smartstore.customer.CustomerRepository; +import me.smartstore.customer.exception.MaxCapacityReachedException; +import me.smartstore.menu.Menu; +import me.smartstore.menu.customer.*; + +public class AddCustomerMenu extends TopicIntroMenu { + + private static final String ADD_CUSTOMER_MENU_OUTPUT = + '\n' + + "======= " + "Customer " + "Info. =======" + '\n' + + " 1. " + "Customer " + "ID" + '\n' + + " 2. " + "Customer " + "Name" + '\n' + + " 3. " + "Customer " + "Spent Hours" + '\n' + + " 4. " + "Customer " + "Total Amount Paid" + '\n' + + " 5. " + "Confirm" + '\n' + + " 6. " + "Cancel(Back)" + '\n' + + "==============================" + '\n' + + "Choose One: "; + + private static class InstanceHolder { + private static final AddCustomerMenu INSTANCE = new AddCustomerMenu(); + } + + private AddCustomerMenu() { super(ADD_CUSTOMER_MENU_OUTPUT); } + + public static AddCustomerMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + public Menu printAndInputAndGetNextMenu() { + CustomerRepository repository = CustomerRepository.getInstance(); + setNextMenus(); + try { + repository.checkIfReachedMaxCapacity(); + } catch (MaxCapacityReachedException e) { + print(e.getMessage()); + return getBackMenu(); + } + if (getPrevMenu() == CustomerIntroMenu.getInstance()) + repository.resetTempCustomer(); + return inputMenuAndMoveToNextMenu(); + } + + @Override + protected void setNextMenus() { + Menu[] nextMenus = { + InputCustomerIdMenu.getInstance(), // id + InputCustomerNameMenu.getInstance(), // name + InputCustomerSpentHoursMenu.getInstance(), // spent hours + InputCustomerTotalPaidAmountMenu.getInstance(), // total amount paid + AddCustomerConfirmMenu.getInstance(), // confirm + CustomerIntroMenu.getInstance() // cancel(back) => CustomerMenu + }; + for (int i = 0; i <= 3; ++i) + nextMenus[i].setNextMenus(null, this); + setNextMenus(nextMenus); + } +} diff --git a/src/me/smartstore/menu/topic/CustomerIntroMenu.java b/src/me/smartstore/menu/topic/CustomerIntroMenu.java new file mode 100644 index 00000000..ba09ebb5 --- /dev/null +++ b/src/me/smartstore/menu/topic/CustomerIntroMenu.java @@ -0,0 +1,35 @@ +package me.smartstore.menu.topic; + +import me.smartstore.menu.customer.DeleteCustomerMenu; +import me.smartstore.menu.customer.UpdateCustomerMenu; +import me.smartstore.menu.customer.ViewCustomerMenu; + +public class CustomerIntroMenu extends TopicIntroMenu { + + private static final String CUSTOMER_MENU_OUTPUT = + '\n' + + "======= " + "Customer" + " Menu ========\n" + + " 1. " + "Add " + "Customer" + '\n' + + " 2. " + "View " + "Customer" + '\n' + + " 3. " + "Update " + "Customer" + '\n' + + " 4. " + "Delete " + "Customer" + '\n' + + " 5. " + "Back" + '\n' + + "==============================\n" + + "Choose One: "; + private static final CustomerIntroMenu INSTANCE = new CustomerIntroMenu(); + + private CustomerIntroMenu() { super(CUSTOMER_MENU_OUTPUT); } + + public static CustomerIntroMenu getInstance() { return INSTANCE; } + + @Override + protected void setNextMenus() { + setNextMenus( + AddCustomerMenu.getInstance(), + ViewCustomerMenu.getInstance(), + UpdateCustomerMenu.getInstance(), + DeleteCustomerMenu.getInstance(), + StartMenu.getInstance() + ); + } +} diff --git a/src/me/smartstore/menu/topic/GroupIntroMenu.java b/src/me/smartstore/menu/topic/GroupIntroMenu.java new file mode 100644 index 00000000..4563e19a --- /dev/null +++ b/src/me/smartstore/menu/topic/GroupIntroMenu.java @@ -0,0 +1,30 @@ +package me.smartstore.menu.topic; + +import me.smartstore.menu.group.UpdateParameterMenu; +import me.smartstore.menu.group.ViewParameterMenu; + +public class GroupIntroMenu extends TopicIntroMenu { + + private static final String GROUP_MENU_OUTPUT = + '\n' + + "========= Group Menu =========" + '\n' + + "1. " + "Update " + "Parameter" + '\n' + + "2. " + "View " + "Parameter" + '\n' + + "3. " + "Back" + '\n' + + "==============================" + '\n' + + "Choose One: "; + private static final GroupIntroMenu INSTANCE = new GroupIntroMenu(); + + private GroupIntroMenu() { super(GROUP_MENU_OUTPUT); } + + public static GroupIntroMenu getInstance() { return INSTANCE; } + + @Override + protected void setNextMenus() { + setNextMenus( + UpdateParameterMenu.getInstance(), // 1 + ViewParameterMenu.getInstance(), // 2 + StartMenu.getInstance() // 3 + ); + } +} diff --git a/src/me/smartstore/menu/topic/StartMenu.java b/src/me/smartstore/menu/topic/StartMenu.java new file mode 100644 index 00000000..9aff9d9f --- /dev/null +++ b/src/me/smartstore/menu/topic/StartMenu.java @@ -0,0 +1,32 @@ +package me.smartstore.menu.topic; + +import me.smartstore.menu.QuitMenu; + +public class StartMenu extends TopicIntroMenu { + + private static final String OUTPUT = + '\n' + + "========= Start Menu =========" + '\n' + + "1. " + "Group" + '\n' + + "2. " + "Customer" + '\n' + + "3. " + "Classification" + '\n' + + "4. " + "Quit" + '\n' + + "==============================" + '\n' + + "Choose One: "; + + private static final StartMenu INSTANCE = new StartMenu(); + + private StartMenu() { super(OUTPUT); } + + public static StartMenu getInstance() { return INSTANCE; } + + @Override + protected void setNextMenus() { + setNextMenus( + GroupIntroMenu.getInstance(), // 1 + CustomerIntroMenu.getInstance(), // 2 + SummaryIntroMenu.getInstance(), // 3 + QuitMenu.getInstance() // 4 + ); + } +} diff --git a/src/me/smartstore/menu/topic/SummaryIntroMenu.java b/src/me/smartstore/menu/topic/SummaryIntroMenu.java new file mode 100644 index 00000000..1d6d0e32 --- /dev/null +++ b/src/me/smartstore/menu/topic/SummaryIntroMenu.java @@ -0,0 +1,33 @@ +package me.smartstore.menu.topic; + +import me.smartstore.menu.summary.*; + +public class SummaryIntroMenu extends TopicIntroMenu { + + private static final String SUMMARY_MENU_OUTPUT = + '\n' + + "========= Summary Menu =======" + '\n' + + " 1. " + "Summary " + '\n' + + " 2. " + "Summary " + "(Sorted By " + "Name" + ")\n" + + " 3. " + "Summary " + "(Sorted By " + "Spent Hours" + ")\n" + + " 4. " + "Summary " + "(Sorted By " + "Total Paid Amount" + ")\n" + + " 5. " + "Back" + '\n' + + "==============================" + '\n' + + "Choose One: "; + private static final SummaryIntroMenu INSTANCE = new SummaryIntroMenu(); + + private SummaryIntroMenu() { super(SUMMARY_MENU_OUTPUT); } + + public static SummaryIntroMenu getInstance() { return INSTANCE; } + + @Override + protected void setNextMenus() { + setNextMenus( + SummaryDefaultMenu.getInstance(), + SummaryByNameMenu.getInstance(), + SummaryBySpentHoursMenu.getInstance(), + SummaryByTotalPaidAmountMenu.getInstance(), + StartMenu.getInstance() + ); + } +} diff --git a/src/me/smartstore/menu/topic/TopicIntroMenu.java b/src/me/smartstore/menu/topic/TopicIntroMenu.java new file mode 100644 index 00000000..02f2a264 --- /dev/null +++ b/src/me/smartstore/menu/topic/TopicIntroMenu.java @@ -0,0 +1,30 @@ +package me.smartstore.menu.topic; + +import me.smartstore.menu.Menu; + +import java.util.InputMismatchException; + +public abstract class TopicIntroMenu extends Menu { + + private final String TOPIC_OUTPUT; + + TopicIntroMenu(String TOPIC_OUTPUT) { this.TOPIC_OUTPUT = TOPIC_OUTPUT; } + + @Override + public Menu printAndInputAndGetNextMenu() { + setNextMenus(); + return inputMenuAndMoveToNextMenu(); + } + + protected Menu inputMenuAndMoveToNextMenu() { + while (true) { + try { + print(TOPIC_OUTPUT); + int menuIdx = inputMenuIdx(); + return getNextMenu(menuIdx); + } catch (InputMismatchException e) { + print(e.getMessage()); + } + } + } +} diff --git a/src/me/smartstore/menu/topic/UpdateCustomerSelectPropertyMenu.java b/src/me/smartstore/menu/topic/UpdateCustomerSelectPropertyMenu.java new file mode 100644 index 00000000..a03e8aea --- /dev/null +++ b/src/me/smartstore/menu/topic/UpdateCustomerSelectPropertyMenu.java @@ -0,0 +1,40 @@ +package me.smartstore.menu.topic; + +import me.smartstore.menu.Menu; +import me.smartstore.menu.customer.*; + +public class UpdateCustomerSelectPropertyMenu extends TopicIntroMenu { + + private static final String CUSTOMER_PROPERTY_MENU_OUTPUT = + '\n' + + "===== Property to update =====" + '\n' + + " 1. " + "Customer " + "Name" + '\n' + + " 2. " + "Customer " + "Spent Hours" + '\n' + + " 3. " + "Customer " + "Total Paid Amount" + '\n' + + " 4. " + "Confirm" + '\n' + + " 5. " + "Cancel(Back)" + '\n' + + "==============================" + '\n' + + "Choose One: "; + + private static class InstanceHolder { + private static final UpdateCustomerSelectPropertyMenu INSTANCE = new UpdateCustomerSelectPropertyMenu(); + } + + private UpdateCustomerSelectPropertyMenu() { super(CUSTOMER_PROPERTY_MENU_OUTPUT); } + + public static UpdateCustomerSelectPropertyMenu getInstance() { return InstanceHolder.INSTANCE; } + + @Override + protected void setNextMenus() { + Menu[] nextMenus = { + InputCustomerNameMenu.getInstance(), // name + InputCustomerSpentHoursMenu.getInstance(), // spent hours + InputCustomerTotalPaidAmountMenu.getInstance(), // total paid amount + UpdateCustomerConfirmMenu.getInstance(), // confirm + CustomerIntroMenu.getInstance() // cancel(back) => CustomerMenu + }; + for (int i = 0; i <= 2; ++i) + nextMenus[i].setNextMenus(null, this); + setNextMenus(nextMenus); + } +} diff --git a/src/me/smartstore/summary/Order.java b/src/me/smartstore/summary/Order.java new file mode 100644 index 00000000..1fee07d1 --- /dev/null +++ b/src/me/smartstore/summary/Order.java @@ -0,0 +1,34 @@ +package me.smartstore.summary; + +import me.smartstore.customer.Customer; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.InputMismatchException; + +public enum Order { + + ASCENDING("A"), DESCENDING("D"); + + private final String shortcut; + + Order(String shortcut) { this.shortcut = shortcut; } + + public static final Comparator ORDER_BY_NAME_ASC = Comparator.comparing(Customer::getName); + public static final Comparator ORDER_BY_NAME_DEC = ORDER_BY_NAME_ASC.reversed(); + public static final Comparator ORDER_BY_SPENT_HOURS_ASC = Comparator.comparing(Customer::getSpentHours); + public static final Comparator ORDER_BY_SPENT_HOURS_DEC = ORDER_BY_SPENT_HOURS_ASC.reversed(); + public static final Comparator ORDER_BY_TOTAL_PAID_AMOUNT_ASC = Comparator.comparing(Customer::getTotalPaidAmount); + public static final Comparator ORDER_BY_TOTAL_PAID_AMOUNT_DEC = ORDER_BY_TOTAL_PAID_AMOUNT_ASC.reversed(); + + public static Order getOrderByName(String name) throws InputMismatchException { + return Arrays.stream(values()) + .filter(order -> order.isName(name)) + .findFirst() + .orElseThrow(() -> new InputMismatchException("Invalid Order name for input. Please try again.\n")); + } + + private boolean isName(String name) { + return shortcut.equalsIgnoreCase(name) || name().equalsIgnoreCase(name); + } +} diff --git a/src/me/smartstore/summary/SortedSummaryTemplate.java b/src/me/smartstore/summary/SortedSummaryTemplate.java new file mode 100644 index 00000000..6554f169 --- /dev/null +++ b/src/me/smartstore/summary/SortedSummaryTemplate.java @@ -0,0 +1,17 @@ +package me.smartstore.summary; + +import me.smartstore.customer.Customer; + +import java.util.Comparator; + +public abstract class SortedSummaryTemplate extends Summary { + + @Override + public String get(Order order) { + Comparator cmp = getComparator(order); + repository.sort(cmp); + return getSummary(); + } + + protected abstract Comparator getComparator(Order order); +} diff --git a/src/me/smartstore/summary/Summary.java b/src/me/smartstore/summary/Summary.java new file mode 100644 index 00000000..352ed1f4 --- /dev/null +++ b/src/me/smartstore/summary/Summary.java @@ -0,0 +1,47 @@ +package me.smartstore.summary; + +import me.smartstore.customer.Customer; +import me.smartstore.customer.CustomerRepository; +import me.smartstore.group.Group; + +public abstract class Summary { + + protected static CustomerRepository repository = CustomerRepository.getInstance(); + + public static String get() { return getSummary(); } + + public abstract String get(Order order); + + protected static String getSummary() { + Group[] groups = Group.values(); + int len = groups.length; + StringBuilder[] stringBuilders = new StringBuilder[len]; + for (int i = 0; i < len; ++i) { + StringBuilder sb = new StringBuilder(); + sb.append('\n').append("==============================") + .append(groups[i]) + .append("==============================").append('\n'); + stringBuilders[i] = sb; + } + + int[] cnt = new int[len]; + for (Customer customer : repository) { + Group group = customer.getGroup(); + for (int i = 0; i < len; ++i) { + if (group == groups[i]) { + stringBuilders[i].append(customer).append('\n'); + cnt[i]++; + break; + } + } + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < len; ++i) { + sb.append(stringBuilders[i]); + if (cnt[i] == 0) + sb.append("No Customers.").append('\n'); + } + return sb.append('\n').toString(); + } +} diff --git a/src/me/smartstore/summary/SummaryByName.java b/src/me/smartstore/summary/SummaryByName.java new file mode 100644 index 00000000..541ad56e --- /dev/null +++ b/src/me/smartstore/summary/SummaryByName.java @@ -0,0 +1,19 @@ +package me.smartstore.summary; + +import me.smartstore.customer.Customer; + +import java.util.Comparator; + +public class SummaryByName extends SortedSummaryTemplate { + + private static class InstanceHolder { + private static final SummaryByName INSTANCE = new SummaryByName(); + } + public static SummaryByName getInstance() { return InstanceHolder.INSTANCE; } + private SummaryByName() {} + + protected Comparator getComparator(Order order) { + return (order == Order.ASCENDING) ? Order.ORDER_BY_NAME_ASC + : Order.ORDER_BY_NAME_DEC; + } +} diff --git a/src/me/smartstore/summary/SummaryBySpentHours.java b/src/me/smartstore/summary/SummaryBySpentHours.java new file mode 100644 index 00000000..9c8d4339 --- /dev/null +++ b/src/me/smartstore/summary/SummaryBySpentHours.java @@ -0,0 +1,19 @@ +package me.smartstore.summary; + +import me.smartstore.customer.Customer; + +import java.util.Comparator; + +public class SummaryBySpentHours extends SortedSummaryTemplate { + + private static class InstanceHolder { + private static final SummaryBySpentHours INSTANCE = new SummaryBySpentHours(); + } + public static SummaryBySpentHours getInstance() { return InstanceHolder.INSTANCE; } + private SummaryBySpentHours() {} + + protected Comparator getComparator(Order order) { + return (order == Order.ASCENDING) ? Order.ORDER_BY_SPENT_HOURS_ASC + : Order.ORDER_BY_SPENT_HOURS_DEC; + } +} diff --git a/src/me/smartstore/summary/SummaryByTotalPaidAmount.java b/src/me/smartstore/summary/SummaryByTotalPaidAmount.java new file mode 100644 index 00000000..d0f8b0d6 --- /dev/null +++ b/src/me/smartstore/summary/SummaryByTotalPaidAmount.java @@ -0,0 +1,19 @@ +package me.smartstore.summary; + +import me.smartstore.customer.Customer; + +import java.util.Comparator; + +public class SummaryByTotalPaidAmount extends SortedSummaryTemplate { + + private static class InstanceHolder { + private static final SummaryByTotalPaidAmount INSTANCE = new SummaryByTotalPaidAmount(); + } + public static SummaryByTotalPaidAmount getInstance() { return InstanceHolder.INSTANCE; } + private SummaryByTotalPaidAmount() {} + + protected Comparator getComparator(Order order) { + return (order == Order.ASCENDING) ? Order.ORDER_BY_TOTAL_PAID_AMOUNT_ASC + : Order.ORDER_BY_TOTAL_PAID_AMOUNT_DEC; + } +} diff --git a/src/me/smartstore/use_merge_squash b/src/me/smartstore/use_merge_squash new file mode 100644 index 00000000..5dfc25bf --- /dev/null +++ b/src/me/smartstore/use_merge_squash @@ -0,0 +1 @@ +use `merge --squash` from now on