diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 2a9fc8d5628..ded8afd8976 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -154,37 +154,46 @@ Classes used by multiple components are in the `io.xpire.commons` package. This section describes some noteworthy details on how certain features are implemented. // tag:tobuylist[] -=== [Proposed] ToReplenish/ToBuy List + +=== [Proposed] Replenish List ==== Implementation -_{Explain here how the ToReplenish/ToBuy List is implemented}_ +//{Explain here how the ToReplenish/ToBuy List is implemented}_ +Items are added to the replenish list by the user using the replenish command. +When an item expires, the item is automatically tagged as "expired". +This enables the user to search for a list of expired items by searching for the "expired" tag. +With this, the user is able to view the list of expired items and decide which items to add to the replenish list. +On the other hand, when an item has run out, the user is prompted to replenish the item using the replenish command. -Given below is an example usage scenario and how the mechanism behaves at each step. +image::ItemManagerClassDiagram.png[] -The following sequence diagram shows how the operation works: +//Given below is an example usage scenario and how the mechanism behaves at each step. -The following activity diagram summarizes what happens when a user executes a new command: +//The following sequence diagram shows how the operation works: + +//The following activity diagram summarizes what happens when a user executes a new command: ==== Design Considerations -===== Aspect: How ToReplenish/ToBuy List executes +===== Aspect: How item is added to the replenish list -* **Alternative 1 (current choice):** -** Pros: -** Cons: +* **Alternative 1 (current choice): Once an item expires or runs out, +the user is prompted to shift the item to the replenish list by typing the replenish command and item index.** +** Pros: User has flexibility in deciding what to add to the replenish list. +** Cons: User has to manually type in a short command to add an item to the replenish list. -* **Alternative 2:** -** Pros: -** Cons: +* **Alternative 2: Once an item expires or runs out, item is transferred to the replenish list.** +** Pros: User need not manually key in item details to transfer it to the replenish list. +** Cons: User may not want the item in the list and as such would expect a delete functionality for the to-replenish list. +// +//===== Aspect: Data structure to store the items +//* **Alternative 1 (current choice):** +//** Pros: +//** Cons: +// +//* **Alternative 2:** +//** Pros: +//** Cons: -===== Aspect: Data structure to store the items -* **Alternative 1 (current choice):** -** Pros: -** Cons: - -* **Alternative 2:** -** Pros: -** Cons: -// end::tobuylist[] // tag:autosort[] === Auto-sorting of items by name then date @@ -259,6 +268,7 @@ The following activity diagram summarizes what happens when a user executes a ne // end::setreminder[] + // tag::undoredo[] === Undo/Redo feature ==== Implementation @@ -788,14 +798,14 @@ _{More to be added}_ |FXML |XML-based user interface markup language for defining user interface of a JaxaFX application -|JavaFX |Software platform for creating and delivering desktop applications and rich Internet applications - -|JSON |An open-standard file format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data types - |ItemCard |UI component that displays information on an item |ItemListPanel |UI component that displays list of items +|JavaFX |Software platform for creating and delivering desktop applications and rich Internet applications + +|JSON |An open-standard file format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data types + |Logic |Handles user input for the application and returns the application's output |MainWindow |Provides the basic application layout containing a menu bar and space where other JavaFX elements can be placed diff --git a/docs/diagrams/ItemManagerClassDiagram.puml b/docs/diagrams/ItemManagerClassDiagram.puml new file mode 100644 index 00000000000..78a824ba6f2 --- /dev/null +++ b/docs/diagrams/ItemManagerClassDiagram.puml @@ -0,0 +1,41 @@ +@startuml + +class ItemManager { +- model: Model +- storage: Storage +~ void updateItemTags() +} +interface Storage { ++ void saveXpire(ReadOnlyXpire) ++ void saveXpire(ReadOnlyXpire, Path) +} +interface Model { +~ void updateItemTags() ++ getXpire(): ReadOnlyXpire +} +class StorageManager { +- xpireStorage: XpireStorage +} +class ModelManager { +- xpire: Xpire +} +class Xpire { +- items: SortedUniqueItemList +~ void checkExpiryDates() +} +class SortedUniqueItemList { ++ Iterator iterator() +} +class Item { +- tags: Set ++ boolean isItemExpired() +- void addTag(Tag) +} +ItemManager --> Model +ItemManager --> Storage +Storage <|.. StorageManager +Model <|.. ModelManager +ModelManager --> Xpire +Xpire --> SortedUniqueItemList +SortedUniqueItemList --> Item +@enduml diff --git a/docs/images/ItemManagerClassDiagram.png b/docs/images/ItemManagerClassDiagram.png new file mode 100644 index 00000000000..599269e74f9 Binary files /dev/null and b/docs/images/ItemManagerClassDiagram.png differ diff --git a/src/main/java/io/xpire/logic/parser/DeleteCommandParser.java b/src/main/java/io/xpire/logic/parser/DeleteCommandParser.java index 82fcfc990bc..140849d7ee5 100644 --- a/src/main/java/io/xpire/logic/parser/DeleteCommandParser.java +++ b/src/main/java/io/xpire/logic/parser/DeleteCommandParser.java @@ -32,6 +32,9 @@ public DeleteCommand parse(String args) throws ParseException { return deleteTagsCommand(index, splitArgs[1]); } else if (containsQuantity(splitArgs)) { return deleteQuantityCommand(index, splitArgs[1]); + } else if (splitArgs.length > 1) { + throw new ParseException( + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); } else { return deleteItemCommand(index); } diff --git a/src/main/java/io/xpire/model/item/Quantity.java b/src/main/java/io/xpire/model/item/Quantity.java index 58d85842ee5..12bd9742fe6 100644 --- a/src/main/java/io/xpire/model/item/Quantity.java +++ b/src/main/java/io/xpire/model/item/Quantity.java @@ -17,6 +17,7 @@ public class Quantity { public static final String DEFAULT_QUANTITY = "1"; public static final String MESSAGE_CONSTRAINTS = "Quantity added should be a positive integer and should not be blank"; + public static final int MAX_VALUE = 100000; private static final String INTERNAL_MESSAGE_CONSTRAINTS = "Quantity added should be a non-negative integer and should not be blank"; private int quantity; @@ -56,13 +57,16 @@ private Quantity(int quantity) throws ParseException { } public static boolean isValidQuantity(String test) { - return StringUtil.isNonNegativeInteger(test); + return StringUtil.isNonNegativeInteger(test) && Integer.parseInt(test) <= MAX_VALUE; } /** * Returns true if a given input string is a valid quantity. */ + /** + * Returns true if a given input string is a valid quantity and lies below the maximum value. + */ public static boolean isValidInputQuantity(String test) { - return StringUtil.isNonZeroUnsignedInteger(test); + return StringUtil.isNonZeroUnsignedInteger(test) && Integer.parseInt(test) <= MAX_VALUE; } /** diff --git a/src/test/java/io/xpire/logic/parser/DeleteCommandParserTest.java b/src/test/java/io/xpire/logic/parser/DeleteCommandParserTest.java index c8cb4259490..a2057b99719 100644 --- a/src/test/java/io/xpire/logic/parser/DeleteCommandParserTest.java +++ b/src/test/java/io/xpire/logic/parser/DeleteCommandParserTest.java @@ -30,15 +30,17 @@ public class DeleteCommandParserTest { @Test public void parse_validArgs_returnsDeleteCommand() { assertEqualsParseSuccess(parser, "1", new DeleteCommand(INDEX_FIRST_ITEM)); - - //trailing bars and arguments behind trailing bars will be trimmed - assertEqualsParseSuccess(parser, "1||||||1", new DeleteCommand(INDEX_FIRST_ITEM)); } @Test public void parse_invalidArgs_throwsParseException() { + assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE)); + + //invalid trailing arguments + assertParseFailure(parser, "1||||||1", String.format(MESSAGE_INVALID_COMMAND_FORMAT, + DeleteCommand.MESSAGE_USAGE)); } @Test diff --git a/src/test/java/io/xpire/model/item/QuantityTest.java b/src/test/java/io/xpire/model/item/QuantityTest.java index 987771fb067..c53a910a57d 100644 --- a/src/test/java/io/xpire/model/item/QuantityTest.java +++ b/src/test/java/io/xpire/model/item/QuantityTest.java @@ -46,6 +46,9 @@ public void isValidInputQuantity() { //input is a character -> returns false assertFalse(Quantity.isValidInputQuantity("a")); + + //input is greater than maximum allowed value + assertFalse(Quantity.isValidInputQuantity("100001")); } @Test @@ -64,6 +67,9 @@ public void isValidQuantity() { //input is a character -> returns false assertFalse(Quantity.isValidQuantity("a")); + + //input is greater than maximum allowed value + assertFalse(Quantity.isValidQuantity("100001")); } @Test