Skip to content

Commit 74575af

Browse files
authored
Merge pull request nus-cs2103-AY2021S1#107 from zhengweii/find-warehouse-command
Find warehouse command
2 parents fb9b1c2 + 3c33317 commit 74575af

25 files changed

+381
-108
lines changed

docs/UserGuide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ and efficient Graphical User Interface interaction.
1313

1414
--------------------------------------------------------------------------------------------------------------------
1515

16-
## Quick startf
16+
## Quick start
1717

1818
1. Ensure you have Java `11` or above installed in your Computer.
1919

src/main/java/seedu/clinic/logic/commands/FindCommand.java

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,73 @@
22

33
import static java.util.Objects.requireNonNull;
44

5+
import java.util.Optional;
6+
57
import seedu.clinic.commons.core.Messages;
68
import seedu.clinic.model.Model;
7-
import seedu.clinic.model.attribute.NameContainsKeywordsPredicateForSupplier;
9+
import seedu.clinic.model.supplier.SupplierProductsContainKeywordsPredicate;
10+
import seedu.clinic.model.warehouse.WarehouseProductsContainKeywordsPredicate;
811

912
/**
10-
* Finds and lists all suppliers/warehouses in the CLI-nic app whose name contains any of the argument keywords.
13+
* Finds and lists all suppliers/warehouses in the CLI-nic app that sell/hold products matching any of the argument
14+
* keywords.
1115
* Keyword matching is case insensitive.
16+
* Keyword only matches whole word e.g. band will match "band aid" but not "bandaid".
1217
*/
1318
public class FindCommand extends Command {
1419

1520
public static final String COMMAND_WORD = "find";
1621

17-
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all suppliers whose names contain any of "
18-
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
19-
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
20-
+ "Example: " + COMMAND_WORD + " alice bob charlie";
22+
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all suppliers/warehouses that sell/hold products"
23+
+ "matching the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
24+
+ "Parameters: TYPE KEYWORD [MORE_KEYWORDS...]\n"
25+
+ "Example: " + COMMAND_WORD + " supplier panadol"
26+
+ "Example: " + COMMAND_WORD + " warehouse face mask";
27+
28+
private final Optional<SupplierProductsContainKeywordsPredicate> supplierPredicate;
29+
private final Optional<WarehouseProductsContainKeywordsPredicate> warehousePredicate;
2130

22-
private final NameContainsKeywordsPredicateForSupplier predicate;
31+
/**
32+
* Constructs a new FindCommand object.
33+
*
34+
* @param supplierPredicate takes in the predicate used to filter a supplier's products.
35+
*/
36+
public FindCommand(SupplierProductsContainKeywordsPredicate supplierPredicate) {
37+
this.supplierPredicate = Optional.of(supplierPredicate);
38+
this.warehousePredicate = Optional.empty();
39+
}
2340

24-
public FindCommand(NameContainsKeywordsPredicateForSupplier predicate) {
25-
this.predicate = predicate;
41+
/**
42+
* Constructs a new FindCommand object.
43+
*
44+
* @param warehousePredicate takes in the predicate used to filter a warehouse's products.
45+
*/
46+
public FindCommand(WarehouseProductsContainKeywordsPredicate warehousePredicate) {
47+
this.warehousePredicate = Optional.of(warehousePredicate);
48+
this.supplierPredicate = Optional.empty();
2649
}
2750

2851
@Override
2952
public CommandResult execute(Model model) {
3053
requireNonNull(model);
31-
model.updateFilteredSupplierList(predicate);
32-
return new CommandResult(
33-
String.format(Messages.MESSAGE_SUPPLIERS_LISTED_OVERVIEW, model.getFilteredSupplierList().size()));
54+
55+
if (supplierPredicate.isPresent()) {
56+
model.updateFilteredSupplierList(supplierPredicate.get());
57+
return new CommandResult(
58+
String.format(Messages.MESSAGE_SUPPLIERS_LISTED_OVERVIEW, model.getFilteredSupplierList().size()));
59+
} else {
60+
model.updateFilteredWarehouseList(warehousePredicate.get());
61+
return new CommandResult(
62+
String.format(Messages.MESSAGE_WAREHOUSE_LISTED_OVERVIEW, model.getFilteredWarehouseList().size()));
63+
}
3464
}
3565

3666
@Override
3767
public boolean equals(Object other) {
3868
return other == this // short circuit if same object
3969
|| (other instanceof FindCommand // instanceof handles nulls
40-
&& predicate.equals(((FindCommand) other).predicate)); // state check
70+
&& (supplierPredicate.isPresent()
71+
? supplierPredicate.equals(((FindCommand) other).supplierPredicate)
72+
: warehousePredicate.equals(((FindCommand) other).warehousePredicate)));
4173
}
4274
}

src/main/java/seedu/clinic/logic/parser/FindCommandParser.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import static seedu.clinic.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
44

55
import java.util.Arrays;
6+
import java.util.List;
67

78
import seedu.clinic.logic.commands.FindCommand;
89
import seedu.clinic.logic.parser.exceptions.ParseException;
9-
import seedu.clinic.model.attribute.NameContainsKeywordsPredicateForSupplier;
10+
import seedu.clinic.model.supplier.SupplierProductsContainKeywordsPredicate;
11+
import seedu.clinic.model.warehouse.WarehouseProductsContainKeywordsPredicate;
1012

1113
/**
1214
* Parses input arguments and creates a new FindCommand object
@@ -25,9 +27,21 @@ public FindCommand parse(String args) throws ParseException {
2527
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
2628
}
2729

28-
String[] nameKeywords = trimmedArgs.split("\\s+");
30+
String[] productNameKeywords = trimmedArgs.split("\\s+");
31+
String type = productNameKeywords[0].toLowerCase();
2932

30-
return new FindCommand(new NameContainsKeywordsPredicateForSupplier(Arrays.asList(nameKeywords)));
33+
// Ensures that the user enters the type and at least 1 keyword
34+
if (!(type.equals("supplier") || type.equals("warehouse")) || productNameKeywords.length < 2) {
35+
throw new ParseException(
36+
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
37+
}
38+
39+
List<String> keywords = Arrays.asList(productNameKeywords);
40+
if (type.equals("supplier")) {
41+
return new FindCommand(new SupplierProductsContainKeywordsPredicate(keywords));
42+
} else {
43+
return new FindCommand(new WarehouseProductsContainKeywordsPredicate(keywords));
44+
}
3145
}
3246

3347
}

src/main/java/seedu/clinic/model/attribute/Name.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ public class Name {
1212
public static final String MESSAGE_CONSTRAINTS =
1313
"Names should only contain alphanumeric characters and spaces, and it should not be blank";
1414

15-
/*
15+
/**
1616
* The first character of the name must be alphanumeric.
17-
* The .
1817
*/
1918
public static final String VALIDATION_REGEX = "[\\p{Alnum}][\\p{Print}]*";
2019

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package seedu.clinic.model.supplier;
2+
3+
import java.util.List;
4+
import java.util.function.Predicate;
5+
6+
import seedu.clinic.commons.util.StringUtil;
7+
import seedu.clinic.model.product.Product;
8+
9+
/**
10+
* Tests that any of the {@code Product} sold by {@code Supplier} matches any of the keywords given.
11+
*/
12+
public class SupplierProductsContainKeywordsPredicate implements Predicate<Supplier> {
13+
private final List<String> keywords;
14+
15+
public SupplierProductsContainKeywordsPredicate(List<String> keywords) {
16+
this.keywords = keywords;
17+
}
18+
19+
@Override
20+
public boolean test(Supplier supplier) {
21+
Product[] products = supplier.getProducts().toArray(Product[]::new);
22+
for (int i = 0; i < products.length; i++) {
23+
String productName = products[i].getProductName().fullName;
24+
boolean match = keywords.stream()
25+
.anyMatch(keyword -> StringUtil.containsWordIgnoreCase(productName, keyword));
26+
27+
if (match) {
28+
return true;
29+
}
30+
}
31+
32+
return false;
33+
}
34+
35+
@Override
36+
public boolean equals(Object other) {
37+
return other == this // short circuit if same object
38+
|| (other instanceof SupplierProductsContainKeywordsPredicate // instanceof handles nulls
39+
&& keywords.equals(((SupplierProductsContainKeywordsPredicate) other).keywords)); // state check
40+
}
41+
42+
}

src/main/java/seedu/clinic/model/util/SampleDataUtil.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,45 +26,45 @@ public static Supplier[] getSampleSuppliers() {
2626
return new Supplier[] {
2727
new Supplier(new Name("Alex Yeoh Ltd"), new Phone("87438807"), new Email("[email protected]"),
2828
new Remark("long term partner"),
29-
getProductSet(Map.of("Panadol", new String[]{"fever"}))),
29+
getProductSet(new HashSet<Product>(), Map.of("Panadol", new String[]{"fever"}))),
3030
new Supplier(new Name("Bernice Yu Pte Ltd"), new Phone("99272758"), new Email("[email protected]"),
3131
new Remark("long term partner"),
32-
getProductSet(Map.of("Panadol", new String[]{"fever"}))),
32+
getProductSet(new HashSet<Product>(), Map.of("Panadol", new String[]{"fever"}))),
3333
new Supplier(new Name("Charlotte Oliveiro Ltd"), new Phone("93210283"), new Email("[email protected]"),
3434
new Remark("long term partner"),
35-
getProductSet(Map.of("Panadol", new String[]{"fever"}))),
35+
getProductSet(new HashSet<Product>(), Map.of("Panadol", new String[]{"fever"}))),
3636
new Supplier(new Name("David Li Pte Ltd"), new Phone("91031282"), new Email("[email protected]"),
3737
new Remark("long term partner"),
38-
getProductSet(Map.of("Panadol", new String[]{"fever"}))),
38+
getProductSet(new HashSet<Product>(), Map.of("Panadol", new String[]{"fever"}))),
3939
new Supplier(new Name("Irfan Ibrahim Pte Ltd"), new Phone("92492021"), new Email("[email protected]"),
4040
new Remark("long term partner"),
41-
getProductSet(Map.of("Panadol", new String[]{"fever"}))),
41+
getProductSet(new HashSet<Product>(), Map.of("Panadol", new String[]{"fever"}))),
4242
new Supplier(new Name("Roy Balakrishnan Pte Ltd"), new Phone("92624417"), new Email("[email protected]"),
4343
new Remark("long term partner"),
44-
getProductSet(Map.of("Panadol", new String[]{"fever"}))),
44+
getProductSet(new HashSet<Product>(), Map.of("Panadol", new String[]{"fever"}))),
4545
};
4646
}
4747

4848
public static Warehouse[] getSampleWarehouses() {
4949
return new Warehouse[] {
5050
new Warehouse(new Name("Alex Yeoh warehouse"), new Phone("87438807"),
5151
new Address("21 Lower Kent Ridge Rd, Singapore 119077"), new Remark("long term partner"),
52-
getProductSetForWarehouse(Map.of("Panadol", 10))),
52+
getProductSetForWarehouse(new HashSet<Product>(), Map.of("Panadol", 10))),
5353
new Warehouse(new Name("Bernice Yu warehouse"), new Phone("99272758"),
5454
new Address("21 Lower Kent Ridge Rd, Singapore 119077"), new Remark("long term partner"),
55-
getProductSetForWarehouse(Map.of("Panadol", 20))),
55+
getProductSetForWarehouse(new HashSet<Product>(), Map.of("Panadol", 20))),
5656
new Warehouse(new Name("Charlotte Oliveiro warehouse"), new Phone("93210283"),
5757
new Address("21 Lower Kent Ridge Rd, Singapore 119077"), new Remark("long term partner"),
58-
getProductSetForWarehouse(Map.of("Panadol", 30))),
58+
getProductSetForWarehouse(new HashSet<Product>(), Map.of("Panadol", 30))),
5959
new Warehouse(new Name("David Li warehouse"), new Phone("91031282"),
6060
new Address("21 Lower Kent Ridge Rd, Singapore 119077"), new Remark("long term partner"),
61-
getProductSetForWarehouse(Map.of("Panadol", 100))),
61+
getProductSetForWarehouse(new HashSet<Product>(), Map.of("Panadol", 100))),
6262
new Warehouse(new Name("Irfan Ibrahim warehouse"), new Phone("92492021"),
6363
new Address("21 Lower Kent Ridge Rd, Singapore 119077"), new Remark("long term partner"),
64-
getProductSetForWarehouse(Map.of("Panadol", 50))),
64+
getProductSetForWarehouse(new HashSet<Product>(), Map.of("Panadol", 50))),
6565
new Warehouse(new Name("Roy Balakrishnan warehouse"), new Phone("92624417"),
6666
new Address("21 Lower Kent Ridge Rd, Singapore 119077"), new Remark("long term partner"),
67-
getProductSetForWarehouse(Map.of("Panadol", 70))),
67+
getProductSetForWarehouse(new HashSet<Product>(), Map.of("Panadol", 70))),
6868
};
6969
}
7070

@@ -93,8 +93,7 @@ public static Set<Tag> getTagSet(String... strings) {
9393
/**
9494
* Returns a product set containing the hashmap of strings given.
9595
*/
96-
public static Set<Product> getProductSet(Map<String, String[]> productMap) {
97-
Set<Product> productSet = new HashSet<>();
96+
public static Set<Product> getProductSet(Set<Product> productSet, Map<String, String[]> productMap) {
9897
for (String productName:productMap.keySet()) {
9998
Set<Tag> productTags = getTagSet(productMap.get(productName));
10099
Product product = new Product(new Name(productName), productTags);
@@ -106,8 +105,7 @@ public static Set<Product> getProductSet(Map<String, String[]> productMap) {
106105
/**
107106
* Returns a product set containing the hashmap of strings given.
108107
*/
109-
public static Set<Product> getProductSetForWarehouse(Map<String, Integer> productMap) {
110-
Set<Product> productSet = new HashSet<>();
108+
public static Set<Product> getProductSetForWarehouse(Set<Product> productSet, Map<String, Integer> productMap) {
111109
for (String productName:productMap.keySet()) {
112110
Product product = new Product(new Name(productName), productMap.get(productName));
113111
productSet.add(product);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package seedu.clinic.model.warehouse;
2+
3+
import java.util.List;
4+
import java.util.function.Predicate;
5+
6+
import seedu.clinic.commons.util.StringUtil;
7+
import seedu.clinic.model.product.Product;
8+
9+
/**
10+
* Tests that any of the {@code Product} stored in a {@code Warehouse} matches any of the keywords given.
11+
*/
12+
public class WarehouseProductsContainKeywordsPredicate implements Predicate<Warehouse> {
13+
private final List<String> keywords;
14+
15+
public WarehouseProductsContainKeywordsPredicate(List<String> keywords) {
16+
this.keywords = keywords;
17+
}
18+
19+
@Override
20+
public boolean test(Warehouse warehouse) {
21+
Product[] products = warehouse.getProducts().toArray(Product[]::new);
22+
for (int i = 0; i < products.length; i++) {
23+
String productName = products[i].getProductName().fullName;
24+
boolean match = keywords.stream()
25+
.anyMatch(keyword -> StringUtil.containsWordIgnoreCase(productName, keyword));
26+
27+
if (match) {
28+
return true;
29+
}
30+
}
31+
32+
return false;
33+
}
34+
35+
@Override
36+
public boolean equals(Object other) {
37+
return other == this // short circuit if same object
38+
|| (other instanceof WarehouseProductsContainKeywordsPredicate // instanceof handles nulls
39+
&& keywords.equals(((WarehouseProductsContainKeywordsPredicate) other).keywords)); // state check
40+
}
41+
42+
}

src/test/data/JsonClinicStorageTest/invalidSupplierClinic.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"name": "Supplier with invalid name field: Ha!ns Mu@ster",
44
"phone": "9482424",
55
"email": "[email protected]",
6-
"remark": "Trusted company"
6+
"remark": "Trusted seller"
77
} ],
88
"warehouse": [ ]
99
}

src/test/data/JsonClinicStorageTest/invalidWarehouseClinic.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"name": "@ invalid name warehouse",
55
"phone": "9482424",
66
"address": "hans address",
7-
"remark": "Trusted company"
7+
"remark": "Biggest warehouse"
88
} ]
99
}

src/test/data/JsonSerializableClinicTest/duplicateWarehouseClinic.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"name" : "Alice Pauline Ltd",
1414
"phone" : "98765432",
1515
"address" : "johnd address",
16-
"remark" : "trusted warehouse",
16+
"remark" : "biggest warehouse",
1717
"products": [ {
1818
"name": "Panadol",
1919
"quantity": 20

0 commit comments

Comments
 (0)