diff options
Diffstat (limited to 'ui-console/src/main/java/market/guess/ui')
8 files changed, 107 insertions, 47 deletions
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/EventDetailsMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/EventDetailsMenuCommand.java index 2ad7a53..bdd3eb1 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/EventDetailsMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/EventDetailsMenuCommand.java | |||
| @@ -29,7 +29,7 @@ public final class EventDetailsMenuCommand implements MenuCommand { | |||
| 29 | var result = catalog.getAllEvents(); | 29 | var result = catalog.getAllEvents(); |
| 30 | 30 | ||
| 31 | if (!result.isSuccess()) { | 31 | if (!result.isSuccess()) { |
| 32 | io.println("Failed to list events"); | 32 | io.println("Failed to list events: %s.".formatted(result.getMessage())); |
| 33 | return; | 33 | return; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| @@ -37,11 +37,17 @@ public final class EventDetailsMenuCommand implements MenuCommand { | |||
| 37 | var viewable = events.stream().filter(event -> event.status() != EventStatus.DRAFT).toList(); | 37 | var viewable = events.stream().filter(event -> event.status() != EventStatus.DRAFT).toList(); |
| 38 | 38 | ||
| 39 | if (viewable.isEmpty()) { | 39 | if (viewable.isEmpty()) { |
| 40 | io.println("There are currently no events to show."); | 40 | io.println("No events are currently loaded. Please load a valid XML file first."); |
| 41 | return; | 41 | return; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | var pick = io.readSelect("Pick an event: ", viewable, event -> "%s".formatted(event.name())); | 44 | io.newLine(); |
| 45 | io.println("Available events:"); | ||
| 46 | var pick = | ||
| 47 | io.readSelect( | ||
| 48 | "Pick an event: ", | ||
| 49 | viewable, | ||
| 50 | event -> "[ID: %d] %s (%s)".formatted(event.displayId(), event.name(), event.status())); | ||
| 45 | 51 | ||
| 46 | var result2 = catalog.getEvent(pick.key()); | 52 | var result2 = catalog.getEvent(pick.key()); |
| 47 | var event = result2.getData(); | 53 | var event = result2.getData(); |
| @@ -50,11 +56,26 @@ public final class EventDetailsMenuCommand implements MenuCommand { | |||
| 50 | return; | 56 | return; |
| 51 | } | 57 | } |
| 52 | 58 | ||
| 59 | io.newLine(); | ||
| 60 | io.println("=== Event Details ==="); | ||
| 61 | io.println("Event ID: %d".formatted(event.summary().displayId())); | ||
| 62 | io.println("Name: %s".formatted(event.summary().name())); | ||
| 63 | io.println("Description: %s".formatted(event.summary().description())); | ||
| 64 | io.println( | ||
| 65 | "Commission: %d%% (%s)" | ||
| 66 | .formatted( | ||
| 67 | event.summary().commissionPercent(), | ||
| 68 | event.summary().commissionTiming() == market.guess.api.CommissionTiming.ON_CLOSE | ||
| 69 | ? "on-close" | ||
| 70 | : "on-purchase")); | ||
| 71 | io.println("Status: %s".formatted(event.summary().status())); | ||
| 72 | |||
| 53 | io.printState(event.state()); | 73 | io.printState(event.state()); |
| 54 | io.printHistory(event.history()); | 74 | io.printHistory(event.history()); |
| 55 | 75 | ||
| 56 | if (!event.settledMarket().isBlank()) { | 76 | if (event.settledMarket() != null && !event.settledMarket().isBlank()) { |
| 57 | io.println("Winning market: %s".formatted(event.settledMarket())); | 77 | io.newLine(); |
| 78 | io.println("Winning option: %s".formatted(event.settledMarket())); | ||
| 58 | } | 79 | } |
| 59 | } | 80 | } |
| 60 | } | 81 | } |
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/ListEventsMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/ListEventsMenuCommand.java index 755bf37..01e93bd 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/ListEventsMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/ListEventsMenuCommand.java | |||
| @@ -29,24 +29,29 @@ public final class ListEventsMenuCommand implements MenuCommand { | |||
| 29 | var result = catalog.getAllEvents(); | 29 | var result = catalog.getAllEvents(); |
| 30 | 30 | ||
| 31 | if (!result.isSuccess()) { | 31 | if (!result.isSuccess()) { |
| 32 | io.println("Failed to list events due to %s.".formatted(result.getMessage())); | 32 | io.println("Failed to list events: %s.".formatted(result.getMessage())); |
| 33 | return; | 33 | return; |
| 34 | } | 34 | } |
| 35 | var events = result.getData(); | 35 | var events = result.getData(); |
| 36 | 36 | ||
| 37 | if (events.isEmpty()) { | ||
| 38 | io.println("No events are currently loaded. Please load a valid XML file first."); | ||
| 39 | return; | ||
| 40 | } | ||
| 41 | |||
| 37 | for (var event : events) { | 42 | for (var event : events) { |
| 38 | io.newLine(); | 43 | io.newLine(); |
| 39 | io.println(" %s".formatted(event.name())); | 44 | io.println(" [%d] %s (ID: %d)".formatted(event.displayId(), event.name(), event.displayId())); |
| 40 | io.println(" %s".formatted(event.description())); | 45 | io.println(" Description: %s".formatted(event.description())); |
| 41 | io.println( | 46 | io.println( |
| 42 | " Commission: %d%% (%s)" | 47 | " Commission: %d%% (%s)" |
| 43 | .formatted(event.commissionPercent(), timing(event.commissionTiming()))); | 48 | .formatted(event.commissionPercent(), timing(event.commissionTiming()))); |
| 44 | io.println(" Options: " + String.join(" | ", event.optionNames())); | 49 | io.println(" Options: " + String.join(" | ", event.optionNames())); |
| 45 | io.println(" Status: " + event.status()); | 50 | io.println(" Status: " + event.status()); |
| 46 | } | 51 | } |
| 47 | } | 52 | } |
| 48 | 53 | ||
| 49 | private static String timing(CommissionTiming timing) { | 54 | private static String timing(CommissionTiming timing) { |
| 50 | return timing == CommissionTiming.ON_CLOSE ? "charged on close" : "charged on purchase"; | 55 | return timing == CommissionTiming.ON_CLOSE ? "on-close" : "on-purchase"; |
| 51 | } | 56 | } |
| 52 | } | 57 | } |
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java index c5b3c77..c36df90 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java | |||
| @@ -24,16 +24,20 @@ public final class LoadFileMenuCommand implements MenuCommand { | |||
| 24 | 24 | ||
| 25 | @Override | 25 | @Override |
| 26 | public void execute() { | 26 | public void execute() { |
| 27 | var path = io.readPath("Pleae enter the full file path to the XML file: "); | 27 | var path = io.readPath("Please enter the full file path to the XML file: "); |
| 28 | var result = catalog.loadEvents(path); | 28 | var result = catalog.loadEvents(path); |
| 29 | 29 | ||
| 30 | if (result.isSuccess()) { | 30 | if (result.isSuccess()) { |
| 31 | io.println( | 31 | io.println( |
| 32 | "Loaded %d event(s) from %s." | 32 | "Successfully loaded %d event(s) from %s." |
| 33 | .formatted(result.getData().eventsLoaded(), result.getData().source())); | 33 | .formatted(result.getData().eventsLoaded(), result.getData().source())); |
| 34 | return; | 34 | return; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | io.println("The file was not loaded, %s ".formatted(result.getDetails())); | 37 | var errorMsg = |
| 38 | result.getDetails() != null && !result.getDetails().isBlank() | ||
| 39 | ? result.getDetails() | ||
| 40 | : result.getMessage(); | ||
| 41 | io.println("The file was not loaded: %s".formatted(errorMsg)); | ||
| 38 | } | 42 | } |
| 39 | } | 43 | } |
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java index 30acef3..8fa77c2 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/LoadMarketStateMenuCommand.java | |||
| @@ -25,11 +25,17 @@ public final class LoadMarketStateMenuCommand implements MenuCommand { | |||
| 25 | 25 | ||
| 26 | @Override | 26 | @Override |
| 27 | public void execute() { | 27 | public void execute() { |
| 28 | var path = io.readPath("Which state file to load? "); | 28 | var path = io.readPath("Please enter full path to state file (without or with .json extension): "); |
| 29 | var result = catalog.restoreState(path); | 29 | var result = catalog.restoreState(path); |
| 30 | 30 | ||
| 31 | if (result.isSuccess()) { | 31 | if (result.isSuccess()) { |
| 32 | io.println("Restored %d event(s) from %s.".formatted(result.getData().eventsLoaded(), path)); | 32 | io.println("Successfully restored %d event(s) from %s.".formatted(result.getData().eventsLoaded(), path)); |
| 33 | } else { | ||
| 34 | var msg = | ||
| 35 | result.getDetails() != null && !result.getDetails().isBlank() | ||
| 36 | ? result.getDetails() | ||
| 37 | : result.getMessage(); | ||
| 38 | io.println("Failed to restore state: %s".formatted(msg)); | ||
| 33 | } | 39 | } |
| 34 | } | 40 | } |
| 35 | } | 41 | } |
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/PlaceOrderMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/PlaceOrderMenuCommand.java index a03f757..0d58b1d 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/PlaceOrderMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/PlaceOrderMenuCommand.java | |||
| @@ -34,11 +34,16 @@ public final class PlaceOrderMenuCommand implements MenuCommand { | |||
| 34 | var result = catalog.getAllEvents(); | 34 | var result = catalog.getAllEvents(); |
| 35 | 35 | ||
| 36 | if (!result.isSuccess()) { | 36 | if (!result.isSuccess()) { |
| 37 | io.println("Failed to list events"); | 37 | io.println("Failed to list events: %s.".formatted(result.getMessage())); |
| 38 | return; | 38 | return; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | var events = result.getData(); | 41 | var events = result.getData(); |
| 42 | if (events.isEmpty()) { | ||
| 43 | io.println("No events are currently loaded. Please load a valid XML file first."); | ||
| 44 | return; | ||
| 45 | } | ||
| 46 | |||
| 42 | var active = events.stream().filter(event -> event.status() == EventStatus.ACTIVE).toList(); | 47 | var active = events.stream().filter(event -> event.status() == EventStatus.ACTIVE).toList(); |
| 43 | 48 | ||
| 44 | if (active.isEmpty()) { | 49 | if (active.isEmpty()) { |
| @@ -46,7 +51,9 @@ public final class PlaceOrderMenuCommand implements MenuCommand { | |||
| 46 | return; | 51 | return; |
| 47 | } | 52 | } |
| 48 | 53 | ||
| 49 | var pick = io.readSelect("Pick an event: ", active, event -> "%s".formatted(event.name())); | 54 | io.newLine(); |
| 55 | io.println("Active events:"); | ||
| 56 | var pick = io.readSelect("Pick an active event: ", active, event -> "[ID: %d] %s".formatted(event.displayId(), event.name())); | ||
| 50 | 57 | ||
| 51 | var result2 = catalog.getEvent(pick.key()); | 58 | var result2 = catalog.getEvent(pick.key()); |
| 52 | var event = result2.getData(); | 59 | var event = result2.getData(); |
| @@ -59,11 +66,11 @@ public final class PlaceOrderMenuCommand implements MenuCommand { | |||
| 59 | 66 | ||
| 60 | var market = | 67 | var market = |
| 61 | io.readSelect( | 68 | io.readSelect( |
| 62 | "Choose a market: ", | 69 | "Choose an option to buy: ", |
| 63 | event.state().markets(), | 70 | event.state().markets(), |
| 64 | o -> "%s [value %s, %s shares helds]".formatted(o.name(), o.price(), o.volume())); | 71 | o -> "%s [current value: %s, %s shares purchased]".formatted(o.name(), o.price(), o.volume())); |
| 65 | 72 | ||
| 66 | var amount = io.readInt("How many shares? ", 1, Integer.MAX_VALUE); | 73 | var amount = io.readInt("How many shares would you like to buy? ", 1, Integer.MAX_VALUE); |
| 67 | 74 | ||
| 68 | var buyResult = | 75 | var buyResult = |
| 69 | context.placeOrder( | 76 | context.placeOrder( |
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java index 3c5d6b9..78a5ca0 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/SaveMarketStateMenuCommand.java | |||
| @@ -25,13 +25,17 @@ public final class SaveMarketStateMenuCommand implements MenuCommand { | |||
| 25 | 25 | ||
| 26 | @Override | 26 | @Override |
| 27 | public void execute() { | 27 | public void execute() { |
| 28 | var path = io.readPath("Save to: "); | 28 | var path = io.readPath("Please enter full path to save file (without or with .json extension): "); |
| 29 | 29 | ||
| 30 | try { | 30 | var result = catalog.saveState(path); |
| 31 | catalog.saveState(path); | 31 | if (result.isSuccess()) { |
| 32 | io.println("Saved current state to %s.".formatted(path)); | 32 | io.println("Successfully saved current market state to %s.".formatted(path)); |
| 33 | } catch (Exception e) { | 33 | } else { |
| 34 | io.println("Failed to save: %s".formatted(e.getMessage())); | 34 | var msg = |
| 35 | result.getDetails() != null && !result.getDetails().isBlank() | ||
| 36 | ? result.getDetails() | ||
| 37 | : result.getMessage(); | ||
| 38 | io.println("Failed to save state: %s".formatted(msg)); | ||
| 35 | } | 39 | } |
| 36 | } | 40 | } |
| 37 | } | 41 | } |
diff --git a/ui-console/src/main/java/market/guess/ui/console/command/SettleEventMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/SettleEventMenuCommand.java index 3457e08..bec25a7 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/SettleEventMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/SettleEventMenuCommand.java | |||
| @@ -32,11 +32,16 @@ public final class SettleEventMenuCommand implements MenuCommand { | |||
| 32 | var result = catalog.getAllEvents(); | 32 | var result = catalog.getAllEvents(); |
| 33 | 33 | ||
| 34 | if (!result.isSuccess()) { | 34 | if (!result.isSuccess()) { |
| 35 | io.println("Failed to list events"); | 35 | io.println("Failed to list events: %s.".formatted(result.getMessage())); |
| 36 | return; | 36 | return; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | var events = result.getData(); | 39 | var events = result.getData(); |
| 40 | if (events.isEmpty()) { | ||
| 41 | io.println("No events are currently loaded. Please load a valid XML file first."); | ||
| 42 | return; | ||
| 43 | } | ||
| 44 | |||
| 40 | var active = events.stream().filter(event -> event.status() == EventStatus.ACTIVE).toList(); | 45 | var active = events.stream().filter(event -> event.status() == EventStatus.ACTIVE).toList(); |
| 41 | 46 | ||
| 42 | if (active.isEmpty()) { | 47 | if (active.isEmpty()) { |
| @@ -44,7 +49,9 @@ public final class SettleEventMenuCommand implements MenuCommand { | |||
| 44 | return; | 49 | return; |
| 45 | } | 50 | } |
| 46 | 51 | ||
| 47 | var pick = io.readSelect("Pick an event: ", active, event -> "%s".formatted(event.name())); | 52 | io.newLine(); |
| 53 | io.println("Active events to settle:"); | ||
| 54 | var pick = io.readSelect("Pick an event to settle: ", active, event -> "[ID: %d] %s".formatted(event.displayId(), event.name())); | ||
| 48 | 55 | ||
| 49 | var result2 = catalog.getEvent(pick.key()); | 56 | var result2 = catalog.getEvent(pick.key()); |
| 50 | var event = result2.getData(); | 57 | var event = result2.getData(); |
| @@ -56,12 +63,17 @@ public final class SettleEventMenuCommand implements MenuCommand { | |||
| 56 | io.printState(event.state()); | 63 | io.printState(event.state()); |
| 57 | 64 | ||
| 58 | var winner = | 65 | var winner = |
| 59 | io.readSelect("Which market won? ", event.state().markets(), o -> "%s".formatted(o.name())); | 66 | io.readSelect("Which option won? ", event.state().markets(), o -> "%s".formatted(o.name())); |
| 60 | 67 | ||
| 61 | var settleResult = context.settleEvent("Tester", event.summary().key(), winner.key()); | 68 | var settleResult = context.settleEvent("Tester", event.summary().key(), winner.key()); |
| 62 | if (settleResult.isSuccess()) { | 69 | if (settleResult.isSuccess()) { |
| 70 | var settledEvent = settleResult.getData(); | ||
| 71 | io.newLine(); | ||
| 72 | io.println("Event closed successfully! Winning option: %s".formatted(settledEvent.settledMarket())); | ||
| 73 | io.printState(settledEvent.state()); | ||
| 74 | io.printHistory(settledEvent.history()); | ||
| 63 | io.newLine(); | 75 | io.newLine(); |
| 64 | io.println("Settled. Winning market: %s".formatted(settleResult.getData().settledMarket())); | 76 | io.println("Winning option: %s".formatted(settledEvent.settledMarket())); |
| 65 | return; | 77 | return; |
| 66 | } | 78 | } |
| 67 | io.newLine(); | 79 | io.newLine(); |
diff --git a/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java b/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java index 721cf8b..3ff752c 100644 --- a/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java +++ b/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java | |||
| @@ -20,20 +20,20 @@ public final class InputProcessor { | |||
| 20 | private final Scanner scanner = new Scanner(System.in); | 20 | private final Scanner scanner = new Scanner(System.in); |
| 21 | 21 | ||
| 22 | public void print(Object object) { | 22 | public void print(Object object) { |
| 23 | IO.print(object); | 23 | System.out.print(object); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | public void println(Object object) { | 26 | public void println(Object object) { |
| 27 | IO.println(object); | 27 | System.out.println(object); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | public void newLine() { | 30 | public void newLine() { |
| 31 | IO.println(""); | 31 | System.out.println(""); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | public void splashScreen() { | 34 | public void splashScreen() { |
| 35 | newLine(); | 35 | newLine(); |
| 36 | IO.println(padLeft("<<- GUESS MARKET ->>", 36)); | 36 | System.out.println(padLeft("<<- GUESS MARKET ->>", 36)); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | public void printState(MarketStateDTO state) { | 39 | public void printState(MarketStateDTO state) { |
| @@ -68,7 +68,8 @@ public final class InputProcessor { | |||
| 68 | 68 | ||
| 69 | public String readLine(String prompt) { | 69 | public String readLine(String prompt) { |
| 70 | print(prompt); | 70 | print(prompt); |
| 71 | return nextLine().trim(); | 71 | var line = nextLine(); |
| 72 | return line != null ? line.trim() : ""; | ||
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | public int readInt(String prompt, int min, int max) { | 75 | public int readInt(String prompt, int min, int max) { |
| @@ -80,7 +81,6 @@ public final class InputProcessor { | |||
| 80 | } | 81 | } |
| 81 | try { | 82 | try { |
| 82 | var value = Integer.parseInt(raw); | 83 | var value = Integer.parseInt(raw); |
| 83 | |||
| 84 | if (value > max || value < min) { | 84 | if (value > max || value < min) { |
| 85 | println( | 85 | println( |
| 86 | "%d is out of range, please enter a number between %d and %d." | 86 | "%d is out of range, please enter a number between %d and %d." |
| @@ -90,9 +90,8 @@ public final class InputProcessor { | |||
| 90 | return value; | 90 | return value; |
| 91 | } catch (NumberFormatException e) { | 91 | } catch (NumberFormatException e) { |
| 92 | println( | 92 | println( |
| 93 | "%s in not a number, please enter a number between %d and %d." | 93 | "'%s' is not a valid number, please enter a number between %d and %d." |
| 94 | .formatted(raw, min, max)); | 94 | .formatted(raw, min, max)); |
| 95 | continue; | ||
| 96 | } | 95 | } |
| 97 | } | 96 | } |
| 98 | } | 97 | } |
| @@ -100,12 +99,10 @@ public final class InputProcessor { | |||
| 100 | public Path readPath(String prompt) { | 99 | public Path readPath(String prompt) { |
| 101 | while (true) { | 100 | while (true) { |
| 102 | var raw = readLine(prompt); | 101 | var raw = readLine(prompt); |
| 103 | |||
| 104 | if (raw.isBlank()) { | 102 | if (raw.isBlank()) { |
| 105 | println("Please enter a file path."); | 103 | println("Please enter a file path."); |
| 106 | continue; | 104 | continue; |
| 107 | } | 105 | } |
| 108 | |||
| 109 | try { | 106 | try { |
| 110 | return Path.of(unquote(raw)); | 107 | return Path.of(unquote(raw)); |
| 111 | } catch (InvalidPathException e) { | 108 | } catch (InvalidPathException e) { |
| @@ -126,7 +123,6 @@ public final class InputProcessor { | |||
| 126 | public boolean readYesNo(String prompt) { | 123 | public boolean readYesNo(String prompt) { |
| 127 | while (true) { | 124 | while (true) { |
| 128 | var raw = readLine("%s [Y/N]: ".formatted(prompt)).toLowerCase(); | 125 | var raw = readLine("%s [Y/N]: ".formatted(prompt)).toLowerCase(); |
| 129 | |||
| 130 | switch (raw) { | 126 | switch (raw) { |
| 131 | case "y", "yes" -> { | 127 | case "y", "yes" -> { |
| 132 | return true; | 128 | return true; |
| @@ -134,14 +130,14 @@ public final class InputProcessor { | |||
| 134 | case "n", "no" -> { | 130 | case "n", "no" -> { |
| 135 | return false; | 131 | return false; |
| 136 | } | 132 | } |
| 137 | default -> IO.println("Please answer y/yes or n/no."); | 133 | default -> println("Please answer y/yes or n/no."); |
| 138 | } | 134 | } |
| 139 | } | 135 | } |
| 140 | } | 136 | } |
| 141 | 137 | ||
| 142 | public <T> T readSelect(String prompt, List<T> items, Function<T, String> function) { | 138 | public <T> T readSelect(String prompt, List<T> items, Function<T, String> function) { |
| 143 | for (var i = 0; i < items.size(); i++) { | 139 | for (var i = 0; i < items.size(); i++) { |
| 144 | IO.println(" [%d]->> %s".formatted(i + 1, function.apply(items.get(i)))); | 140 | println(" [%d]->> %s".formatted(i + 1, function.apply(items.get(i)))); |
| 145 | } | 141 | } |
| 146 | 142 | ||
| 147 | var pick = readInt(prompt, 1, items.size()); | 143 | var pick = readInt(prompt, 1, items.size()); |
| @@ -156,12 +152,16 @@ public final class InputProcessor { | |||
| 156 | public void printReceipt(PurchaseReceiptDTO receipt) { | 152 | public void printReceipt(PurchaseReceiptDTO receipt) { |
| 157 | newLine(); | 153 | newLine(); |
| 158 | println("Purchase confirmed:"); | 154 | println("Purchase confirmed:"); |
| 159 | println(tradeRow("Option", "Qty", "Paid", "At")); | 155 | println(tradeRow("Option", "Qty", "Cost", "At")); |
| 160 | println("-".repeat(OPTION_WIDTH + QTY_WIDTH + PAID_WIDTH + AT_WIDTH + 3)); | 156 | println("-".repeat(OPTION_WIDTH + QTY_WIDTH + PAID_WIDTH + AT_WIDTH + 3)); |
| 161 | 157 | ||
| 162 | for (var trade : receipt.trades()) { | 158 | for (var trade : receipt.trades()) { |
| 163 | println(tradeRow(trade.optionName(), trade.quantity(), trade.pricePaid(), trade.at())); | 159 | println(tradeRow(trade.optionName(), trade.quantity(), trade.pricePaid(), trade.at())); |
| 164 | } | 160 | } |
| 161 | newLine(); | ||
| 162 | println("Shares cost: %s".formatted(receipt.sharesCost())); | ||
| 163 | println("Commission paid: %s".formatted(receipt.commissionPaid())); | ||
| 164 | println("Total amount paid: %s".formatted(receipt.totalPaid())); | ||
| 165 | 165 | ||
| 166 | printState(receipt.stateAfter()); | 166 | printState(receipt.stateAfter()); |
| 167 | } | 167 | } |
| @@ -175,7 +175,7 @@ public final class InputProcessor { | |||
| 175 | return; | 175 | return; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | println(tradeRow("Option", "Qty", "Paid", "At")); | 178 | println(tradeRow("Option", "Qty", "Cost", "At")); |
| 179 | println("-".repeat(OPTION_WIDTH + QTY_WIDTH + PAID_WIDTH + AT_WIDTH + 3)); | 179 | println("-".repeat(OPTION_WIDTH + QTY_WIDTH + PAID_WIDTH + AT_WIDTH + 3)); |
| 180 | 180 | ||
| 181 | for (var trade : history) { | 181 | for (var trade : history) { |
| @@ -192,3 +192,4 @@ public final class InputProcessor { | |||
| 192 | padRight(at, AT_WIDTH)); | 192 | padRight(at, AT_WIDTH)); |
| 193 | } | 193 | } |
| 194 | } | 194 | } |
| 195 | |||