From 5c616f881d606ce3d1fda1b1248ea3f2986edf72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ege=20Demirk=C4=B1rkan?= Date: Fri, 4 Mar 2022 10:15:21 +0800 Subject: [PATCH 001/131] Set theme jekyll-theme-minimal --- docs/_config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/_config.yml diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000000..2f7efbeab5 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-minimal \ No newline at end of file From 80c25f76aaa0a3bbcc19e4831457c7805b8aa0a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ege=20Demirk=C4=B1rkan?= Date: Fri, 4 Mar 2022 10:43:00 +0800 Subject: [PATCH 002/131] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..3f17a13604 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,7 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From 6035a3df1f1e7d52a047f56f42cc0e48b4416814 Mon Sep 17 00:00:00 2001 From: chintaiann Date: Fri, 4 Mar 2022 10:45:03 +0800 Subject: [PATCH 003/131] update AboutUs --- docs/AboutUs.md | 14 +++++++------- docs/team/chintaiann.md | 6 ++++++ 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 docs/team/chintaiann.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..6ca2df8535 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:------------:|:---------------------------------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) diff --git a/docs/team/chintaiann.md b/docs/team/chintaiann.md new file mode 100644 index 0000000000..c1db15bd38 --- /dev/null +++ b/docs/team/chintaiann.md @@ -0,0 +1,6 @@ +# Tai Ann - Project Portfolio Page + +## Overview + + +### Summary of Contributions \ No newline at end of file From 4fda6aa1417b8b83baaa59c86cd7cbd234527be6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Mar 2022 10:49:19 +0800 Subject: [PATCH 004/131] Add brendan to aboutus --- docs/AboutUs.md | 14 +++++++------- docs/team/brendan.md | 0 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 docs/team/brendan.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..19d9d700da 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +| Display | Name | Github Profile | Portfolio | +| --------------------------------------------------- | :---------: | :--------------------------------: | :-------------------------------: | +| ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | diff --git a/docs/team/brendan.md b/docs/team/brendan.md new file mode 100644 index 0000000000..e69de29bb2 From d40c81f7e396edc025698f7a0dc58319d9e201d4 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 4 Mar 2022 10:59:37 +0800 Subject: [PATCH 005/131] update about-us --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..2e431cc3a1 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -4,6 +4,6 @@ Display | Name | Github Profile | Portfolio --------|:----:|:--------------:|:---------: ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang| [Github](https://github.com/timchang27) | [Portfolio](docs/team/timothy.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From 354e627ccc805b5e527b6d16ae90128b317c4c90 Mon Sep 17 00:00:00 2001 From: chintaiann Date: Thu, 10 Mar 2022 20:55:38 +0800 Subject: [PATCH 006/131] v1.0 Implement TravelPackage class Adding of travel package Removal of travel package through ID Printing of all travel packages todo: error handling --- src/main/java/seedu/duke/Duke.java | 101 +++++++++++++++++--- src/main/java/seedu/duke/TravelPackage.java | 54 +++++++++++ 2 files changed, 141 insertions(+), 14 deletions(-) create mode 100644 src/main/java/seedu/duke/TravelPackage.java diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 5c74e68d59..17b506dcb3 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -1,21 +1,94 @@ package seedu.duke; +import java.util.ArrayList; +import java.util.Date; import java.util.Scanner; - public class Duke { - /** - * Main entry-point for the java.duke.Duke application. - */ + // private ArrayList packages; + // public TravelPackage(String name, int id, Date startDate, Date endDate, String hotel, double price, String country, int maxParticipants) { + public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - System.out.println("What is your name?"); - - Scanner in = new Scanner(System.in); - System.out.println("Hello " + in.nextLine()); + ArrayList packages = new ArrayList(); + packages.add(new TravelPackage("Experience Korea!", 1, new Date(25032021), new Date(28032021), "Four Seasons", 500.25,"Korea", 20)); + + boolean endProgram = false; + System.out.print("Welcome to Travel Agency Booking Reservation System!"); + + while (!endProgram) { + Scanner sc = new Scanner(System.in); + System.out.println("Please enter command: "); + String nextLine = sc.nextLine(); + if (nextLine.equals("bye")) { + endProgram = true; + System.out.println("Thank you for using TARBS. See you again!"); + break; + } + + else if (nextLine.equals("packages")){ + for (int i = 0; i < packages.size(); i++){ + packages.get(i).printInfo(); + } + + } + + //add [packageName], [id] , [DDMMYYYY] , [DDMMYYYY], [hotel], [price], [country], [maxVacancies] + else if (nextLine.equals("add")) { + + System.out.println("Enter package name: "); + String name = sc.nextLine(); + System.out.println("Enter package id: "); + int id = Integer.parseInt(sc.nextLine()); + System.out.println("Enter start date in DDMMYYYY"); + int date1 = Integer.parseInt(sc.nextLine()); + System.out.println("Enter end date in DDMMYYYY"); + int date2 = Integer.parseInt(sc.nextLine()); + System.out.println("Enter hotel name: "); + String hotel = sc.nextLine(); + System.out.println("Enter price: "); + double price = Double.parseDouble(sc.nextLine()); + System.out.println("Enter country name: "); + String country = sc.nextLine(); + System.out.println("Enter max vacancies: "); + int maxVacancies = Integer.parseInt(sc.nextLine()); + + packages.add(new TravelPackage(name, id, new Date(date1), new Date(date2), hotel, price, country, maxVacancies)); + } + + else if (nextLine.startsWith("help")) { + //print guide info for first time users + } + + else if (nextLine.matches("delete \\d+")) { + //input must be delete [number] -> delete 1 deletes travel package ID 1 + String[] line = nextLine.split(" "); + int removeID = Integer.parseInt(line[1]); + System.out.println(line[1]); + + for (int i = 0; i Date: Thu, 10 Mar 2022 23:18:49 +0800 Subject: [PATCH 007/131] Add OOP abstractions --- .gitignore | 2 + src/main/java/seedu/duke/Duke.java | 106 +++++------------- src/main/java/seedu/duke/Packages.java | 27 +++++ src/main/java/seedu/duke/Parser.java | 48 ++++++++ .../java/seedu/duke/command/AddCommand.java | 21 ++++ .../java/seedu/duke/command/ByeCommand.java | 13 +++ src/main/java/seedu/duke/command/Command.java | 21 ++++ .../seedu/duke/command/DeleteCommand.java | 22 ++++ .../seedu/duke/command/PackagesCommand.java | 15 +++ 9 files changed, 195 insertions(+), 80 deletions(-) create mode 100644 src/main/java/seedu/duke/Packages.java create mode 100644 src/main/java/seedu/duke/Parser.java create mode 100644 src/main/java/seedu/duke/command/AddCommand.java create mode 100644 src/main/java/seedu/duke/command/ByeCommand.java create mode 100644 src/main/java/seedu/duke/command/Command.java create mode 100644 src/main/java/seedu/duke/command/DeleteCommand.java create mode 100644 src/main/java/seedu/duke/command/PackagesCommand.java diff --git a/.gitignore b/.gitignore index f69985ef1f..6364bde48c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT + +.vscode/ \ No newline at end of file diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 17b506dcb3..d76f26a4ef 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -3,92 +3,38 @@ import java.util.ArrayList; import java.util.Date; import java.util.Scanner; -public class Duke { - // private ArrayList packages; - // public TravelPackage(String name, int id, Date startDate, Date endDate, String hotel, double price, String country, int maxParticipants) { - - public static void main(String[] args) { - ArrayList packages = new ArrayList(); - packages.add(new TravelPackage("Experience Korea!", 1, new Date(25032021), new Date(28032021), "Four Seasons", 500.25,"Korea", 20)); - - boolean endProgram = false; - System.out.print("Welcome to Travel Agency Booking Reservation System!"); - - while (!endProgram) { - Scanner sc = new Scanner(System.in); - System.out.println("Please enter command: "); - String nextLine = sc.nextLine(); - if (nextLine.equals("bye")) { - endProgram = true; - System.out.println("Thank you for using TARBS. See you again!"); - break; - } - - else if (nextLine.equals("packages")){ - for (int i = 0; i < packages.size(); i++){ - packages.get(i).printInfo(); - } - } +import seedu.duke.command.Command; - //add [packageName], [id] , [DDMMYYYY] , [DDMMYYYY], [hotel], [price], [country], [maxVacancies] - else if (nextLine.equals("add")) { - - System.out.println("Enter package name: "); - String name = sc.nextLine(); - System.out.println("Enter package id: "); - int id = Integer.parseInt(sc.nextLine()); - System.out.println("Enter start date in DDMMYYYY"); - int date1 = Integer.parseInt(sc.nextLine()); - System.out.println("Enter end date in DDMMYYYY"); - int date2 = Integer.parseInt(sc.nextLine()); - System.out.println("Enter hotel name: "); - String hotel = sc.nextLine(); - System.out.println("Enter price: "); - double price = Double.parseDouble(sc.nextLine()); - System.out.println("Enter country name: "); - String country = sc.nextLine(); - System.out.println("Enter max vacancies: "); - int maxVacancies = Integer.parseInt(sc.nextLine()); - - packages.add(new TravelPackage(name, id, new Date(date1), new Date(date2), hotel, price, country, maxVacancies)); - } - - else if (nextLine.startsWith("help")) { - //print guide info for first time users - } - - else if (nextLine.matches("delete \\d+")) { - //input must be delete [number] -> delete 1 deletes travel package ID 1 - String[] line = nextLine.split(" "); - int removeID = Integer.parseInt(line[1]); - System.out.println(line[1]); - - for (int i = 0; i temp = new ArrayList<>(); + temp.add(new TravelPackage("Experience Korea!", 1, new Date(25032021), new Date(28032021), "Four Seasons", + 500.25, "Korea", 20)); + packages = new Packages(temp); + } - else if (nextLine.startsWith("reserve")) { - // add,remove or list all reservations for a travel package + public static void main(String[] args) { + Duke duke = new Duke(); + duke.run(); + } - } + public void run() { - else { - System.out.println("Command not recognized."); - } + boolean endProgram = false; + System.out.print("Welcome to Travel Agency Booking Reservation System!"); - + while (!endProgram) { + Scanner sc = new Scanner(System.in); + System.out.println("Please enter command: "); + Command command = Parser.parse(sc.nextLine()); + command.execute(packages); + endProgram = command.getIsExit(); } - - - - } - -} +} diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java new file mode 100644 index 0000000000..79af75fce9 --- /dev/null +++ b/src/main/java/seedu/duke/Packages.java @@ -0,0 +1,27 @@ +package seedu.duke; + +import java.util.ArrayList; + +public class Packages { + private ArrayList packages; + + public Packages(ArrayList packages) { + this.packages = packages; + } + + public int getSize() { + return packages.size(); + } + + public TravelPackage getPackage(int index) { + return packages.get(index); + } + + public void addPackage(TravelPackage newPackage) { + packages.add(newPackage); + } + + public void removePackage(int index) { + packages.remove(index); + } +} diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java new file mode 100644 index 0000000000..0c28a9027b --- /dev/null +++ b/src/main/java/seedu/duke/Parser.java @@ -0,0 +1,48 @@ +package seedu.duke; + +import seedu.duke.command.AddCommand; +import seedu.duke.command.ByeCommand; +import seedu.duke.command.Command; +import seedu.duke.command.DeleteCommand; +import seedu.duke.command.PackagesCommand; + +public class Parser { + public static Command parse(String input) { + String[] inputArray = input.split(" "); + String commandType = inputArray[0]; + + int id, start, end, vacancies; + double price; + String name, hotel, country; + + switch (commandType) { + case "bye": + return new ByeCommand(); + case "add": + final int nameIndex = 1; + final int idIndex = 2; + final int startIndex = 3; + final int endIndex = 4; + final int hotelIndex = 5; + final int priceIndex = 6; + final int countryIndex = 7; + final int vacanciesIndex = 8; + name = inputArray[nameIndex]; + id = Integer.parseInt(inputArray[idIndex]); + start = Integer.parseInt(inputArray[startIndex]); + end = Integer.parseInt(inputArray[endIndex]); + hotel = inputArray[hotelIndex]; + price = Double.parseDouble(inputArray[priceIndex]); + country = inputArray[countryIndex]; + vacancies = Integer.parseInt(inputArray[vacanciesIndex]); + return new AddCommand(name, id, start, end, hotel, price, country, vacancies); + case "delete": + id = Integer.parseInt(inputArray[1]); + return new DeleteCommand(id); + case "packages": + return new PackagesCommand(); + default: + return new ByeCommand(); + } + } +} diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java new file mode 100644 index 0000000000..31b185badb --- /dev/null +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -0,0 +1,21 @@ +package seedu.duke.command; + +import java.util.Date; + +import seedu.duke.Packages; +import seedu.duke.TravelPackage; + +public class AddCommand extends Command { + private TravelPackage newPackage; + + public AddCommand(String name, int id, int date1, int date2, String hotel, double price, String country, + int maxVacancies) { + super(false); + this.newPackage = new TravelPackage(name, id, new Date(date1), new Date(date2), hotel, price, country, + maxVacancies); + } + + public void execute(Packages packages) { + packages.addPackage(newPackage); + } +} diff --git a/src/main/java/seedu/duke/command/ByeCommand.java b/src/main/java/seedu/duke/command/ByeCommand.java new file mode 100644 index 0000000000..e2f249cfbe --- /dev/null +++ b/src/main/java/seedu/duke/command/ByeCommand.java @@ -0,0 +1,13 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public class ByeCommand extends Command { + public ByeCommand() { + super(true); + } + + public void execute(Packages packages) { + System.out.println("Thank you for using TARBS. See you again!"); + } +} diff --git a/src/main/java/seedu/duke/command/Command.java b/src/main/java/seedu/duke/command/Command.java new file mode 100644 index 0000000000..ab105284df --- /dev/null +++ b/src/main/java/seedu/duke/command/Command.java @@ -0,0 +1,21 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public abstract class Command { + private boolean isExit; + + public Command(boolean isExit) { + this.isExit = isExit; + } + + public boolean getIsExit() { + return this.isExit; + } + + public void setIsExit(boolean isExit) { + this.isExit = isExit; + } + + public abstract void execute(Packages packages); +} diff --git a/src/main/java/seedu/duke/command/DeleteCommand.java b/src/main/java/seedu/duke/command/DeleteCommand.java new file mode 100644 index 0000000000..355a887510 --- /dev/null +++ b/src/main/java/seedu/duke/command/DeleteCommand.java @@ -0,0 +1,22 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public class DeleteCommand extends Command { + private int id; + + public DeleteCommand(int id) { + super(false); + this.id = id; + } + + public void execute(Packages packages) { + for (int i = 0; i < packages.getSize(); i++) { + if (packages.getPackage(i).getID() == id) { + packages.removePackage(i); + break; + } + } + + } +} diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java new file mode 100644 index 0000000000..0d50866eba --- /dev/null +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -0,0 +1,15 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public class PackagesCommand extends Command { + public PackagesCommand() { + super(false); + } + + public void execute(Packages packages) { + for (int i = 0; i < packages.getSize(); i++) { + packages.getPackage(i).printInfo(); + } + } +} From 5628838c0e7fda6f1e7e5d2163d081e629d631b6 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 11 Mar 2022 10:07:28 +0800 Subject: [PATCH 008/131] v1.0 - Some bugs --- src/main/java/seedu/duke/Customer.java | 23 +++ src/main/java/seedu/duke/Duke.java | 133 ++++++++++++++++-- src/main/java/seedu/duke/Help.java | 31 ++++ src/main/java/seedu/duke/Packages.java | 27 ++++ src/main/java/seedu/duke/Parser.java | 48 +++++++ src/main/java/seedu/duke/Reservation.java | 47 +++++++ src/main/java/seedu/duke/Reservations.java | 27 ++++ src/main/java/seedu/duke/TravelPackage.java | 49 +++++++ .../java/seedu/duke/command/AddCommand.java | 22 +++ .../duke/command/AddReservationCommand.java | 19 +++ .../java/seedu/duke/command/ByeCommand.java | 15 ++ src/main/java/seedu/duke/command/Command.java | 23 +++ .../seedu/duke/command/DeleteCommand.java | 22 +++ .../command/DeleteReservationCommand.java | 22 +++ .../duke/command/FindReservationsCommand.java | 16 +++ .../seedu/duke/command/PackagesCommand.java | 16 +++ .../duke/command/ReservationCommand.java | 22 +++ 17 files changed, 548 insertions(+), 14 deletions(-) create mode 100644 src/main/java/seedu/duke/Customer.java create mode 100644 src/main/java/seedu/duke/Help.java create mode 100644 src/main/java/seedu/duke/Packages.java create mode 100644 src/main/java/seedu/duke/Parser.java create mode 100644 src/main/java/seedu/duke/Reservation.java create mode 100644 src/main/java/seedu/duke/Reservations.java create mode 100644 src/main/java/seedu/duke/TravelPackage.java create mode 100644 src/main/java/seedu/duke/command/AddCommand.java create mode 100644 src/main/java/seedu/duke/command/AddReservationCommand.java create mode 100644 src/main/java/seedu/duke/command/ByeCommand.java create mode 100644 src/main/java/seedu/duke/command/Command.java create mode 100644 src/main/java/seedu/duke/command/DeleteCommand.java create mode 100644 src/main/java/seedu/duke/command/DeleteReservationCommand.java create mode 100644 src/main/java/seedu/duke/command/FindReservationsCommand.java create mode 100644 src/main/java/seedu/duke/command/PackagesCommand.java create mode 100644 src/main/java/seedu/duke/command/ReservationCommand.java diff --git a/src/main/java/seedu/duke/Customer.java b/src/main/java/seedu/duke/Customer.java new file mode 100644 index 0000000000..951c421123 --- /dev/null +++ b/src/main/java/seedu/duke/Customer.java @@ -0,0 +1,23 @@ +package seedu.duke; + +public class Customer { + private String customerID; + private String name; + private String contactNumber; + + public Customer(String customerID, String name, String contactNumber){ + this.customerID = customerID; + this.name = name; + this.contactNumber = contactNumber; + } + + public String getCustomerID() { + return customerID; + } + public String getName() { + return name; + } + public String getContactNumber() { + return contactNumber; + } +} diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 5c74e68d59..a0093f731a 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -1,21 +1,126 @@ package seedu.duke; +import java.util.ArrayList; +import java.util.Date; import java.util.Scanner; - public class Duke { - /** - * Main entry-point for the java.duke.Duke application. - */ + // private ArrayList packages; + // public TravelPackage(String name, int id, Date startDate, Date endDate, String hotel, double price, String country, int maxParticipants) { + public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - System.out.println("What is your name?"); - - Scanner in = new Scanner(System.in); - System.out.println("Hello " + in.nextLine()); + ArrayList packages = new ArrayList(); + ArrayList reservations = new ArrayList(); + packages.add(new TravelPackage("Experience Korea!", 1, new Date(25032021), new Date(28032021), "Four Seasons", 500.25,"Korea", 20)); + + Help helper = new Help(); + + boolean endProgram = false; + System.out.print("Welcome to Travel Agency Booking Reservation System!"); + + while (!endProgram) { + Scanner sc = new Scanner(System.in); + System.out.println("Please enter command: "); + String nextLine = sc.nextLine(); + if (nextLine.equals("bye")) { + endProgram = true; + System.out.println("Thank you for using TARBS. See you again!"); + break; + } + + else if (nextLine.equals("packages")){ + for (int i = 0; i < packages.size(); i++){ + System.out.println(Integer.toString(i+1) + ". " + packages.get(i).getName()); + } + } + else if (nextLine.equals("info")){ + System.out.println("Which package would you like to find out more about?"); + for (int i = 0; i < packages.size(); i++){ + System.out.println(Integer.toString(i+1) + ". " + packages.get(i).getName()); + } + String st = sc.nextLine(); + int index = Integer.parseInt(st); + if (index <= 0 || index > packages.size()){ + System.out.println("Please enter a valid number."); + } + else{ + packages.get(index-1).printInfo(); + } + } + //add [packageName], [id] , [DDMMYYYY] , [DDMMYYYY], [hotel], [price], [country], [maxVacancies] + else if (nextLine.equals("add")) { + System.out.println("Enter package name: "); + String name = sc.nextLine(); + System.out.println("Enter package id: "); + int id = Integer.parseInt(sc.nextLine()); + System.out.println("Enter start date in DDMMYYYY"); + int date1 = Integer.parseInt(sc.nextLine()); + System.out.println("Enter end date in DDMMYYYY"); + int date2 = Integer.parseInt(sc.nextLine()); + System.out.println("Enter hotel name: "); + String hotel = sc.nextLine(); + System.out.println("Enter price: "); + double price = Double.parseDouble(sc.nextLine()); + System.out.println("Enter country name: "); + String country = sc.nextLine(); + System.out.println("Enter max vacancies: "); + int maxVacancies = Integer.parseInt(sc.nextLine()); + + packages.add(new TravelPackage(name, id, new Date(date1), new Date(date2), hotel, price, country, maxVacancies)); + } + + else if (nextLine.equals("help")){ + System.out.println("Here's a guide on how to use TARBS!"); + helper.printHelp(); + } + + else if (nextLine.matches("delete \\d+")) { + //input must be delete [number] -> delete 1 deletes travel package ID 1 + String[] line = nextLine.split(" "); + int removeID = Integer.parseInt(line[1]); + System.out.println(line[1]); + + for (int i = 0; i desc; + + public Help(){ + this.desc = new ArrayList<>(); + String[] packages = {"View all available packages", "packages"}; + desc.add(packages); + String[] info = {"View package details", "info {num}"}; + desc.add(info); + String[] add = {"Add a new package", "add {package_name} {country} {duration} {price} {vacancies}"}; + desc.add(add); + String[] delete = {"Delete a package", "delete {num}"}; + desc.add(delete); + String[] reserve = {"Create a reservation for a package", "reserve {package_number} {contact_name} {contact_number} {number_pax}"}; + desc.add(reserve); + String[] remove = {"Remove a reservation", "remove {reservation_id}"}; + desc.add(remove); + String[] reservations = {"Shows all reservations for a package", "reservations {package_number}"}; + desc.add(reservations); + } + + public void printHelp(){ + for (String[] strings : desc) { + String foo = String.format("%-50s %s", strings[0], strings[1]); + System.out.println(foo); + } + } +} diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java new file mode 100644 index 0000000000..555d7eca87 --- /dev/null +++ b/src/main/java/seedu/duke/Packages.java @@ -0,0 +1,27 @@ +package seedu.duke; + +import java.util.ArrayList; + +public class Packages { + private ArrayList packages; + + public Packages(ArrayList packages) { + this.packages = packages; + } + + public int getSize() { + return packages.size(); + } + + public TravelPackage getPackage(int index) { + return packages.get(index); + } + + public void addPackage(TravelPackage newPackage) { + packages.add(newPackage); + } + + public void removePackage(int index) { + packages.remove(index); + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java new file mode 100644 index 0000000000..ff66fbf87c --- /dev/null +++ b/src/main/java/seedu/duke/Parser.java @@ -0,0 +1,48 @@ +package seedu.duke; + +import seedu.duke.command.*; + +public class Parser { + public static Command parse(String input) { + String[] inputArray = input.split(" "); + String commandType = inputArray[0]; + + int id, start, end, vacancies; + double price; + String name, hotel, country; + + switch (commandType) { + case "bye": + return new ByeCommand(); + case "add": + final int nameIndex = 1; + final int idIndex = 2; + final int startIndex = 3; + final int endIndex = 4; + final int hotelIndex = 5; + final int priceIndex = 6; + final int countryIndex = 7; + final int vacanciesIndex = 8; + name = inputArray[nameIndex]; + id = Integer.parseInt(inputArray[idIndex]); + start = Integer.parseInt(inputArray[startIndex]); + end = Integer.parseInt(inputArray[endIndex]); + hotel = inputArray[hotelIndex]; + price = Double.parseDouble(inputArray[priceIndex]); + country = inputArray[countryIndex]; + vacancies = Integer.parseInt(inputArray[vacanciesIndex]); + return new AddCommand(name, id, start, end, hotel, price, country, vacancies); + case "delete": + id = Integer.parseInt(inputArray[1]); + return new DeleteCommand(id); + case "packages": + return new PackagesCommand(); + + case "reserve": + case "reservations": + return new FindReservationsCommand(); + default: + return new ByeCommand(); + } + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/Reservation.java b/src/main/java/seedu/duke/Reservation.java new file mode 100644 index 0000000000..dfb563bb3e --- /dev/null +++ b/src/main/java/seedu/duke/Reservation.java @@ -0,0 +1,47 @@ +package seedu.duke; + +public class Reservation { + private int reservationID; + private String customerName; + private String contactNumber; + private int packageID; + private int numOfPax; + + public Reservation(int reservationID, int packageID, String customerName, String contactNumber, int numOfPax){ + this.reservationID = reservationID; + this.customerName = customerName; + this.contactNumber = contactNumber; + this.packageID = packageID; + this.numOfPax = numOfPax; + } + + public int getReservationID() { + return reservationID; + } + + public int getNumOfPax() { + return numOfPax; + } + + public int getPackageID() { + return packageID; + } + + public String getCustomerName() { + return customerName; + } + + public String getContactNumber() { + return contactNumber; + } + + @Override + public String toString() { + return "Reservation '" + getReservationID() + "'\n" + + "Package " + getPackageID() + "\n" + + "POC " + getCustomerName() + "\n" + + "Contact No. " + getContactNumber() + "\n" + + "Pax " + getNumOfPax() + "\n" + ; + } +} diff --git a/src/main/java/seedu/duke/Reservations.java b/src/main/java/seedu/duke/Reservations.java new file mode 100644 index 0000000000..25e42abe6f --- /dev/null +++ b/src/main/java/seedu/duke/Reservations.java @@ -0,0 +1,27 @@ +package seedu.duke; + +import java.util.ArrayList; + +public class Reservations { + private ArrayList reservations; + + public Reservations(ArrayList reservations) { + this.reservations = reservations; + } + + public int getSize() { + return reservations.size(); + } + + public Reservation getReservation(int index) { + return reservations.get(index); + } + + public void addReservation(Reservation newReservation) { + reservations.add(newReservation); + } + + public void removeReservation(int index) { + reservations.remove(index); + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java new file mode 100644 index 0000000000..7d012fe500 --- /dev/null +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -0,0 +1,49 @@ +package seedu.duke; +import java.util.Date; + +public class TravelPackage { + private String name; + private int id; + private Date[] period; //[startDate,endDate] + private String hotel; + private double price; + private String country; + private int maxParticipants; + private int numParticipants; + + public TravelPackage(String name, int id, Date startDate, Date endDate, String hotel, double price, String country, int maxParticipants) { + this.name = name; + this.id = id; + // this.period = [startDate,endDate]; + this.hotel = hotel; + this.price = price; + this.country = country; + this.maxParticipants = maxParticipants; + this.numParticipants = 0; + + } + + public boolean isFull() { + if (this.numParticipants < maxParticipants) { + return false; + } + else { + return true; + } + } + + public int getID() { + return this.id; + } + public String getName() { + return (this.country + " - " + this.name); + } + + public void printInfo() { + System.out.println("Here are the details for " + this.name + ", Travel Package ID of "+ this.id); + System.out.println("Country: "+ this.country); + System.out.println("Price: " + this.price); + System.out.println("Hotel: " + this.hotel); + } + +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java new file mode 100644 index 0000000000..3b51acf8d9 --- /dev/null +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -0,0 +1,22 @@ +package seedu.duke.command; + +import java.util.Date; +import seedu.duke.Packages; +import seedu.duke.TravelPackage; + + +public class AddCommand extends Command { + private TravelPackage newPackage; + + public AddCommand(String name, int id, int date1, int date2, String hotel, double price, String country, + int maxVacancies) { + super(false); + this.newPackage = new TravelPackage(name, id, new Date(date1), new Date(date2), hotel, price, country, + maxVacancies); + } + + public void execute(Packages packages) { + packages.addPackage(newPackage); + } + +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/AddReservationCommand.java b/src/main/java/seedu/duke/command/AddReservationCommand.java new file mode 100644 index 0000000000..30feded0fc --- /dev/null +++ b/src/main/java/seedu/duke/command/AddReservationCommand.java @@ -0,0 +1,19 @@ +//package seedu.duke.command; +// +//import seedu.duke.Reservations; +//import seedu.duke.Reservation; +// +// +//public class AddReservationCommand extends ReservationCommand { +// private Reservation newReservation; +// +// public AddReservationCommand(int reservationID, int packageID, String customerName, String contactNumber, int numOfPax) { +// super(false); +// this.newReservation = new Reservation(reservationID, packageID, customerName, contactNumber, numOfPax); +// } +// +// public void execute(Reservations reservations) { +// reservations.addReservation(newReservation); +// } +// +//} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/ByeCommand.java b/src/main/java/seedu/duke/command/ByeCommand.java new file mode 100644 index 0000000000..08a6ff790f --- /dev/null +++ b/src/main/java/seedu/duke/command/ByeCommand.java @@ -0,0 +1,15 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + + +public class ByeCommand extends Command { + public ByeCommand() { + super(true); + } + + public void execute(Packages packages) { + System.out.println("Thank you for using TARBS. See you again!"); + } + +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/Command.java b/src/main/java/seedu/duke/command/Command.java new file mode 100644 index 0000000000..25b472790c --- /dev/null +++ b/src/main/java/seedu/duke/command/Command.java @@ -0,0 +1,23 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + + +public abstract class Command { + private boolean isExit; + + public Command(boolean isExit) { + this.isExit = isExit; + } + + public boolean getIsExit() { + return this.isExit; + } + + public void setIsExit(boolean isExit) { + this.isExit = isExit; + } + + public abstract void execute(Packages packages); + +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/DeleteCommand.java b/src/main/java/seedu/duke/command/DeleteCommand.java new file mode 100644 index 0000000000..49e36e424e --- /dev/null +++ b/src/main/java/seedu/duke/command/DeleteCommand.java @@ -0,0 +1,22 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + + +public class DeleteCommand extends Command { + private int id; + + public DeleteCommand(int id) { + super(false); + this.id = id; + } + + public void execute(Packages packages) { + for (int i = 0; i < packages.getSize(); i++) { + if (packages.getPackage(i).getID() == id) { + packages.removePackage(i); + break; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/DeleteReservationCommand.java b/src/main/java/seedu/duke/command/DeleteReservationCommand.java new file mode 100644 index 0000000000..3ce5e60e23 --- /dev/null +++ b/src/main/java/seedu/duke/command/DeleteReservationCommand.java @@ -0,0 +1,22 @@ +//package seedu.duke.command; +//import seedu.duke.Reservations; +//import seedu.duke.Reservation; +// +// +//public class DeleteReservationCommand extends ReservationCommand { +// private int id; +// +// public DeleteReservationCommand(int id) { +// super(false); +// this.id = id; +// +// +// public void execute(Reservations reservations) { +// for (int i = 0; i < reservations.getSize(); i++) { +// if (reservations.getReservation(i).getReservationID() == id) { +// reservations.removeReservation(i); +// break; +// } +// } +// } +//} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/FindReservationsCommand.java b/src/main/java/seedu/duke/command/FindReservationsCommand.java new file mode 100644 index 0000000000..3a34e6d9ec --- /dev/null +++ b/src/main/java/seedu/duke/command/FindReservationsCommand.java @@ -0,0 +1,16 @@ +//package seedu.duke.command; +// +//import seedu.duke.Reservations; +// +// +//public class FindReservationsCommand extends ReservationCommand { +// public FindReservationsCommand() { +// super(false); +// } +// +// public void execute(Reservations reservations) { +// for (int i = 0; i < reservations.getSize(); i++) { +// reservations.getReservation(i).toString(); +// } +// } +//} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java new file mode 100644 index 0000000000..8f6bd4dd7a --- /dev/null +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -0,0 +1,16 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + + +public class PackagesCommand extends Command { + public PackagesCommand() { + super(false); + } + + public void execute(Packages packages) { + for (int i = 0; i < packages.getSize(); i++) { + packages.getPackage(i).printInfo(); + } + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java new file mode 100644 index 0000000000..f3699b828c --- /dev/null +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -0,0 +1,22 @@ +//package seedu.duke.command; +//import seedu.duke.Packages; +//import seedu.duke.Reservations; +//public abstract class ReservationCommand { +// +// private boolean isExit; +// +// public ReservationCommand(boolean isExit) { +// this.isExit = isExit; +// } +// +// public boolean getIsExit() { +// return this.isExit; +// } +// +// public void setIsExit(boolean isExit) { +// this.isExit = isExit; +// } +// +// public abstract void execute(Reservations reservations); +// +//} From 146fd7cd479a1e0db5b30f34d5ce54104e65fc9f Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 11 Mar 2022 10:14:53 +0800 Subject: [PATCH 009/131] v1.0 - Some bugs --- docs/AboutUs.md | 4 ++-- .../java/seedu/duke/command/DeleteReservationCommand.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 2e431cc3a1..c4f0068c50 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -5,5 +5,5 @@ Display | Name | Github Profile | Portfolio ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang| [Github](https://github.com/timchang27) | [Portfolio](docs/team/timothy.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) diff --git a/src/main/java/seedu/duke/command/DeleteReservationCommand.java b/src/main/java/seedu/duke/command/DeleteReservationCommand.java index 3ce5e60e23..d09709008c 100644 --- a/src/main/java/seedu/duke/command/DeleteReservationCommand.java +++ b/src/main/java/seedu/duke/command/DeleteReservationCommand.java @@ -9,7 +9,7 @@ // public DeleteReservationCommand(int id) { // super(false); // this.id = id; -// +// // // public void execute(Reservations reservations) { // for (int i = 0; i < reservations.getSize(); i++) { From 914229162ac6f38f667499874d172c9669fa117e Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 11 Mar 2022 10:17:32 +0800 Subject: [PATCH 010/131] v1.0 - Some bugs --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index c4f0068c50..b3197ceb95 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -6,4 +6,4 @@ Display | Name | Github Profile | Portfolio ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang| [Github](https://github.com/timchang27) | [Portfolio](docs/team/timothy.md) ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) +![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) From aa628d020bc7fcff73236efc93586f9c2b0275db Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 11 Mar 2022 10:36:42 +0800 Subject: [PATCH 011/131] v1.0 - Some bugs --- src/main/java/seedu/duke/Parser.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index ff66fbf87c..04d14e1819 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -37,10 +37,6 @@ public static Command parse(String input) { return new DeleteCommand(id); case "packages": return new PackagesCommand(); - - case "reserve": - case "reservations": - return new FindReservationsCommand(); default: return new ByeCommand(); } From 66bf2493caa6ee6642af70a51307c340baf54952 Mon Sep 17 00:00:00 2001 From: chintaiann Date: Thu, 17 Mar 2022 22:22:07 +0800 Subject: [PATCH 012/131] v1.0 1. added Reservation class 2. added Reservation arraylist to packages 3. ErrorCommand and ReservationCommand added --- src/main/java/seedu/duke/Duke.java | 3 +- src/main/java/seedu/duke/Packages.java | 24 ++++- src/main/java/seedu/duke/Parser.java | 9 +- src/main/java/seedu/duke/Reservation.java | 47 ++++++++++ .../java/seedu/duke/command/ErrorCommand.java | 19 ++++ .../duke/command/ReservationCommand.java | 92 +++++++++++++++++++ 6 files changed, 189 insertions(+), 5 deletions(-) create mode 100644 src/main/java/seedu/duke/Reservation.java create mode 100644 src/main/java/seedu/duke/command/ErrorCommand.java create mode 100644 src/main/java/seedu/duke/command/ReservationCommand.java diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index d76f26a4ef..fb5aa5c08b 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -15,7 +15,8 @@ public Duke() { ArrayList temp = new ArrayList<>(); temp.add(new TravelPackage("Experience Korea!", 1, new Date(25032021), new Date(28032021), "Four Seasons", 500.25, "Korea", 20)); - packages = new Packages(temp); + ArrayList temp2 = new ArrayList<>(); + packages = new Packages(temp,temp2); } public static void main(String[] args) { diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index 79af75fce9..b75e69d27b 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -1,12 +1,14 @@ package seedu.duke; import java.util.ArrayList; - +//Packages include arrayList packages to hold all TravelPackages public class Packages { private ArrayList packages; + private ArrayList reservations; - public Packages(ArrayList packages) { + public Packages(ArrayList packages, ArrayList reservations) { this.packages = packages; + this.reservations = reservations; } public int getSize() { @@ -24,4 +26,22 @@ public void addPackage(TravelPackage newPackage) { public void removePackage(int index) { packages.remove(index); } + + public Reservation getReservation(int index){ + return reservations.get(index); + } + + public int getReservationSize() { + return reservations.size(); + } + + public void addReservation(Reservation newReservation) { + reservations.add(newReservation); + System.out.println("RESERVATION ADDED"); + + } + + public void removeReservation(int index) { + reservations.remove(index); + } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 0c28a9027b..91c1fd7e8f 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -5,6 +5,8 @@ import seedu.duke.command.Command; import seedu.duke.command.DeleteCommand; import seedu.duke.command.PackagesCommand; +import seedu.duke.command.ErrorCommand; +import seedu.duke.command.ReservationCommand; public class Parser { public static Command parse(String input) { @@ -18,7 +20,8 @@ public static Command parse(String input) { switch (commandType) { case "bye": return new ByeCommand(); - case "add": + + case "add": //only can have spaces between variables - what if hotel has 2 words? final int nameIndex = 1; final int idIndex = 2; final int startIndex = 3; @@ -41,8 +44,10 @@ public static Command parse(String input) { return new DeleteCommand(id); case "packages": return new PackagesCommand(); + case "reservation": + return new ReservationCommand(); default: - return new ByeCommand(); + return new ErrorCommand(input); } } } diff --git a/src/main/java/seedu/duke/Reservation.java b/src/main/java/seedu/duke/Reservation.java new file mode 100644 index 0000000000..dfb563bb3e --- /dev/null +++ b/src/main/java/seedu/duke/Reservation.java @@ -0,0 +1,47 @@ +package seedu.duke; + +public class Reservation { + private int reservationID; + private String customerName; + private String contactNumber; + private int packageID; + private int numOfPax; + + public Reservation(int reservationID, int packageID, String customerName, String contactNumber, int numOfPax){ + this.reservationID = reservationID; + this.customerName = customerName; + this.contactNumber = contactNumber; + this.packageID = packageID; + this.numOfPax = numOfPax; + } + + public int getReservationID() { + return reservationID; + } + + public int getNumOfPax() { + return numOfPax; + } + + public int getPackageID() { + return packageID; + } + + public String getCustomerName() { + return customerName; + } + + public String getContactNumber() { + return contactNumber; + } + + @Override + public String toString() { + return "Reservation '" + getReservationID() + "'\n" + + "Package " + getPackageID() + "\n" + + "POC " + getCustomerName() + "\n" + + "Contact No. " + getContactNumber() + "\n" + + "Pax " + getNumOfPax() + "\n" + ; + } +} diff --git a/src/main/java/seedu/duke/command/ErrorCommand.java b/src/main/java/seedu/duke/command/ErrorCommand.java new file mode 100644 index 0000000000..6b3f2ab96c --- /dev/null +++ b/src/main/java/seedu/duke/command/ErrorCommand.java @@ -0,0 +1,19 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public class ErrorCommand extends Command{ + private String input; + + public ErrorCommand(String input) { + super(false); + this.input = input; + } + + public void execute(Packages packages) { + System.out.println("Input not recognized: " + this.input); + System.out.println("Use the help command to find out the valid commands."); + + } + +} diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java new file mode 100644 index 0000000000..91731d3643 --- /dev/null +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -0,0 +1,92 @@ +package seedu.duke.command; + +import seedu.duke.Packages; +import seedu.duke.Reservation; + +import java.util.Scanner; + +public class ReservationCommand extends Command{ + public ReservationCommand() { + super(false); + } + + + public void execute(Packages packages) { + Scanner s = new Scanner(System.in); + System.out.println("Please choose which function you would like to perform for Reservations."); + System.out.println("1. Add Reservation"); + System.out.println("2. Remove Reservation"); + System.out.println("3. Check Reservations"); + int choice = Integer.parseInt(s.nextLine()); + + if (choice == 1) { + addReservation(packages); + } + + else if (choice == 2) { + deleteReservation(packages); + } + + else if (choice ==3) { + printReservation(packages); + } + else { + System.out.println("Please only enter numbers 1-3!"); + + } + } + + public void printReservation(Packages packages){ + Scanner sc = new Scanner(System.in); + System.out.println("Enter Reservation ID to check details: "); + int index = sc.nextInt(); + boolean reservationFound = false; + for (int i = 0; i < packages.getReservationSize(); i++) { + if (packages.getReservation(i).getReservationID() == index) { + System.out.println(packages.getReservation(i).toString()); + reservationFound = true; + break; + }} + if (!reservationFound) { + System.out.println("Reservation ID could not be found. Please try again with a valid ID."); + } + } + + public void addReservation(Packages packages){ + Scanner c = new Scanner(System.in); + System.out.println("Enter reservation ID: "); + int rid = Integer.parseInt(c.nextLine()); + System.out.println("Enter customer name: "); + String name = c.nextLine(); + System.out.println("Enter mobile number: "); + String number = c.nextLine(); + System.out.println("Enter Travel Package ID: "); + int tid = Integer.parseInt(c.nextLine()); + System.out.println("Enter number of pax: "); + int pax = Integer.parseInt(c.nextLine()); + + + packages.addReservation(new Reservation(rid,tid,name,number,pax)); + } + + public void deleteReservation(Packages packages){ + Scanner p = new Scanner(System.in); + System.out.println("Please enter the reservation ID to be deleted: "); + int index = p.nextInt(); + boolean deletionFound = false; + for (int i = 0; i < packages.getReservationSize(); i++) { + if (packages.getReservation(i).getReservationID() == index) { + System.out.println("Deleting Reservation"); + packages.removeReservation(i); + deletionFound = true; + break; + } + } + + if (!deletionFound) { + System.out.println("Reservation ID could not be found. Please try again with a valid ID."); + } + + + } +} From ba42c739ec78e6d175978d22e2c6711080d5aa34 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Fri, 18 Mar 2022 01:33:47 +0800 Subject: [PATCH 013/131] make general revision --- docs/AboutUs.md | 14 ++--- docs/team/ege.md | 0 src/main/java/seedu/duke/Duke.java | 25 ++------- src/main/java/seedu/duke/Packages.java | 8 +-- src/main/java/seedu/duke/Parser.java | 21 ++++---- src/main/java/seedu/duke/Reservation.java | 14 ++--- src/main/java/seedu/duke/TravelPackage.java | 45 +++++++--------- .../java/seedu/duke/command/AddCommand.java | 5 +- .../java/seedu/duke/command/ByeCommand.java | 2 +- src/main/java/seedu/duke/command/Command.java | 6 +-- .../seedu/duke/command/DeleteCommand.java | 10 ++-- .../java/seedu/duke/command/ErrorCommand.java | 1 - .../seedu/duke/command/PackagesCommand.java | 6 +-- .../duke/command/ReservationCommand.java | 34 ++++-------- text-ui-test/EXPECTED.TXT | 52 ++++++++++++++++--- text-ui-test/input.txt | 14 ++++- 16 files changed, 130 insertions(+), 127 deletions(-) create mode 100644 docs/team/ege.md diff --git a/docs/AboutUs.md b/docs/AboutUs.md index a8a1ed8d8d..88d7d00edb 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -| Display | Name | Github Profile | Portfolio | -| --------------------------------------------------- | :---------: | :--------------------------------: | :-------------------------------: | -| ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) | +| Display | Name | Github Profile | Portfolio | +| --------------------------------------------------- |:---------------:|:-----------------------------------------:| :-------------------------------: | +| ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) | diff --git a/docs/team/ege.md b/docs/team/ege.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index fb5aa5c08b..a3138b0d01 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -1,36 +1,21 @@ package seedu.duke; import java.util.ArrayList; -import java.util.Date; import java.util.Scanner; import seedu.duke.command.Command; public class Duke { - private Packages packages; - - // public TravelPackage(String name, int id, Date startDate, Date endDate, - // String hotel, double price, String country, int maxParticipants) { - public Duke() { - ArrayList temp = new ArrayList<>(); - temp.add(new TravelPackage("Experience Korea!", 1, new Date(25032021), new Date(28032021), "Four Seasons", - 500.25, "Korea", 20)); - ArrayList temp2 = new ArrayList<>(); - packages = new Packages(temp,temp2); - } - public static void main(String[] args) { - Duke duke = new Duke(); - duke.run(); + run(); } - public void run() { - + public static void run() { + Packages packages = new Packages(); boolean endProgram = false; - System.out.print("Welcome to Travel Agency Booking Reservation System!"); - + System.out.println("Welcome to Travel Agency Booking Reservation System!"); + Scanner sc = new Scanner(System.in); while (!endProgram) { - Scanner sc = new Scanner(System.in); System.out.println("Please enter command: "); Command command = Parser.parse(sc.nextLine()); command.execute(packages); diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index b75e69d27b..7ce1c4a79c 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -6,9 +6,9 @@ public class Packages { private ArrayList packages; private ArrayList reservations; - public Packages(ArrayList packages, ArrayList reservations) { - this.packages = packages; - this.reservations = reservations; + public Packages() { + packages = new ArrayList<>(); + reservations = new ArrayList<>(); } public int getSize() { @@ -44,4 +44,4 @@ public void addReservation(Reservation newReservation) { public void removeReservation(int index) { reservations.remove(index); } -} +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 91c1fd7e8f..b66f3dca20 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -13,7 +13,8 @@ public static Command parse(String input) { String[] inputArray = input.split(" "); String commandType = inputArray[0]; - int id, start, end, vacancies; + String id; + int start, end, vacancies; double price; String name, hotel, country; @@ -23,24 +24,22 @@ public static Command parse(String input) { case "add": //only can have spaces between variables - what if hotel has 2 words? final int nameIndex = 1; - final int idIndex = 2; - final int startIndex = 3; - final int endIndex = 4; - final int hotelIndex = 5; - final int priceIndex = 6; - final int countryIndex = 7; - final int vacanciesIndex = 8; + final int startIndex = 2; + final int endIndex = 3; + final int hotelIndex = 4; + final int priceIndex = 5; + final int countryIndex = 6; + final int vacanciesIndex = 7; name = inputArray[nameIndex]; - id = Integer.parseInt(inputArray[idIndex]); start = Integer.parseInt(inputArray[startIndex]); end = Integer.parseInt(inputArray[endIndex]); hotel = inputArray[hotelIndex]; price = Double.parseDouble(inputArray[priceIndex]); country = inputArray[countryIndex]; vacancies = Integer.parseInt(inputArray[vacanciesIndex]); - return new AddCommand(name, id, start, end, hotel, price, country, vacancies); + return new AddCommand(name, start, end, hotel, price, country, vacancies); case "delete": - id = Integer.parseInt(inputArray[1]); + id = inputArray[1]; return new DeleteCommand(id); case "packages": return new PackagesCommand(); diff --git a/src/main/java/seedu/duke/Reservation.java b/src/main/java/seedu/duke/Reservation.java index dfb563bb3e..336523764d 100644 --- a/src/main/java/seedu/duke/Reservation.java +++ b/src/main/java/seedu/duke/Reservation.java @@ -1,13 +1,13 @@ package seedu.duke; public class Reservation { - private int reservationID; - private String customerName; - private String contactNumber; - private int packageID; - private int numOfPax; + private final int reservationID; + private final String customerName; + private final String contactNumber; + private final String packageID; + private final int numOfPax; - public Reservation(int reservationID, int packageID, String customerName, String contactNumber, int numOfPax){ + public Reservation(int reservationID, String packageID, String customerName, String contactNumber, int numOfPax){ this.reservationID = reservationID; this.customerName = customerName; this.contactNumber = contactNumber; @@ -23,7 +23,7 @@ public int getNumOfPax() { return numOfPax; } - public int getPackageID() { + public String getPackageID() { return packageID; } diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index aa16a2248f..bfb6fdcd6d 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -2,47 +2,40 @@ import java.util.Date; public class TravelPackage { - private String name; - private int id; + private final String name; + private static int nextId = 1; + private final int id; private Date[] period; //[startDate,endDate] - private String hotel; - private double price; - private String country; - private int maxParticipants; - private int numParticipants; + private final String hotel; + private final double price; + private final String country; + private final int maxParticipants; + private final int numParticipants; - public TravelPackage(String name, int id, Date startDate, Date endDate, String hotel, double price, String country, int maxParticipants) { + public TravelPackage(String name, Date startDate, Date endDate, String hotel, double price, String country, int maxParticipants) { this.name = name; - this.id = id; // this.period = [startDate,endDate]; this.hotel = hotel; this.price = price; this.country = country; this.maxParticipants = maxParticipants; - this.numParticipants = 0; - + this.numParticipants = 0; + id = nextId++; } - public boolean isFull() { - if (this.numParticipants < maxParticipants) { - return false; - } - else { - return true; - } + public boolean isFull() { + return this.numParticipants >= maxParticipants; } - public int getID() { - return this.id; + public String getID() { + return "P" + this.id; } - - public void printInfo() { - System.out.println("Here are the details for " + this.name + ", Travel Package ID of "+ this.id); - System.out.println("Country: "+ this.country); - System.out.println("Price: " + this.price); - System.out.println("Hotel: " + this.hotel); + + public String toString() { + return "Here are the details for " + this.name + ", Travel Package ID of " + this.getID() + "\nCountry: "+ this.country + "\nPrice: " + this.price + "\nHotel: " + this.hotel; } + diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java index 31b185badb..1709a0efe5 100644 --- a/src/main/java/seedu/duke/command/AddCommand.java +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -8,10 +8,9 @@ public class AddCommand extends Command { private TravelPackage newPackage; - public AddCommand(String name, int id, int date1, int date2, String hotel, double price, String country, + public AddCommand(String name, int date1, int date2, String hotel, double price, String country, int maxVacancies) { - super(false); - this.newPackage = new TravelPackage(name, id, new Date(date1), new Date(date2), hotel, price, country, + this.newPackage = new TravelPackage(name, new Date(date1), new Date(date2), hotel, price, country, maxVacancies); } diff --git a/src/main/java/seedu/duke/command/ByeCommand.java b/src/main/java/seedu/duke/command/ByeCommand.java index e2f249cfbe..c8fb168640 100644 --- a/src/main/java/seedu/duke/command/ByeCommand.java +++ b/src/main/java/seedu/duke/command/ByeCommand.java @@ -4,7 +4,7 @@ public class ByeCommand extends Command { public ByeCommand() { - super(true); + setIsExit(true); } public void execute(Packages packages) { diff --git a/src/main/java/seedu/duke/command/Command.java b/src/main/java/seedu/duke/command/Command.java index ab105284df..63cfac6c1c 100644 --- a/src/main/java/seedu/duke/command/Command.java +++ b/src/main/java/seedu/duke/command/Command.java @@ -3,11 +3,7 @@ import seedu.duke.Packages; public abstract class Command { - private boolean isExit; - - public Command(boolean isExit) { - this.isExit = isExit; - } + private boolean isExit = false; public boolean getIsExit() { return this.isExit; diff --git a/src/main/java/seedu/duke/command/DeleteCommand.java b/src/main/java/seedu/duke/command/DeleteCommand.java index 355a887510..6b43838fa8 100644 --- a/src/main/java/seedu/duke/command/DeleteCommand.java +++ b/src/main/java/seedu/duke/command/DeleteCommand.java @@ -3,16 +3,16 @@ import seedu.duke.Packages; public class DeleteCommand extends Command { - private int id; + private final String id; - public DeleteCommand(int id) { - super(false); + public DeleteCommand(String id) { this.id = id; } public void execute(Packages packages) { - for (int i = 0; i < packages.getSize(); i++) { - if (packages.getPackage(i).getID() == id) { + int numberOfPackages = packages.getSize(); + for (int i = 0; i < numberOfPackages; i++) { + if (packages.getPackage(i).getID().equals(id)) { packages.removePackage(i); break; } diff --git a/src/main/java/seedu/duke/command/ErrorCommand.java b/src/main/java/seedu/duke/command/ErrorCommand.java index 6b3f2ab96c..545f54ee1f 100644 --- a/src/main/java/seedu/duke/command/ErrorCommand.java +++ b/src/main/java/seedu/duke/command/ErrorCommand.java @@ -6,7 +6,6 @@ public class ErrorCommand extends Command{ private String input; public ErrorCommand(String input) { - super(false); this.input = input; } diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index 0d50866eba..eff33ef580 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -3,13 +3,9 @@ import seedu.duke.Packages; public class PackagesCommand extends Command { - public PackagesCommand() { - super(false); - } - public void execute(Packages packages) { for (int i = 0; i < packages.getSize(); i++) { - packages.getPackage(i).printInfo(); + System.out.println(packages.getPackage(i)); } } } diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java index 91731d3643..e6570b9fda 100644 --- a/src/main/java/seedu/duke/command/ReservationCommand.java +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -2,15 +2,9 @@ import seedu.duke.Packages; import seedu.duke.Reservation; - import java.util.Scanner; public class ReservationCommand extends Command{ - public ReservationCommand() { - super(false); - } - - public void execute(Packages packages) { Scanner s = new Scanner(System.in); System.out.println("Please choose which function you would like to perform for Reservations."); @@ -18,21 +12,18 @@ public void execute(Packages packages) { System.out.println("2. Remove Reservation"); System.out.println("3. Check Reservations"); int choice = Integer.parseInt(s.nextLine()); - - if (choice == 1) { + switch (choice) { + case 1: addReservation(packages); - } - - else if (choice == 2) { + return; + case 2: deleteReservation(packages); - } - - else if (choice ==3) { + return; + case 3: printReservation(packages); - } - else { + return; + default: System.out.println("Please only enter numbers 1-3!"); - } } @@ -43,7 +34,7 @@ public void printReservation(Packages packages){ boolean reservationFound = false; for (int i = 0; i < packages.getReservationSize(); i++) { if (packages.getReservation(i).getReservationID() == index) { - System.out.println(packages.getReservation(i).toString()); + System.out.println(packages.getReservation(i)); reservationFound = true; break; }} @@ -61,12 +52,11 @@ public void addReservation(Packages packages){ System.out.println("Enter mobile number: "); String number = c.nextLine(); System.out.println("Enter Travel Package ID: "); - int tid = Integer.parseInt(c.nextLine()); + String tid = c.nextLine(); System.out.println("Enter number of pax: "); int pax = Integer.parseInt(c.nextLine()); - - packages.addReservation(new Reservation(rid,tid,name,number,pax)); + packages.addReservation(new Reservation(rid, tid, name, number, pax)); } public void deleteReservation(Packages packages){ @@ -86,7 +76,5 @@ public void deleteReservation(Packages packages){ if (!deletionFound) { System.out.println("Reservation ID could not be found. Please try again with a valid ID."); } - - } } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 892cb6cae7..d75ac0e9ef 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,9 +1,45 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| +Welcome to Travel Agency Booking Reservation System! +Please enter command: +add Skiing 10 20 Hilton 1000 Switzerland 500 +Please enter command: +packages +Here are the details for Skiing, Travel Package ID of P1 +Country: Switzerland +Price: 1000.0 +Hotel: Hilton +Please enter command: +reservation +Please choose which function you would like to perform for Reservations. +1. Add Reservation +2. Remove Reservation +3. Check Reservations +1 +Enter reservation ID: +1 +Enter customer name: +John +Enter mobile number: +83232321 +Enter Travel Package ID: +P1 +Enter number of pax: +5 +RESERVATION ADDED +Please enter command: +reservation +Please choose which function you would like to perform for Reservations. +1. Add Reservation +2. Remove Reservation +3. Check Reservations +3 +Enter Reservation ID to check details: +1 +Reservation '1' +Package P1 +POC John +Contact No. 83232321 +Pax 5 -What is your name? -Hello James Gosling +Please enter command: +bye +Thank you for using TARBS. See you again! diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index f6ec2e9f95..535d4ecf9d 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +1,13 @@ -James Gosling \ No newline at end of file +add Skiing 10 20 Hilton 1000 Switzerland 500 +packages +reservation +1 +1 +John +83232321 +P1 +5 +reservation +3 +1 +bye \ No newline at end of file From 40314b793150bf0e309e59c40c52b63fb2669c64 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Fri, 18 Mar 2022 01:49:15 +0800 Subject: [PATCH 014/131] revise the style --- src/main/java/seedu/duke/Packages.java | 3 ++- src/main/java/seedu/duke/Parser.java | 8 +++++-- src/main/java/seedu/duke/Reservation.java | 13 ++++++------ src/main/java/seedu/duke/TravelPackage.java | 11 ++++++++-- .../java/seedu/duke/command/ErrorCommand.java | 5 ++--- .../duke/command/ReservationCommand.java | 21 ++++++++++--------- 6 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index 7ce1c4a79c..4b830c3e68 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -2,6 +2,7 @@ import java.util.ArrayList; //Packages include arrayList packages to hold all TravelPackages + public class Packages { private ArrayList packages; private ArrayList reservations; @@ -27,7 +28,7 @@ public void removePackage(int index) { packages.remove(index); } - public Reservation getReservation(int index){ + public Reservation getReservation(int index) { return reservations.get(index); } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index b66f3dca20..49c4993d72 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -14,9 +14,13 @@ public static Command parse(String input) { String commandType = inputArray[0]; String id; - int start, end, vacancies; + int start; + int end; + int vacancies; double price; - String name, hotel, country; + String name; + String hotel; + String country; switch (commandType) { case "bye": diff --git a/src/main/java/seedu/duke/Reservation.java b/src/main/java/seedu/duke/Reservation.java index 336523764d..7216292886 100644 --- a/src/main/java/seedu/duke/Reservation.java +++ b/src/main/java/seedu/duke/Reservation.java @@ -7,7 +7,7 @@ public class Reservation { private final String packageID; private final int numOfPax; - public Reservation(int reservationID, String packageID, String customerName, String contactNumber, int numOfPax){ + public Reservation(int reservationID, String packageID, String customerName, String contactNumber, int numOfPax) { this.reservationID = reservationID; this.customerName = customerName; this.contactNumber = contactNumber; @@ -37,11 +37,10 @@ public String getContactNumber() { @Override public String toString() { - return "Reservation '" + getReservationID() + "'\n" + - "Package " + getPackageID() + "\n" + - "POC " + getCustomerName() + "\n" + - "Contact No. " + getContactNumber() + "\n" + - "Pax " + getNumOfPax() + "\n" - ; + return "Reservation '" + getReservationID() + "'\n" + + "Package " + getPackageID() + "\n" + + "POC " + getCustomerName() + "\n" + + "Contact No. " + getContactNumber() + "\n" + + "Pax " + getNumOfPax() + "\n"; } } diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index bfb6fdcd6d..8ff8bc2c0b 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -1,4 +1,5 @@ package seedu.duke; + import java.util.Date; public class TravelPackage { @@ -12,7 +13,8 @@ public class TravelPackage { private final int maxParticipants; private final int numParticipants; - public TravelPackage(String name, Date startDate, Date endDate, String hotel, double price, String country, int maxParticipants) { + public TravelPackage(String name, Date startDate, Date endDate, + String hotel, double price, String country, int maxParticipants) { this.name = name; // this.period = [startDate,endDate]; this.hotel = hotel; @@ -32,7 +34,12 @@ public String getID() { } public String toString() { - return "Here are the details for " + this.name + ", Travel Package ID of " + this.getID() + "\nCountry: "+ this.country + "\nPrice: " + this.price + "\nHotel: " + this.hotel; + return "Here are the details for " + + this.name + ", Travel Package ID of " + + this.getID() + "\nCountry: " + + this.country + "\nPrice: " + + this.price + "\nHotel: " + + this.hotel; } diff --git a/src/main/java/seedu/duke/command/ErrorCommand.java b/src/main/java/seedu/duke/command/ErrorCommand.java index 545f54ee1f..ce4e4961d2 100644 --- a/src/main/java/seedu/duke/command/ErrorCommand.java +++ b/src/main/java/seedu/duke/command/ErrorCommand.java @@ -2,10 +2,10 @@ import seedu.duke.Packages; -public class ErrorCommand extends Command{ +public class ErrorCommand extends Command { private String input; - public ErrorCommand(String input) { + public ErrorCommand(String input) { this.input = input; } @@ -14,5 +14,4 @@ public void execute(Packages packages) { System.out.println("Use the help command to find out the valid commands."); } - } diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java index e6570b9fda..0d2feeb96a 100644 --- a/src/main/java/seedu/duke/command/ReservationCommand.java +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -4,7 +4,7 @@ import seedu.duke.Reservation; import java.util.Scanner; -public class ReservationCommand extends Command{ +public class ReservationCommand extends Command { public void execute(Packages packages) { Scanner s = new Scanner(System.in); System.out.println("Please choose which function you would like to perform for Reservations."); @@ -27,7 +27,7 @@ public void execute(Packages packages) { } } - public void printReservation(Packages packages){ + public void printReservation(Packages packages) { Scanner sc = new Scanner(System.in); System.out.println("Enter Reservation ID to check details: "); int index = sc.nextInt(); @@ -37,29 +37,30 @@ public void printReservation(Packages packages){ System.out.println(packages.getReservation(i)); reservationFound = true; break; - }} + } + } if (!reservationFound) { System.out.println("Reservation ID could not be found. Please try again with a valid ID."); } } - public void addReservation(Packages packages){ + public void addReservation(Packages packages) { Scanner c = new Scanner(System.in); System.out.println("Enter reservation ID: "); - int rid = Integer.parseInt(c.nextLine()); + final int rid = Integer.parseInt(c.nextLine()); System.out.println("Enter customer name: "); - String name = c.nextLine(); + final String name = c.nextLine(); System.out.println("Enter mobile number: "); - String number = c.nextLine(); + final String number = c.nextLine(); System.out.println("Enter Travel Package ID: "); - String tid = c.nextLine(); + final String tid = c.nextLine(); System.out.println("Enter number of pax: "); - int pax = Integer.parseInt(c.nextLine()); + final int pax = Integer.parseInt(c.nextLine()); packages.addReservation(new Reservation(rid, tid, name, number, pax)); } - public void deleteReservation(Packages packages){ + public void deleteReservation(Packages packages) { Scanner p = new Scanner(System.in); System.out.println("Please enter the reservation ID to be deleted: "); int index = p.nextInt(); From 5932e943889eec03478f9615bf6600678717ac42 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Fri, 18 Mar 2022 01:52:59 +0800 Subject: [PATCH 015/131] revise the style --- text-ui-test/EXPECTED.TXT | 45 --------------------------------------- text-ui-test/input.txt | 13 ----------- 2 files changed, 58 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index d75ac0e9ef..e69de29bb2 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,45 +0,0 @@ -Welcome to Travel Agency Booking Reservation System! -Please enter command: -add Skiing 10 20 Hilton 1000 Switzerland 500 -Please enter command: -packages -Here are the details for Skiing, Travel Package ID of P1 -Country: Switzerland -Price: 1000.0 -Hotel: Hilton -Please enter command: -reservation -Please choose which function you would like to perform for Reservations. -1. Add Reservation -2. Remove Reservation -3. Check Reservations -1 -Enter reservation ID: -1 -Enter customer name: -John -Enter mobile number: -83232321 -Enter Travel Package ID: -P1 -Enter number of pax: -5 -RESERVATION ADDED -Please enter command: -reservation -Please choose which function you would like to perform for Reservations. -1. Add Reservation -2. Remove Reservation -3. Check Reservations -3 -Enter Reservation ID to check details: -1 -Reservation '1' -Package P1 -POC John -Contact No. 83232321 -Pax 5 - -Please enter command: -bye -Thank you for using TARBS. See you again! diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index 535d4ecf9d..e69de29bb2 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,13 +0,0 @@ -add Skiing 10 20 Hilton 1000 Switzerland 500 -packages -reservation -1 -1 -John -83232321 -P1 -5 -reservation -3 -1 -bye \ No newline at end of file From 2b759a9e22ba41dcdfa6fce12c67d18c7ba9c73f Mon Sep 17 00:00:00 2001 From: mafpovbul Date: Thu, 24 Mar 2022 22:14:30 +0800 Subject: [PATCH 016/131] Added storage --- packages.txt | 1 + reservations.txt | 1 + src/main/java/seedu/duke/Duke.java | 5 +- src/main/java/seedu/duke/Reservation.java | 4 + src/main/java/seedu/duke/Storage.java | 109 ++++++++++++++++++++ src/main/java/seedu/duke/TravelPackage.java | 5 + 6 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 packages.txt create mode 100644 reservations.txt create mode 100644 src/main/java/seedu/duke/Storage.java diff --git a/packages.txt b/packages.txt new file mode 100644 index 0000000000..8286425097 --- /dev/null +++ b/packages.txt @@ -0,0 +1 @@ +mugg | 2 | 1 | mariott | 50.0 | korea | 30 | 0 diff --git a/reservations.txt b/reservations.txt new file mode 100644 index 0000000000..7ce14e09ba --- /dev/null +++ b/reservations.txt @@ -0,0 +1 @@ +1 | 123 | 1 | bawj | 2 diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index a3138b0d01..8137dd0a3e 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -11,7 +11,8 @@ public static void main(String[] args) { } public static void run() { - Packages packages = new Packages(); + Storage storage = new Storage("packages.txt", "reservations.txt"); + Packages packages = storage.convertFileToList(); boolean endProgram = false; System.out.println("Welcome to Travel Agency Booking Reservation System!"); Scanner sc = new Scanner(System.in); @@ -21,6 +22,8 @@ public static void run() { command.execute(packages); endProgram = command.getIsExit(); } + storage.convertListToFile(packages); + } } diff --git a/src/main/java/seedu/duke/Reservation.java b/src/main/java/seedu/duke/Reservation.java index 7216292886..e72ca2ddb8 100644 --- a/src/main/java/seedu/duke/Reservation.java +++ b/src/main/java/seedu/duke/Reservation.java @@ -43,4 +43,8 @@ public String toString() { + "Contact No. " + getContactNumber() + "\n" + "Pax " + getNumOfPax() + "\n"; } + + public String toSave(){ + return Integer.toString(reservationID) + " | " + customerName + " | " + contactNumber + " | " + packageID + " | " + Integer.toString(numOfPax); + } } diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java new file mode 100644 index 0000000000..123ac0a1a1 --- /dev/null +++ b/src/main/java/seedu/duke/Storage.java @@ -0,0 +1,109 @@ +package seedu.duke; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Date; +import java.util.Scanner; + + +/** + * Represents the controller to parse and write to a save file for packages and reservations + */ +public class Storage { + private String packages_filePath; + private String reservations_filePath; + + /** + * String representation of the file path to the save file + * + * @param package_path, reservations_path + */ + public Storage(String package_path, String reservations_path) { + this.packages_filePath = package_path; + this.reservations_filePath = reservations_path; + } + + /** + * Writes the tasks in task list to the save file + * + */ + public void convertListToFile(Packages p) { + String text = ""; + for (int i = 0; i < p.getSize(); i++) { + TravelPackage currentPackage = p.getPackage(i); + text = text + currentPackage.toSave() + System.lineSeparator(); + } + try { + FileWriter fw = new FileWriter(packages_filePath); + fw.write(text); + fw.close(); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + + String resText = ""; + for (int i = 0; i < p.getReservationSize(); i++) { + Reservation currentReservation = p.getReservation(i); + resText = resText + currentReservation.toSave() + System.lineSeparator(); + } + try { + FileWriter fw = new FileWriter(reservations_filePath); + fw.write(resText); + fw.close(); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } + + + /** + * Parses the save file + * + * @return ArrayList of tasks + */ + public Packages convertFileToList() { + Packages p = new Packages(); + File pFile = new File(packages_filePath); + File rFile = new File(reservations_filePath); + try { + Scanner s = new Scanner(pFile); + while (s.hasNext()) { + String currentLine = s.nextLine(); + String[] arrayElements = currentLine.split("\\|"); + String name = arrayElements[0].trim(); + int start = Integer.parseInt(arrayElements[1].trim()); + int end = Integer.parseInt(arrayElements[2].trim()); + String hotel = arrayElements[3].trim(); + double price = Double.parseDouble(arrayElements[4].trim()); + String country = arrayElements[5].trim(); + int vacancies = Integer.parseInt(arrayElements[6].trim()); + TravelPackage newPackage = new TravelPackage(name, new Date(start), new Date(end), hotel, price, country, vacancies); + p.addPackage(newPackage); + } + } catch (FileNotFoundException e) { + System.out.println(e.getMessage()); + } + try { + Scanner s = new Scanner(rFile); + while (s.hasNext()) { + String currentLine = s.nextLine(); + String[] arrayElements = currentLine.split("\\|"); + int reservationID = Integer.parseInt(arrayElements[0].trim()); + String packageID = arrayElements[1].trim(); + String custName = arrayElements[2].trim(); + String custNum = arrayElements[3].trim(); + int numPax = Integer.parseInt(arrayElements[4].trim()); + Reservation newReservation = new Reservation(reservationID, packageID, custName, custNum, numPax); + p.addReservation(newReservation); + } + } catch (FileNotFoundException e) { + System.out.println(e.getMessage()); + } + return p; + } + + +} + diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 8ff8bc2c0b..45a020da5d 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -42,6 +42,11 @@ public String toString() { + this.hotel; } + public String toSave(){ + return name + " | " + Integer.toString(nextId) + " | " + Integer.toString(id) + " | " + //startDate, endDate + hotel + " | " + Double.toString(price) + " | " + country + " | " + Integer.toString(maxParticipants) + " | " + Integer.toString(numParticipants); + } + From 212b2684c549abe1f86d3fa4da4349bfdf5365f8 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Thu, 24 Mar 2022 23:51:40 +0800 Subject: [PATCH 017/131] v1.0 - Initial Changes --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 88d7d00edb..026f9d25b2 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -4,6 +4,6 @@ | --------------------------------------------------- |:---------------:|:-----------------------------------------:| :-------------------------------: | | ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/johndoe.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](docs/team/timothy.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) | From 2948ac2dcf4d2f9c51c2648465ff079661983ddf Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Fri, 25 Mar 2022 01:40:36 +0800 Subject: [PATCH 018/131] Added the 'help' command --- docs/DeveloperGuide.md | 3 ++ src/main/java/seedu/duke/Duke.java | 11 +++++-- src/main/java/seedu/duke/Parser.java | 11 ++----- .../java/seedu/duke/command/HelpCommand.java | 30 +++++++++++++++++++ 4 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 src/main/java/seedu/duke/command/HelpCommand.java diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..d4876e0f86 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -36,3 +36,6 @@ ## Instructions for manual testing {Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} + +## Feature - Help Command +Aim: Displays a list of all available commands that the user can refer to as a guide \ No newline at end of file diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index a3138b0d01..dd0a76d689 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -17,9 +17,14 @@ public static void run() { Scanner sc = new Scanner(System.in); while (!endProgram) { System.out.println("Please enter command: "); - Command command = Parser.parse(sc.nextLine()); - command.execute(packages); - endProgram = command.getIsExit(); + try { + Command command = Parser.parse(sc.nextLine()); + command.execute(packages); + endProgram = command.getIsExit(); + } catch (Exception ex) { + System.out.println("Wrong format. All available" + + " commands can be seen with the 'help' command"); + } } } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 49c4993d72..ac1782bb7a 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,12 +1,6 @@ package seedu.duke; -import seedu.duke.command.AddCommand; -import seedu.duke.command.ByeCommand; -import seedu.duke.command.Command; -import seedu.duke.command.DeleteCommand; -import seedu.duke.command.PackagesCommand; -import seedu.duke.command.ErrorCommand; -import seedu.duke.command.ReservationCommand; +import seedu.duke.command.*; public class Parser { public static Command parse(String input) { @@ -25,7 +19,8 @@ public static Command parse(String input) { switch (commandType) { case "bye": return new ByeCommand(); - + case "help": + return new HelpCommand(); case "add": //only can have spaces between variables - what if hotel has 2 words? final int nameIndex = 1; final int startIndex = 2; diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java new file mode 100644 index 0000000000..86241f3fae --- /dev/null +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -0,0 +1,30 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public class HelpCommand extends Command{ + + @Override + public void execute(Packages packages) { + final String SEPARATOR = "---------------------------------------------" + + "--------------------------\n"; + System.out.println(SEPARATOR + "SHOW ALL PACKAGES\nView a list of all available packages\n" + + "Format/Usage: packages\n" + SEPARATOR + "SHOW CHOSEN PACKAGE\nDisplays the " + + "detailed information of a specific travel " + "package from\nthe " + + "'packages' page Able to print out specific details of any package\n" + + "Format: info {package_id}\n" + "Usage: info P2\n" + SEPARATOR + "ADD PACKAGE\n" + + "Allows the user to add a new travel package\ninto the list of available packages\n" + + "Format: add {package_name}, {country}, {duration}, {price}, {vacancies}\n" + + "Usage: add Skiing Trip, Sweden, 15/2/2022-19/2/2022, 800, 100\n" + SEPARATOR + + "DELETE PACKAGE\nAllows the user to delete an existing travel package\nfrom the " + + "list of available packages\nFormat: delete {package_id}\nUsage: delete P2\n" + + SEPARATOR + "SHOW RESERVATIONS\nShows reservations of the user for " + + "a specified travel package\nfrom the packages page\nFormat: reservations " + + "{package_id}\nUsage: reservations 3\n" + SEPARATOR + "MAKE RESERVATION" + + "\nCreates a reservation for a travel package from the packages page\nFormat: " + + "reserve {package_id} {contact_name} {contact_number} {pax}\nUsage: reserve 3 " + + "John Doe 91234567 3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + + "for a travel package from the packages page\nFormat: remove {reservation_id}" + + "\nUsage: remove R3\n" + SEPARATOR); + } +} From add2be9b1fce4f24606fdd5adc4499898b5a6805 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Fri, 25 Mar 2022 01:43:38 +0800 Subject: [PATCH 019/131] Revise the import issue --- src/main/java/seedu/duke/Parser.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index ac1782bb7a..2a4aaaeeb7 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,6 +1,13 @@ package seedu.duke; -import seedu.duke.command.*; +import seedu.duke.command.AddCommand; +import seedu.duke.command.ByeCommand; +import seedu.duke.command.Command; +import seedu.duke.command.DeleteCommand; +import seedu.duke.command.PackagesCommand; +import seedu.duke.command.ErrorCommand; +import seedu.duke.command.ReservationCommand; +import seedu.duke.command.HelpCommand; public class Parser { public static Command parse(String input) { From 9b7ebe651e9047aa3bf28d6730e06cb68c59984e Mon Sep 17 00:00:00 2001 From: timchang27 <64303732+timchang27@users.noreply.github.com> Date: Fri, 25 Mar 2022 02:22:43 +0800 Subject: [PATCH 020/131] Update DeveloperGuide.md Initial Commit of Product Scope, User Stories, NFRs, and User Instructions --- docs/DeveloperGuide.md | 53 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index d4876e0f86..dcbc709a63 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -12,30 +12,71 @@ ## Product scope ### Target user profile -{Describe the target user profile} +- Studies in a non-IT field +- Usually works alone +- Working in a small travel agency that offers affordable budget travel packages to only some countries +- Handles many customers a day +- Is unfamiliar with using CLI apps ### Value proposition -{Describe the value proposition: what problem does it solve?} +- Travel agencies often have to manage multiple customers and their respective bookings or plans. +- For employees of the travel agencies to track and record customers’ booking of travel packages. + ## User Stories |Version| As a ... | I want to ... | So that I can ...| |--------|----------|---------------|------------------| -|v1.0|new user|see usage instructions|refer to them when I forget how to use the application| -|v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list| +|v1.0|new user|Add reservation for a customer with basic information such as name, country etc. |Make a reservation| +|v1.0|new user|Print a list of all current and available travel packages |View all current travel packages and tell customers about our travel packages with one look| +|v1.0|new user|Remove an existing reservation|Remove information that we do not need anymore| +|v1.0|User ready to start using the app| Find out which travel packages are available for the specific location and duration|Make a recommendation of travel package to customers based on their desired location| +|v1.0|new user|Search for a specific travel package|Make recommendations to a customer based on their desired travel package requirements| +|v2.0|User ready to start using the app|Upload existing reservation data|Get started quickly| +|v2.0|User ready to start using the app|Make reservations based on custom input and edit them where necessary|Get familiar with inputting| +|v2.0|User ready to start using the app|See the changes I made from the previous day|Continue working| +|v2.1|Expert user|Create and use shortcuts|Quickly enter the details needed for a reservation and query any details I might need for an existing reservation| +|v2.1|Expert user|Update ratings of travel packages based on customer feedback|Provide a better recommendations for future customers| +|v2.1|Expert user|Ascertain the error in my input based on the error messages from the application|Quickly troubleshoot any mistakes that would slow down my work| +|v2.1|Expert user|View all reservations currently under a specific travel package|Optimize that travel package according to user’s feedback| +|v2.1|Expert user|I can build a customized travel package based on what the customer wants|It appeals to customers who do not want our existing tour packages| +|v2.1|Expert user|Add in hotels to the list of available hotel options|Update the itinerary | +|v2.1|Expert user|Add in countries to the list of available countries|Update the itinerary| +|v2.1|Expert user|Sort all reservations according to month|Analyze trends throughout the year| +|v2.1|Expert user|Mark a reservation as ‘completed’|Access both completed and ongoing reservations| +|v2.1|Expert user|Compute the price of custom travel packages|Get a rough estimate for what to charge the customer| ## Non-Functional Requirements -{Give non-functional requirements} +### Performance Requirements +- Should work on any mainstream OS as long as it has Java 11 or above installed. + +### Usability +- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. +- Prompts and instructions must be in proper and concise sentences for ease of understanding. ## Glossary * *glossary item* - Definition +* Packages - Travel Package within the agency's database +* Reservations - Reservation of travel package made by one customer through the app ## Instructions for manual testing {Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} +### Summary of User Commands + +| Command | Format Examples | +| ------- | --------------- | +|packages|packages| +|info|info {num} (num < number of available packages)
e.g. info 2 | +|add|add {package_name} {country} {duration} {price} {vacancies}
e.g. add Skiing_Trip Sweden 15/2/2022-19/2/2022 800 100| +|delete|delete {num} (num < number of available packages)
e.g. delete 2| +|reserve|reserve {package_number} {contact_name} {contact_number} {number_pax}
e..g reserve 3 John 91234567 3 | +|remove|remove {reservation_id}
e..g remove R001| +|reservations|reservations {package_number}
eg. reservations 2| + ## Feature - Help Command -Aim: Displays a list of all available commands that the user can refer to as a guide \ No newline at end of file +Aim: Displays a list of all available commands that the user can refer to as a guide From 098dc2180e08966e5c049aa0003ce763167c7b9b Mon Sep 17 00:00:00 2001 From: mafpovbul Date: Sat, 26 Mar 2022 21:02:51 +0800 Subject: [PATCH 021/131] Refactored storage, added more exception handling --- reservations.txt | 2 +- src/main/java/seedu/duke/Duke.java | 3 +- src/main/java/seedu/duke/Packages.java | 9 ++- src/main/java/seedu/duke/Parser.java | 36 ++++++---- src/main/java/seedu/duke/Storage.java | 71 ++++++++++++------- .../duke/command/WrongFormatCommand.java | 19 +++++ 6 files changed, 95 insertions(+), 45 deletions(-) create mode 100644 src/main/java/seedu/duke/command/WrongFormatCommand.java diff --git a/reservations.txt b/reservations.txt index 7ce14e09ba..f63d822898 100644 --- a/reservations.txt +++ b/reservations.txt @@ -1 +1 @@ -1 | 123 | 1 | bawj | 2 +1 | bawj | 123 | 1 | 2 diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 8137dd0a3e..d9d785f1ef 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -12,7 +12,7 @@ public static void main(String[] args) { public static void run() { Storage storage = new Storage("packages.txt", "reservations.txt"); - Packages packages = storage.convertFileToList(); + Packages packages = storage.createPackages(); boolean endProgram = false; System.out.println("Welcome to Travel Agency Booking Reservation System!"); Scanner sc = new Scanner(System.in); @@ -23,7 +23,6 @@ public static void run() { endProgram = command.getIsExit(); } storage.convertListToFile(packages); - } } diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index 4b830c3e68..e086dda033 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -8,8 +8,13 @@ public class Packages { private ArrayList reservations; public Packages() { - packages = new ArrayList<>(); - reservations = new ArrayList<>(); + this.packages = new ArrayList<>(); + this.reservations = new ArrayList<>(); + } + + public Packages(ArrayList t, ArrayList r){ + this.packages = t; + this.reservations = r; } public int getSize() { diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 49c4993d72..a14fc4b2e0 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -7,6 +7,7 @@ import seedu.duke.command.PackagesCommand; import seedu.duke.command.ErrorCommand; import seedu.duke.command.ReservationCommand; +import seedu.duke.command.WrongFormatCommand; public class Parser { public static Command parse(String input) { @@ -27,21 +28,26 @@ public static Command parse(String input) { return new ByeCommand(); case "add": //only can have spaces between variables - what if hotel has 2 words? - final int nameIndex = 1; - final int startIndex = 2; - final int endIndex = 3; - final int hotelIndex = 4; - final int priceIndex = 5; - final int countryIndex = 6; - final int vacanciesIndex = 7; - name = inputArray[nameIndex]; - start = Integer.parseInt(inputArray[startIndex]); - end = Integer.parseInt(inputArray[endIndex]); - hotel = inputArray[hotelIndex]; - price = Double.parseDouble(inputArray[priceIndex]); - country = inputArray[countryIndex]; - vacancies = Integer.parseInt(inputArray[vacanciesIndex]); - return new AddCommand(name, start, end, hotel, price, country, vacancies); + if (inputArray.length != 8){ + return new WrongFormatCommand(input); + } + else{ + final int nameIndex = 1; + final int startIndex = 2; + final int endIndex = 3; + final int hotelIndex = 4; + final int priceIndex = 5; + final int countryIndex = 6; + final int vacanciesIndex = 7; + name = inputArray[nameIndex]; + start = Integer.parseInt(inputArray[startIndex]); + end = Integer.parseInt(inputArray[endIndex]); + hotel = inputArray[hotelIndex]; + price = Double.parseDouble(inputArray[priceIndex]); + country = inputArray[countryIndex]; + vacancies = Integer.parseInt(inputArray[vacanciesIndex]); + return new AddCommand(name, start, end, hotel, price, country, vacancies); + } case "delete": id = inputArray[1]; return new DeleteCommand(id); diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 123ac0a1a1..6d40dfab6d 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -4,6 +4,7 @@ import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; +import java.util.ArrayList; import java.util.Date; import java.util.Scanner; @@ -59,14 +60,52 @@ public void convertListToFile(Packages p) { /** - * Parses the save file + * Calls the functions to read packages and reservations saved files * - * @return ArrayList of tasks + * @return Packages object for Control class */ - public Packages convertFileToList() { - Packages p = new Packages(); - File pFile = new File(packages_filePath); + public Packages createPackages() { + ArrayList r = parseReservationFile(); + ArrayList t = parseTravelPackageFile(); + Packages p = new Packages(t, r); + return p; + } + + /** + * Parses the saved reservation file + * + * @return Arraylist of Reservations + */ + public ArrayList parseReservationFile(){ File rFile = new File(reservations_filePath); + ArrayList r = new ArrayList<>(); + try { + Scanner s = new Scanner(rFile); + while (s.hasNext()) { + String currentLine = s.nextLine(); + String[] arrayElements = currentLine.split("\\|"); + int reservationID = Integer.parseInt(arrayElements[0].trim()); + String packageID = arrayElements[1].trim(); + String customerName = arrayElements[2].trim(); + String customerNum = arrayElements[3].trim(); + int numPax = Integer.parseInt(arrayElements[4].trim()); + Reservation newReservation = new Reservation(reservationID, packageID, customerName, customerNum, numPax); + r.add(newReservation); + } + } catch (FileNotFoundException e) { + System.out.println(e.getMessage()); + } + return r; + } + + /** + * Parses the saved travel packages file + * + * @return Arraylist of TravelPackage + */ + public ArrayList parseTravelPackageFile() { + ArrayList t = new ArrayList<>(); + File pFile = new File(packages_filePath); try { Scanner s = new Scanner(pFile); while (s.hasNext()) { @@ -80,30 +119,12 @@ public Packages convertFileToList() { String country = arrayElements[5].trim(); int vacancies = Integer.parseInt(arrayElements[6].trim()); TravelPackage newPackage = new TravelPackage(name, new Date(start), new Date(end), hotel, price, country, vacancies); - p.addPackage(newPackage); - } - } catch (FileNotFoundException e) { - System.out.println(e.getMessage()); - } - try { - Scanner s = new Scanner(rFile); - while (s.hasNext()) { - String currentLine = s.nextLine(); - String[] arrayElements = currentLine.split("\\|"); - int reservationID = Integer.parseInt(arrayElements[0].trim()); - String packageID = arrayElements[1].trim(); - String custName = arrayElements[2].trim(); - String custNum = arrayElements[3].trim(); - int numPax = Integer.parseInt(arrayElements[4].trim()); - Reservation newReservation = new Reservation(reservationID, packageID, custName, custNum, numPax); - p.addReservation(newReservation); + t.add(newPackage); } } catch (FileNotFoundException e) { System.out.println(e.getMessage()); } - return p; + return t; } - - } diff --git a/src/main/java/seedu/duke/command/WrongFormatCommand.java b/src/main/java/seedu/duke/command/WrongFormatCommand.java new file mode 100644 index 0000000000..ec94803e2d --- /dev/null +++ b/src/main/java/seedu/duke/command/WrongFormatCommand.java @@ -0,0 +1,19 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public class WrongFormatCommand extends Command{ + + private String input; + + public WrongFormatCommand(String input) { + this.input = input; + } + + public void execute(Packages packages) { + System.out.println("Input in wrong format: " + this.input); + System.out.println("Use the help command to find out the valid commands."); + + } + +} From 30068875486cd32a306f029e898a561ab8350575 Mon Sep 17 00:00:00 2001 From: mafpovbul Date: Sat, 26 Mar 2022 21:08:17 +0800 Subject: [PATCH 022/131] changed save file --- reservations.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reservations.txt b/reservations.txt index f63d822898..e465c6e55c 100644 --- a/reservations.txt +++ b/reservations.txt @@ -1 +1 @@ -1 | bawj | 123 | 1 | 2 +1 | bawj | 98765432 | 123 | 2 From a73a44c606f0f04a8e03d095096c8cdfc2f9c436 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sat, 26 Mar 2022 21:45:23 +0800 Subject: [PATCH 023/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index dcbc709a63..ffdf67ef88 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -80,3 +80,6 @@ ## Feature - Help Command Aim: Displays a list of all available commands that the user can refer to as a guide + +## Feature - Saved files +Aim: Allows users to save and load up existing reservations and travel packages from a text file From 03f2e8856fea78fc278381481c90c24cc71891b0 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 10:25:31 +0800 Subject: [PATCH 024/131] Add files via upload --- docs/storage sequence diagram.png | Bin 0 -> 15065 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/storage sequence diagram.png diff --git a/docs/storage sequence diagram.png b/docs/storage sequence diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..a276fc6a967395629456e7e94e674abc78c499a3 GIT binary patch literal 15065 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 Zx#j80mpT&^;jSuyrmBugwbJ#l{{v1RYGD8X literal 0 HcmV?d00001 From d01889c26e83c6bcd82aa05a98bbd37d6b6623d8 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 10:26:11 +0800 Subject: [PATCH 025/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ffdf67ef88..fc3bc507f1 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -83,3 +83,5 @@ Aim: Displays a list of all available commands that the user can refer to as a g ## Feature - Saved files Aim: Allows users to save and load up existing reservations and travel packages from a text file +![](storage sequence diagram.png) + From 4c85f6b164b13dcf52077134f3f37694f3f3ff28 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 10:40:50 +0800 Subject: [PATCH 026/131] Delete storage sequence diagram.png --- docs/storage sequence diagram.png | Bin 15065 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/storage sequence diagram.png diff --git a/docs/storage sequence diagram.png b/docs/storage sequence diagram.png deleted file mode 100644 index a276fc6a967395629456e7e94e674abc78c499a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15065 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 Zx#j80mpT&^;jSuyrmBugwbJ#l{{v1RYGD8X From 300b235cd26abe00b70050a6b5be4a21fe717157 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 10:41:12 +0800 Subject: [PATCH 027/131] Add files via upload --- docs/StorageSeqDiag.png | Bin 0 -> 15065 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/StorageSeqDiag.png diff --git a/docs/StorageSeqDiag.png b/docs/StorageSeqDiag.png new file mode 100644 index 0000000000000000000000000000000000000000..a276fc6a967395629456e7e94e674abc78c499a3 GIT binary patch literal 15065 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 Zx#j80mpT&^;jSuyrmBugwbJ#l{{v1RYGD8X literal 0 HcmV?d00001 From fd4f6899916b0773bd3c833803fb8825d7b8ee40 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 10:41:40 +0800 Subject: [PATCH 028/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index fc3bc507f1..fdda32c615 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -82,6 +82,6 @@ Aim: Displays a list of all available commands that the user can refer to as a guide ## Feature - Saved files -Aim: Allows users to save and load up existing reservations and travel packages from a text file -![](storage sequence diagram.png) +Aim: Allows users to save and load up existing reservations and travel packages from a text file
+![](docs/StorageSeqDiag.png) From acdd0fbc6f65cddddb82b8821ad5b9e49cbf95fa Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 10:43:03 +0800 Subject: [PATCH 029/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index fdda32c615..8f577aa0f1 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -83,5 +83,5 @@ Aim: Displays a list of all available commands that the user can refer to as a g ## Feature - Saved files Aim: Allows users to save and load up existing reservations and travel packages from a text file
-![](docs/StorageSeqDiag.png) +![](StorageSeqDiag.png) From d6f852f057c62edf5f81ecb7e3f828b83c24957f Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 11:04:19 +0800 Subject: [PATCH 030/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8f577aa0f1..49cca8b386 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -81,7 +81,13 @@ ## Feature - Help Command Aim: Displays a list of all available commands that the user can refer to as a guide -## Feature - Saved files -Aim: Allows users to save and load up existing reservations and travel packages from a text file
+## Feature - Storage +#### Initialisation (Loading Data) +The sequence diagram that shows how `Storage` is created and the data is loaded from the saved files when the program is initialised is shown below: ![](StorageSeqDiag.png) +1. `Duke` creates a Storage object with the relevant file names. +2. `Duke` then calls the `createPackages()` method of the Storage class +3. `storage` will then load the contents of the file in the `Reservation` and `TravelPackages` file calling the different `parse` methods. The exact implementation is not shown in the diagram. +4. A new `Package` object is constructed with the relevant data. +5. `storage` returns `package` object to `Duke`. From 9654fc6c601d59abbef7eec587734e61e55658ed Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 11:19:11 +0800 Subject: [PATCH 031/131] Update UserGuide.md --- docs/UserGuide.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index abd9fbe891..e9417a583a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -37,6 +37,15 @@ Example of usage: ## Command Summary -{Give a 'cheat sheet' of commands here} +| Command | Syntax | +| --- | ----------- | +| packages | packages | +| info | info {num} | +| add | add {package_name} {country} {duration} {price} {vacancies} | +| delete | delete {num} | +| reserve | reserve {package_number} {contact_name} {contact_number} {number_pax} | +| remove | remove {reservation_id} | +| reservations | reservations {package_number} | + + -* Add todo `todo n/TODO_NAME d/DEADLINE` From 6aa0c3922e4c7c57f90a68ab362696cdbcbdc8ad Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 11:19:40 +0800 Subject: [PATCH 032/131] Update UserGuide.md --- docs/UserGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index e9417a583a..e89e66b7b9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -38,7 +38,7 @@ Example of usage: ## Command Summary | Command | Syntax | -| --- | ----------- | +| --- | :--- | | packages | packages | | info | info {num} | | add | add {package_name} {country} {duration} {price} {vacancies} | From 54f4643256872339b737ff839a7d00740a760e16 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 27 Mar 2022 14:27:04 +0800 Subject: [PATCH 033/131] Abstract reservations out from packages --- reservations.txt | 2 +- src/main/java/seedu/duke/Duke.java | 5 ++- src/main/java/seedu/duke/Packages.java | 22 +---------- src/main/java/seedu/duke/Reservation.java | 5 ++- src/main/java/seedu/duke/Reservations.java | 34 ++++++++++++++++ src/main/java/seedu/duke/Storage.java | 32 ++++++++------- .../java/seedu/duke/command/AddCommand.java | 3 +- .../java/seedu/duke/command/ByeCommand.java | 3 +- src/main/java/seedu/duke/command/Command.java | 3 +- .../seedu/duke/command/DeleteCommand.java | 3 +- .../java/seedu/duke/command/ErrorCommand.java | 3 +- .../java/seedu/duke/command/HelpCommand.java | 39 ++++++++++--------- .../seedu/duke/command/PackagesCommand.java | 3 +- .../duke/command/ReservationCommand.java | 30 +++++++------- .../duke/command/WrongFormatCommand.java | 5 ++- 15 files changed, 112 insertions(+), 80 deletions(-) create mode 100644 src/main/java/seedu/duke/Reservations.java diff --git a/reservations.txt b/reservations.txt index e465c6e55c..9a832780cd 100644 --- a/reservations.txt +++ b/reservations.txt @@ -1 +1 @@ -1 | bawj | 98765432 | 123 | 2 +1 | 123 | bawj | 98765432 | 2 diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index fadda26a82..32020e07d3 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -13,6 +13,7 @@ public static void main(String[] args) { public static void run() { Storage storage = new Storage("packages.txt", "reservations.txt"); Packages packages = storage.createPackages(); + Reservations reservations = storage.createReservatons(); boolean endProgram = false; System.out.println("Welcome to Travel Agency Booking Reservation System!"); Scanner sc = new Scanner(System.in); @@ -20,14 +21,14 @@ public static void run() { System.out.println("Please enter command: "); try { Command command = Parser.parse(sc.nextLine()); - command.execute(packages); + command.execute(packages, reservations); endProgram = command.getIsExit(); } catch (Exception ex) { System.out.println("Wrong format. All available" + " commands can be seen with the 'help' command"); } } - storage.convertListToFile(packages); + storage.convertListToFile(packages, reservations); } } diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index e086dda033..db40d7af52 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -5,16 +5,13 @@ public class Packages { private ArrayList packages; - private ArrayList reservations; public Packages() { this.packages = new ArrayList<>(); - this.reservations = new ArrayList<>(); } - public Packages(ArrayList t, ArrayList r){ + public Packages(ArrayList t) { this.packages = t; - this.reservations = r; } public int getSize() { @@ -33,21 +30,4 @@ public void removePackage(int index) { packages.remove(index); } - public Reservation getReservation(int index) { - return reservations.get(index); - } - - public int getReservationSize() { - return reservations.size(); - } - - public void addReservation(Reservation newReservation) { - reservations.add(newReservation); - System.out.println("RESERVATION ADDED"); - - } - - public void removeReservation(int index) { - reservations.remove(index); - } } \ No newline at end of file diff --git a/src/main/java/seedu/duke/Reservation.java b/src/main/java/seedu/duke/Reservation.java index e72ca2ddb8..039dc35ad4 100644 --- a/src/main/java/seedu/duke/Reservation.java +++ b/src/main/java/seedu/duke/Reservation.java @@ -44,7 +44,8 @@ public String toString() { + "Pax " + getNumOfPax() + "\n"; } - public String toSave(){ - return Integer.toString(reservationID) + " | " + customerName + " | " + contactNumber + " | " + packageID + " | " + Integer.toString(numOfPax); + public String toSave() { + return Integer.toString(reservationID) + " | " + packageID + " | " + customerName + " | " + contactNumber + + " | " + Integer.toString(numOfPax); } } diff --git a/src/main/java/seedu/duke/Reservations.java b/src/main/java/seedu/duke/Reservations.java new file mode 100644 index 0000000000..b44678e38b --- /dev/null +++ b/src/main/java/seedu/duke/Reservations.java @@ -0,0 +1,34 @@ +package seedu.duke; + +import java.util.ArrayList; + +public class Reservations { + private ArrayList reservations; + + public Reservations() { + this.reservations = new ArrayList<>(); + } + + public Reservations(ArrayList r) { + this.reservations = r; + } + + public Reservation getReservation(int index) { + return reservations.get(index); + } + + public int getReservationSize() { + return reservations.size(); + } + + public void addReservation(Reservation newReservation) { + reservations.add(newReservation); + System.out.println("RESERVATION ADDED"); + + } + + public void removeReservation(int index) { + reservations.remove(index); + } + +} diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 6d40dfab6d..432d801c6c 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -8,9 +8,9 @@ import java.util.Date; import java.util.Scanner; - /** - * Represents the controller to parse and write to a save file for packages and reservations + * Represents the controller to parse and write to a save file for packages and + * reservations */ public class Storage { private String packages_filePath; @@ -19,7 +19,8 @@ public class Storage { /** * String representation of the file path to the save file * - * @param package_path, reservations_path + * @param package_path, + * reservations_path */ public Storage(String package_path, String reservations_path) { this.packages_filePath = package_path; @@ -30,7 +31,7 @@ public Storage(String package_path, String reservations_path) { * Writes the tasks in task list to the save file * */ - public void convertListToFile(Packages p) { + public void convertListToFile(Packages p, Reservations r) { String text = ""; for (int i = 0; i < p.getSize(); i++) { TravelPackage currentPackage = p.getPackage(i); @@ -45,8 +46,8 @@ public void convertListToFile(Packages p) { } String resText = ""; - for (int i = 0; i < p.getReservationSize(); i++) { - Reservation currentReservation = p.getReservation(i); + for (int i = 0; i < r.getReservationSize(); i++) { + Reservation currentReservation = r.getReservation(i); resText = resText + currentReservation.toSave() + System.lineSeparator(); } try { @@ -58,25 +59,29 @@ public void convertListToFile(Packages p) { } } - /** * Calls the functions to read packages and reservations saved files * * @return Packages object for Control class */ public Packages createPackages() { - ArrayList r = parseReservationFile(); ArrayList t = parseTravelPackageFile(); - Packages p = new Packages(t, r); + Packages p = new Packages(t); return p; } + public Reservations createReservatons() { + ArrayList r = parseReservationFile(); + Reservations reservations = new Reservations(r); + return reservations; + } + /** * Parses the saved reservation file * * @return Arraylist of Reservations */ - public ArrayList parseReservationFile(){ + public ArrayList parseReservationFile() { File rFile = new File(reservations_filePath); ArrayList r = new ArrayList<>(); try { @@ -89,7 +94,8 @@ public ArrayList parseReservationFile(){ String customerName = arrayElements[2].trim(); String customerNum = arrayElements[3].trim(); int numPax = Integer.parseInt(arrayElements[4].trim()); - Reservation newReservation = new Reservation(reservationID, packageID, customerName, customerNum, numPax); + Reservation newReservation = new Reservation(reservationID, packageID, customerName, customerNum, + numPax); r.add(newReservation); } } catch (FileNotFoundException e) { @@ -118,7 +124,8 @@ public ArrayList parseTravelPackageFile() { double price = Double.parseDouble(arrayElements[4].trim()); String country = arrayElements[5].trim(); int vacancies = Integer.parseInt(arrayElements[6].trim()); - TravelPackage newPackage = new TravelPackage(name, new Date(start), new Date(end), hotel, price, country, vacancies); + TravelPackage newPackage = new TravelPackage(name, new Date(start), new Date(end), hotel, price, + country, vacancies); t.add(newPackage); } } catch (FileNotFoundException e) { @@ -127,4 +134,3 @@ public ArrayList parseTravelPackageFile() { return t; } } - diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java index 1709a0efe5..bb559adef6 100644 --- a/src/main/java/seedu/duke/command/AddCommand.java +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -3,6 +3,7 @@ import java.util.Date; import seedu.duke.Packages; +import seedu.duke.Reservations; import seedu.duke.TravelPackage; public class AddCommand extends Command { @@ -14,7 +15,7 @@ public AddCommand(String name, int date1, int date2, String hotel, double price, maxVacancies); } - public void execute(Packages packages) { + public void execute(Packages packages, Reservations r) { packages.addPackage(newPackage); } } diff --git a/src/main/java/seedu/duke/command/ByeCommand.java b/src/main/java/seedu/duke/command/ByeCommand.java index c8fb168640..80bc8519af 100644 --- a/src/main/java/seedu/duke/command/ByeCommand.java +++ b/src/main/java/seedu/duke/command/ByeCommand.java @@ -1,13 +1,14 @@ package seedu.duke.command; import seedu.duke.Packages; +import seedu.duke.Reservations; public class ByeCommand extends Command { public ByeCommand() { setIsExit(true); } - public void execute(Packages packages) { + public void execute(Packages packages, Reservations r) { System.out.println("Thank you for using TARBS. See you again!"); } } diff --git a/src/main/java/seedu/duke/command/Command.java b/src/main/java/seedu/duke/command/Command.java index 63cfac6c1c..58b55b5beb 100644 --- a/src/main/java/seedu/duke/command/Command.java +++ b/src/main/java/seedu/duke/command/Command.java @@ -1,6 +1,7 @@ package seedu.duke.command; import seedu.duke.Packages; +import seedu.duke.Reservations; public abstract class Command { private boolean isExit = false; @@ -13,5 +14,5 @@ public void setIsExit(boolean isExit) { this.isExit = isExit; } - public abstract void execute(Packages packages); + public abstract void execute(Packages packages, Reservations reservations); } diff --git a/src/main/java/seedu/duke/command/DeleteCommand.java b/src/main/java/seedu/duke/command/DeleteCommand.java index 6b43838fa8..b8f558977c 100644 --- a/src/main/java/seedu/duke/command/DeleteCommand.java +++ b/src/main/java/seedu/duke/command/DeleteCommand.java @@ -1,6 +1,7 @@ package seedu.duke.command; import seedu.duke.Packages; +import seedu.duke.Reservations; public class DeleteCommand extends Command { private final String id; @@ -9,7 +10,7 @@ public DeleteCommand(String id) { this.id = id; } - public void execute(Packages packages) { + public void execute(Packages packages, Reservations r) { int numberOfPackages = packages.getSize(); for (int i = 0; i < numberOfPackages; i++) { if (packages.getPackage(i).getID().equals(id)) { diff --git a/src/main/java/seedu/duke/command/ErrorCommand.java b/src/main/java/seedu/duke/command/ErrorCommand.java index ce4e4961d2..12a70072a2 100644 --- a/src/main/java/seedu/duke/command/ErrorCommand.java +++ b/src/main/java/seedu/duke/command/ErrorCommand.java @@ -1,6 +1,7 @@ package seedu.duke.command; import seedu.duke.Packages; +import seedu.duke.Reservations; public class ErrorCommand extends Command { private String input; @@ -9,7 +10,7 @@ public ErrorCommand(String input) { this.input = input; } - public void execute(Packages packages) { + public void execute(Packages packages, Reservations r) { System.out.println("Input not recognized: " + this.input); System.out.println("Use the help command to find out the valid commands."); diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index 86241f3fae..f2d9f9452e 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -1,30 +1,31 @@ package seedu.duke.command; import seedu.duke.Packages; +import seedu.duke.Reservations; -public class HelpCommand extends Command{ +public class HelpCommand extends Command { @Override - public void execute(Packages packages) { + public void execute(Packages packages, Reservations r) { final String SEPARATOR = "---------------------------------------------" + "--------------------------\n"; System.out.println(SEPARATOR + "SHOW ALL PACKAGES\nView a list of all available packages\n" + - "Format/Usage: packages\n" + SEPARATOR + "SHOW CHOSEN PACKAGE\nDisplays the " + - "detailed information of a specific travel " + "package from\nthe " + - "'packages' page Able to print out specific details of any package\n" + - "Format: info {package_id}\n" + "Usage: info P2\n" + SEPARATOR + "ADD PACKAGE\n" + - "Allows the user to add a new travel package\ninto the list of available packages\n" + - "Format: add {package_name}, {country}, {duration}, {price}, {vacancies}\n" + - "Usage: add Skiing Trip, Sweden, 15/2/2022-19/2/2022, 800, 100\n" + SEPARATOR + - "DELETE PACKAGE\nAllows the user to delete an existing travel package\nfrom the " + - "list of available packages\nFormat: delete {package_id}\nUsage: delete P2\n" + - SEPARATOR + "SHOW RESERVATIONS\nShows reservations of the user for " + - "a specified travel package\nfrom the packages page\nFormat: reservations " + - "{package_id}\nUsage: reservations 3\n" + SEPARATOR + "MAKE RESERVATION" + - "\nCreates a reservation for a travel package from the packages page\nFormat: " + - "reserve {package_id} {contact_name} {contact_number} {pax}\nUsage: reserve 3 " + - "John Doe 91234567 3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + - "for a travel package from the packages page\nFormat: remove {reservation_id}" + - "\nUsage: remove R3\n" + SEPARATOR); + "Format/Usage: packages\n" + SEPARATOR + "SHOW CHOSEN PACKAGE\nDisplays the " + + "detailed information of a specific travel " + "package from\nthe " + + "'packages' page Able to print out specific details of any package\n" + + "Format: info {package_id}\n" + "Usage: info P2\n" + SEPARATOR + "ADD PACKAGE\n" + + "Allows the user to add a new travel package\ninto the list of available packages\n" + + "Format: add {package_name}, {country}, {duration}, {price}, {vacancies}\n" + + "Usage: add Skiing Trip, Sweden, 15/2/2022-19/2/2022, 800, 100\n" + SEPARATOR + + "DELETE PACKAGE\nAllows the user to delete an existing travel package\nfrom the " + + "list of available packages\nFormat: delete {package_id}\nUsage: delete P2\n" + + SEPARATOR + "SHOW RESERVATIONS\nShows reservations of the user for " + + "a specified travel package\nfrom the packages page\nFormat: reservations " + + "{package_id}\nUsage: reservations 3\n" + SEPARATOR + "MAKE RESERVATION" + + "\nCreates a reservation for a travel package from the packages page\nFormat: " + + "reserve {package_id} {contact_name} {contact_number} {pax}\nUsage: reserve 3 " + + "John Doe 91234567 3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + + "for a travel package from the packages page\nFormat: remove {reservation_id}" + + "\nUsage: remove R3\n" + SEPARATOR); } } diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index eff33ef580..f1052fb62d 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -1,9 +1,10 @@ package seedu.duke.command; import seedu.duke.Packages; +import seedu.duke.Reservations; public class PackagesCommand extends Command { - public void execute(Packages packages) { + public void execute(Packages packages, Reservations r) { for (int i = 0; i < packages.getSize(); i++) { System.out.println(packages.getPackage(i)); } diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java index 0d2feeb96a..86045be6a6 100644 --- a/src/main/java/seedu/duke/command/ReservationCommand.java +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -2,10 +2,12 @@ import seedu.duke.Packages; import seedu.duke.Reservation; +import seedu.duke.Reservations; + import java.util.Scanner; public class ReservationCommand extends Command { - public void execute(Packages packages) { + public void execute(Packages packages, Reservations reservations) { Scanner s = new Scanner(System.in); System.out.println("Please choose which function you would like to perform for Reservations."); System.out.println("1. Add Reservation"); @@ -14,27 +16,27 @@ public void execute(Packages packages) { int choice = Integer.parseInt(s.nextLine()); switch (choice) { case 1: - addReservation(packages); + addReservation(reservations); return; case 2: - deleteReservation(packages); + deleteReservation(reservations); return; case 3: - printReservation(packages); + printReservation(reservations); return; default: System.out.println("Please only enter numbers 1-3!"); } } - public void printReservation(Packages packages) { + public void printReservation(Reservations r) { Scanner sc = new Scanner(System.in); System.out.println("Enter Reservation ID to check details: "); int index = sc.nextInt(); boolean reservationFound = false; - for (int i = 0; i < packages.getReservationSize(); i++) { - if (packages.getReservation(i).getReservationID() == index) { - System.out.println(packages.getReservation(i)); + for (int i = 0; i < r.getReservationSize(); i++) { + if (r.getReservation(i).getReservationID() == index) { + System.out.println(r.getReservation(i)); reservationFound = true; break; } @@ -44,7 +46,7 @@ public void printReservation(Packages packages) { } } - public void addReservation(Packages packages) { + public void addReservation(Reservations r) { Scanner c = new Scanner(System.in); System.out.println("Enter reservation ID: "); final int rid = Integer.parseInt(c.nextLine()); @@ -57,18 +59,18 @@ public void addReservation(Packages packages) { System.out.println("Enter number of pax: "); final int pax = Integer.parseInt(c.nextLine()); - packages.addReservation(new Reservation(rid, tid, name, number, pax)); + r.addReservation(new Reservation(rid, tid, name, number, pax)); } - public void deleteReservation(Packages packages) { + public void deleteReservation(Reservations r) { Scanner p = new Scanner(System.in); System.out.println("Please enter the reservation ID to be deleted: "); int index = p.nextInt(); boolean deletionFound = false; - for (int i = 0; i < packages.getReservationSize(); i++) { - if (packages.getReservation(i).getReservationID() == index) { + for (int i = 0; i < r.getReservationSize(); i++) { + if (r.getReservation(i).getReservationID() == index) { System.out.println("Deleting Reservation"); - packages.removeReservation(i); + r.removeReservation(i); deletionFound = true; break; } diff --git a/src/main/java/seedu/duke/command/WrongFormatCommand.java b/src/main/java/seedu/duke/command/WrongFormatCommand.java index ec94803e2d..77d1e5de51 100644 --- a/src/main/java/seedu/duke/command/WrongFormatCommand.java +++ b/src/main/java/seedu/duke/command/WrongFormatCommand.java @@ -1,8 +1,9 @@ package seedu.duke.command; import seedu.duke.Packages; +import seedu.duke.Reservations; -public class WrongFormatCommand extends Command{ +public class WrongFormatCommand extends Command { private String input; @@ -10,7 +11,7 @@ public WrongFormatCommand(String input) { this.input = input; } - public void execute(Packages packages) { + public void execute(Packages packages, Reservations r) { System.out.println("Input in wrong format: " + this.input); System.out.println("Use the help command to find out the valid commands."); From 66c0907a88180accde205a67e6570523f033860c Mon Sep 17 00:00:00 2001 From: Brendan <53790951+bbawj@users.noreply.github.com> Date: Sun, 27 Mar 2022 15:28:05 +0800 Subject: [PATCH 034/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 49cca8b386..62a8bb5154 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -7,6 +7,8 @@ ## Design & implementation {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +### Basic Class Diagram +![image](https://user-images.githubusercontent.com/53790951/160271319-4a351f51-afd7-4e04-9451-f04143146551.png) ## Product scope From e449f68278d7f53293309c74f6c2f7b4a4c4fb6d Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 27 Mar 2022 16:38:07 +0800 Subject: [PATCH 035/131] Add ParserTest --- src/main/java/seedu/duke/Parser.java | 15 ++-- src/main/java/seedu/duke/Storage.java | 6 +- src/main/java/seedu/duke/TravelPackage.java | 66 +++++++++++---- .../java/seedu/duke/command/AddCommand.java | 8 +- src/test/java/seedu/duke/ParserTest.java | 81 +++++++++++++++++++ 5 files changed, 146 insertions(+), 30 deletions(-) create mode 100644 src/test/java/seedu/duke/ParserTest.java diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index f0d11839b9..50c1b41975 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -16,8 +16,8 @@ public static Command parse(String input) { String commandType = inputArray[0]; String id; - int start; - int end; + String start; + String end; int vacancies; double price; String name; @@ -29,11 +29,10 @@ public static Command parse(String input) { return new ByeCommand(); case "help": return new HelpCommand(); - case "add": //only can have spaces between variables - what if hotel has 2 words? - if (inputArray.length != 8){ + case "add": // only can have spaces between variables - what if hotel has 2 words? + if (inputArray.length != 8) { return new WrongFormatCommand(input); - } - else{ + } else { final int nameIndex = 1; final int startIndex = 2; final int endIndex = 3; @@ -42,8 +41,8 @@ public static Command parse(String input) { final int countryIndex = 6; final int vacanciesIndex = 7; name = inputArray[nameIndex]; - start = Integer.parseInt(inputArray[startIndex]); - end = Integer.parseInt(inputArray[endIndex]); + start = inputArray[startIndex]; + end = inputArray[endIndex]; hotel = inputArray[hotelIndex]; price = Double.parseDouble(inputArray[priceIndex]); country = inputArray[countryIndex]; diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 432d801c6c..ba9b74195d 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -118,13 +118,13 @@ public ArrayList parseTravelPackageFile() { String currentLine = s.nextLine(); String[] arrayElements = currentLine.split("\\|"); String name = arrayElements[0].trim(); - int start = Integer.parseInt(arrayElements[1].trim()); - int end = Integer.parseInt(arrayElements[2].trim()); + String start = arrayElements[1].trim(); + String end = arrayElements[2].trim(); String hotel = arrayElements[3].trim(); double price = Double.parseDouble(arrayElements[4].trim()); String country = arrayElements[5].trim(); int vacancies = Integer.parseInt(arrayElements[6].trim()); - TravelPackage newPackage = new TravelPackage(name, new Date(start), new Date(end), hotel, price, + TravelPackage newPackage = new TravelPackage(name, start, end, hotel, price, country, vacancies); t.add(newPackage); } diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 45a020da5d..f9b6e24999 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -3,20 +3,32 @@ import java.util.Date; public class TravelPackage { + public static final String EXAMPLENAME = "Switzerland - Conquer Summits"; + public static final String EXAMPLESTART = ""; + public static final String EXAMPLEEND = ""; + public static final String EXAMPLEHOTEL = "EXAMPLE HOTEL"; + public static final double EXAMPLEPRICE = 99.99; + public static final String EXAMPLECOUNTRY = "Switzerland"; + public static final int EXAMPLEMAX = 10; + private final String name; private static int nextId = 1; private final int id; - private Date[] period; //[startDate,endDate] + private Date[] period; // [startDate,endDate] + private final String startDate; + private final String endDate; private final String hotel; private final double price; private final String country; private final int maxParticipants; private final int numParticipants; - public TravelPackage(String name, Date startDate, Date endDate, - String hotel, double price, String country, int maxParticipants) { + public TravelPackage(String name, String startDate, String endDate, + String hotel, double price, String country, int maxParticipants) { this.name = name; // this.period = [startDate,endDate]; + this.startDate = startDate; + this.endDate = endDate; this.hotel = hotel; this.price = price; this.country = country; @@ -24,36 +36,56 @@ public TravelPackage(String name, Date startDate, Date endDate, this.numParticipants = 0; id = nextId++; } - + public boolean isFull() { - return this.numParticipants >= maxParticipants; + return this.numParticipants >= maxParticipants; } public String getID() { return "P" + this.id; } - public String toString() { - return "Here are the details for " - + this.name + ", Travel Package ID of " - + this.getID() + "\nCountry: " - + this.country + "\nPrice: " - + this.price + "\nHotel: " - + this.hotel; + public String getName() { + return this.name; } - public String toSave(){ - return name + " | " + Integer.toString(nextId) + " | " + Integer.toString(id) + " | " + //startDate, endDate - hotel + " | " + Double.toString(price) + " | " + country + " | " + Integer.toString(maxParticipants) + " | " + Integer.toString(numParticipants); + public String getStartDate() { + return this.startDate; } + public String getEndDate() { + return this.endDate; + } - + public String getHotel() { + return this.hotel; + } + public double getPrice() { + return this.price; + } - + public String getCountry() { + return this.country; + } + public int getMaxParticipants() { + return this.maxParticipants; + } + public String toString() { + return "Here are the details for " + + this.name + ", Travel Package ID of " + + this.getID() + "\nCountry: " + + this.country + "\nPrice: " + + this.price + "\nHotel: " + + this.hotel; + } + public String toSave() { + return name + " | " + Integer.toString(nextId) + " | " + Integer.toString(id) + " | " + // startDate, endDate + hotel + " | " + Double.toString(price) + " | " + country + " | " + Integer.toString(maxParticipants) + + " | " + Integer.toString(numParticipants); + } } \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java index bb559adef6..f0d10525d6 100644 --- a/src/main/java/seedu/duke/command/AddCommand.java +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -9,12 +9,16 @@ public class AddCommand extends Command { private TravelPackage newPackage; - public AddCommand(String name, int date1, int date2, String hotel, double price, String country, + public AddCommand(String name, String date1, String date2, String hotel, double price, String country, int maxVacancies) { - this.newPackage = new TravelPackage(name, new Date(date1), new Date(date2), hotel, price, country, + this.newPackage = new TravelPackage(name, date1, date2, hotel, price, country, maxVacancies); } + public TravelPackage getPackage() { + return this.newPackage; + } + public void execute(Packages packages, Reservations r) { packages.addPackage(newPackage); } diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java new file mode 100644 index 0000000000..f431dd8d28 --- /dev/null +++ b/src/test/java/seedu/duke/ParserTest.java @@ -0,0 +1,81 @@ +package seedu.duke; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import seedu.duke.command.AddCommand; +import seedu.duke.command.ByeCommand; +import seedu.duke.command.Command; +import seedu.duke.command.HelpCommand; + +public class ParserTest { + + @Test + public void parse_ByeCommand_parsedCorrectly() { + final String input = "bye"; + parseAndAssertCommandType(input, ByeCommand.class); + } + + @Test + public void parse_helpCommand_parsedCorrectly() { + final String input = "help"; + parseAndAssertCommandType(input, HelpCommand.class); + } + + @Test + public void parse_addCommandValidPersonData_parsedCorrectly() { + final TravelPackage testPackage = generateTestTravelPackage(); + final String input = convertPersonToAddCommandString(testPackage); + final AddCommand result = parseAndAssertCommandType(input, AddCommand.class); + assertEquals(result.getPackage(), testPackage); + } + + /** + * Generates an instance of a {@code TravelPackage} from valid test data. + * + * @return an instance of a {@code TravelPackage}. + */ + private static TravelPackage generateTestTravelPackage() { + try { + return new TravelPackage( + TravelPackage.EXAMPLENAME, + TravelPackage.EXAMPLESTART, + TravelPackage.EXAMPLEEND, + TravelPackage.EXAMPLEHOTEL, + TravelPackage.EXAMPLEPRICE, + TravelPackage.EXAMPLECOUNTRY, + TravelPackage.EXAMPLEMAX); + } catch (Exception e) { + throw new RuntimeException("test person data should be valid by definition"); + } + } + + /** + * Generates an add command from a {@code TravelPackage}. + * + * @param t + * whose data will be filled into the string. + * @return a string describing an {@code AddCommand}. + */ + private static String convertPersonToAddCommandString(TravelPackage t) { + String addCommand = "add " + t.getName() + " " + t.getStartDate() + " " + t.getEndDate() + " " + + t.getHotel() + " " + t.getPrice() + " " + t.getCountry() + " " + t.getMaxParticipants(); + return addCommand; + } + + /** + * Parses input and asserts the class/type of the returned command object. + * + * @param input + * to be parsed + * @param expectedCommandClass + * expected class of returned command + * @return the parsed command object + */ + private T parseAndAssertCommandType(String input, Class expectedCommandClass) { + final Command result = Parser.parse(input); + assertTrue(result.getClass().isAssignableFrom(expectedCommandClass)); + return (T) result; + } +} From 20ee0cabda187c0621def0a6f6d4c6cecfd3a811 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 27 Mar 2022 23:31:39 +0800 Subject: [PATCH 036/131] Update to TARBS --- src/main/java/seedu/duke/{Duke.java => TARBS.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/seedu/duke/{Duke.java => TARBS.java} (100%) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/TARBS.java similarity index 100% rename from src/main/java/seedu/duke/Duke.java rename to src/main/java/seedu/duke/TARBS.java From 2b93114f45a65a20b59143ab12e31c24fabe2212 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 23:33:13 +0800 Subject: [PATCH 037/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 62a8bb5154..43fb94077f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -85,11 +85,11 @@ Aim: Displays a list of all available commands that the user can refer to as a g ## Feature - Storage #### Initialisation (Loading Data) -The sequence diagram that shows how `Storage` is created and the data is loaded from the saved files when the program is initialised is shown below: +The sequence diagram that shows how `Storage` is created and the data is loaded from the saved files when the program is initialised is shown below:
![](StorageSeqDiag.png) -1. `Duke` creates a Storage object with the relevant file names. -2. `Duke` then calls the `createPackages()` method of the Storage class +1. `TARBS` creates a Storage object with the relevant file names. +2. `TARBS` then calls the `createPackages()` method of the Storage class 3. `storage` will then load the contents of the file in the `Reservation` and `TravelPackages` file calling the different `parse` methods. The exact implementation is not shown in the diagram. 4. A new `Package` object is constructed with the relevant data. -5. `storage` returns `package` object to `Duke`. +5. `storage` returns `package` object to `TARBS`. From b6b12f9834550cbafc93bc0e056352fdb6ea976b Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 23:33:30 +0800 Subject: [PATCH 038/131] Delete StorageSeqDiag.png --- docs/StorageSeqDiag.png | Bin 15065 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/StorageSeqDiag.png diff --git a/docs/StorageSeqDiag.png b/docs/StorageSeqDiag.png deleted file mode 100644 index a276fc6a967395629456e7e94e674abc78c499a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15065 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 Zx#j80mpT&^;jSuyrmBugwbJ#l{{v1RYGD8X From 297d751ce9c69c97c21fc8b9a465c42397db42db Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 23:33:54 +0800 Subject: [PATCH 039/131] Add files via upload --- docs/StorageSeqDiag.png | Bin 0 -> 9932 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/StorageSeqDiag.png diff --git a/docs/StorageSeqDiag.png b/docs/StorageSeqDiag.png new file mode 100644 index 0000000000000000000000000000000000000000..684bb8807e7ed1df06ce14019eb0c4085964bc7e GIT binary patch literal 9932 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 literal 0 HcmV?d00001 From b371ad8fccd759d2bb823b4025ef94c0bed79b46 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 23:34:26 +0800 Subject: [PATCH 040/131] Delete StorageSeqDiag.png --- docs/StorageSeqDiag.png | Bin 9932 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/StorageSeqDiag.png diff --git a/docs/StorageSeqDiag.png b/docs/StorageSeqDiag.png deleted file mode 100644 index 684bb8807e7ed1df06ce14019eb0c4085964bc7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9932 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 From c6b416a4830db379b4272288e2e6afd0d7b393d2 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sun, 27 Mar 2022 23:34:43 +0800 Subject: [PATCH 041/131] Add files via upload --- docs/StorageSeqDiag.png | Bin 0 -> 9932 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/StorageSeqDiag.png diff --git a/docs/StorageSeqDiag.png b/docs/StorageSeqDiag.png new file mode 100644 index 0000000000000000000000000000000000000000..684bb8807e7ed1df06ce14019eb0c4085964bc7e GIT binary patch literal 9932 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 literal 0 HcmV?d00001 From a75449a9b16bacccf583b1064d7e9087a5c27592 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 27 Mar 2022 23:34:44 +0800 Subject: [PATCH 042/131] Update to TARBS --- src/main/java/seedu/duke/TARBS.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/TARBS.java b/src/main/java/seedu/duke/TARBS.java index 32020e07d3..c752bfbc9f 100644 --- a/src/main/java/seedu/duke/TARBS.java +++ b/src/main/java/seedu/duke/TARBS.java @@ -5,7 +5,7 @@ import seedu.duke.command.Command; -public class Duke { +public class TARBS { public static void main(String[] args) { run(); } From 1f74e319fd51471351cdafa467c1917c8236309b Mon Sep 17 00:00:00 2001 From: Brendan <53790951+bbawj@users.noreply.github.com> Date: Sun, 27 Mar 2022 23:55:38 +0800 Subject: [PATCH 043/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 43fb94077f..03fad9d8d5 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -93,3 +93,11 @@ The sequence diagram that shows how `Storage` is created and the data is loaded 3. `storage` will then load the contents of the file in the `Reservation` and `TravelPackages` file calling the different `parse` methods. The exact implementation is not shown in the diagram. 4. A new `Package` object is constructed with the relevant data. 5. `storage` returns `package` object to `TARBS`. + +## Feature - Parser +The sequence diagram shows an example of how a user input is parsed and returns a new `Command`. + +For simplicity, `ByeCommand` is shown here: + +![image](https://user-images.githubusercontent.com/53790951/160289728-5a17b2ea-0599-48f4-a18b-cadfbbcbfb11.png) + From d123fc4004e2989ebad9571938d76776a323735e Mon Sep 17 00:00:00 2001 From: chintaiann Date: Wed, 30 Mar 2022 00:21:55 +0800 Subject: [PATCH 044/131] v2.0 1. all input standardized to using [COMMAND] [INPUT,INPUT,INPUT] -> using commas to separate between multiple inputs 2. reservations only used by TravelPackage 3. feature to add and delete reservations by providing travelpackageID and other details 4. commented out storage code, needs review after this commit --- build.gradle | 1 + src/main/java/seedu/duke/Help.java | 4 +- src/main/java/seedu/duke/Packages.java | 13 +- src/main/java/seedu/duke/Parser.java | 64 ++-- src/main/java/seedu/duke/Reservation.java | 22 +- src/main/java/seedu/duke/Reservations.java | 12 +- src/main/java/seedu/duke/Storage.java | 275 +++++++++--------- src/main/java/seedu/duke/TARBS.java | 17 +- src/main/java/seedu/duke/TravelPackage.java | 45 ++- .../java/seedu/duke/command/AddCommand.java | 8 +- .../java/seedu/duke/command/ByeCommand.java | 2 +- src/main/java/seedu/duke/command/Command.java | 4 +- .../seedu/duke/command/DeleteCommand.java | 8 +- .../java/seedu/duke/command/ErrorCommand.java | 3 +- .../java/seedu/duke/command/HelpCommand.java | 2 +- .../seedu/duke/command/PackagesCommand.java | 2 +- .../command/RemoveReservationCommand.java | 31 ++ .../duke/command/ReservationCommand.java | 82 +----- .../duke/command/WrongFormatCommand.java | 2 +- src/test/java/seedu/duke/ParserTest.java | 1 + 20 files changed, 314 insertions(+), 284 deletions(-) create mode 100644 src/main/java/seedu/duke/command/RemoveReservationCommand.java diff --git a/build.gradle b/build.gradle index b0c5528fb5..91fffd027d 100644 --- a/build.gradle +++ b/build.gradle @@ -43,4 +43,5 @@ checkstyle { run{ standardInput = System.in + enableAssertions = true } diff --git a/src/main/java/seedu/duke/Help.java b/src/main/java/seedu/duke/Help.java index 3b9fabf4f5..0ba463cdbf 100644 --- a/src/main/java/seedu/duke/Help.java +++ b/src/main/java/seedu/duke/Help.java @@ -14,9 +14,9 @@ public Help(){ desc.add(add); String[] delete = {"Delete a package", "delete {num}"}; desc.add(delete); - String[] reserve = {"Create a reservation for a package", "reserve {package_number} {contact_name} {contact_number} {number_pax}"}; + String[] reserve = {"Create a reservation for a package", "reserve {package_number},{contact_name},{contact_number},{number_pax}"}; desc.add(reserve); - String[] remove = {"Remove a reservation", "remove {reservation_id}"}; + String[] remove = {"Remove a reservation","remove {travelpackageID},{contact_number}"}; desc.add(remove); String[] reservations = {"Shows all reservations for a package", "reservations {package_number}"}; desc.add(reservations); diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index db40d7af52..8cf997cb77 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -5,7 +5,6 @@ public class Packages { private ArrayList packages; - public Packages() { this.packages = new ArrayList<>(); } @@ -30,4 +29,16 @@ public void removePackage(int index) { packages.remove(index); } + + //check if packageID already exists. return true if already exists - unique IDs only! + public boolean idExists(int id) { + for (int i =0; i reservations; public Reservations() { this.reservations = new ArrayList<>(); } - public Reservations(ArrayList r) { this.reservations = r; } @@ -21,14 +22,21 @@ public int getReservationSize() { return reservations.size(); } + public void printAllReservations(){ + for (int i = 0; i t = parseTravelPackageFile(); - Packages p = new Packages(t); - return p; - } - - public Reservations createReservatons() { - ArrayList r = parseReservationFile(); - Reservations reservations = new Reservations(r); - return reservations; - } - - /** - * Parses the saved reservation file - * - * @return Arraylist of Reservations - */ - public ArrayList parseReservationFile() { - File rFile = new File(reservations_filePath); - ArrayList r = new ArrayList<>(); - try { - Scanner s = new Scanner(rFile); - while (s.hasNext()) { - String currentLine = s.nextLine(); - String[] arrayElements = currentLine.split("\\|"); - int reservationID = Integer.parseInt(arrayElements[0].trim()); - String packageID = arrayElements[1].trim(); - String customerName = arrayElements[2].trim(); - String customerNum = arrayElements[3].trim(); - int numPax = Integer.parseInt(arrayElements[4].trim()); - Reservation newReservation = new Reservation(reservationID, packageID, customerName, customerNum, - numPax); - r.add(newReservation); - } - } catch (FileNotFoundException e) { - System.out.println(e.getMessage()); - } - return r; - } - - /** - * Parses the saved travel packages file - * - * @return Arraylist of TravelPackage - */ - public ArrayList parseTravelPackageFile() { - ArrayList t = new ArrayList<>(); - File pFile = new File(packages_filePath); - try { - Scanner s = new Scanner(pFile); - while (s.hasNext()) { - String currentLine = s.nextLine(); - String[] arrayElements = currentLine.split("\\|"); - String name = arrayElements[0].trim(); - String start = arrayElements[1].trim(); - String end = arrayElements[2].trim(); - String hotel = arrayElements[3].trim(); - double price = Double.parseDouble(arrayElements[4].trim()); - String country = arrayElements[5].trim(); - int vacancies = Integer.parseInt(arrayElements[6].trim()); - TravelPackage newPackage = new TravelPackage(name, start, end, hotel, price, - country, vacancies); - t.add(newPackage); - } - } catch (FileNotFoundException e) { - System.out.println(e.getMessage()); - } - return t; - } -} +//package seedu.duke; +// +//import java.io.File; +//import java.io.FileNotFoundException; +//import java.io.FileWriter; +//import java.io.IOException; +//import java.util.ArrayList; +//import java.util.Date; +//import java.util.Scanner; +// +///** +// * Represents the controller to parse and write to a save file for packages and +// * reservations +// */ +//public class Storage { +// private String packages_filePath; +// private String reservations_filePath; +// +// /** +// * String representation of the file path to the save file +// * +// * @param package_path, +// * reservations_path +// */ +// public Storage(String package_path, String reservations_path) { +// this.packages_filePath = package_path; +// this.reservations_filePath = reservations_path; +// } +// +// /** +// * Writes the tasks in task list to the save file +// * +// */ +// public void convertListToFile(Packages p, Reservations r) { +// String text = ""; +// for (int i = 0; i < p.getSize(); i++) { +// TravelPackage currentPackage = p.getPackage(i); +// text = text + currentPackage.toSave() + System.lineSeparator(); +// } +// try { +// FileWriter fw = new FileWriter(packages_filePath); +// fw.write(text); +// fw.close(); +// } catch (IOException e) { +// System.out.println(e.getMessage()); +// } +// +// String resText = ""; +// for (int i = 0; i < r.getReservationSize(); i++) { +// Reservation currentReservation = r.getReservation(i); +// resText = resText + currentReservation.toSave() + System.lineSeparator(); +// } +// try { +// FileWriter fw = new FileWriter(reservations_filePath); +// fw.write(resText); +// fw.close(); +// } catch (IOException e) { +// System.out.println(e.getMessage()); +// } +// } +// +// /** +// * Calls the functions to read packages and reservations saved files +// * +// * @return Packages object for Control class +// */ +// public Packages createPackages() { +// ArrayList t = parseTravelPackageFile(); +// Packages p = new Packages(t); +// return p; +// } +// +// public Reservations createReservatons() { +// ArrayList r = parseReservationFile(); +// Reservations reservations = new Reservations(r); +// return reservations; +// } +// +// /** +// * Parses the saved reservation file +// * +// * @return Arraylist of Reservations +// */ +// public ArrayList parseReservationFile() { +// File rFile = new File(reservations_filePath); +// ArrayList r = new ArrayList<>(); +// try { +// Scanner s = new Scanner(rFile); +// while (s.hasNext()) { +// String currentLine = s.nextLine(); +// String[] arrayElements = currentLine.split("\\|"); +// +// String packageID = arrayElements[0].trim(); +// int packageId2 = Integer.parseInt(packageID); +// String customerName = arrayElements[1].trim(); +// String customerNum = arrayElements[2].trim(); +// int numPax = Integer.parseInt(arrayElements[4].trim()); +// Reservation newReservation = new Reservation(packageId2, customerName, customerNum, +// numPax); +// r.add(newReservation); +// } +// } catch (FileNotFoundException e) { +// System.out.println(e.getMessage()); +// } +// return r; +// } +// +// /** +// * Parses the saved travel packages file +// * +// * @return Arraylist of TravelPackage +// */ +// public ArrayList parseTravelPackageFile() { +// ArrayList t = new ArrayList<>(); +// File pFile = new File(packages_filePath); +// try { +// Scanner s = new Scanner(pFile); +// while (s.hasNext()) { +// String currentLine = s.nextLine(); +// String[] arrayElements = currentLine.split("\\|"); +// String name = arrayElements[0].trim(); +// String sid = arrayElements[1].trim(); +// int id = Integer.parseInt(sid); +// String start = arrayElements[2].trim(); +// String end = arrayElements[3].trim(); +// String hotel = arrayElements[4].trim(); +// double price = Double.parseDouble(arrayElements[5].trim()); +// String country = arrayElements[6].trim(); +// int vacancies = Integer.parseInt(arrayElements[7].trim()); +// TravelPackage newPackage = new TravelPackage(name, id, start, end, hotel, price, +// country, vacancies); +// t.add(newPackage); +// } +// } catch (FileNotFoundException e) { +// System.out.println(e.getMessage()); +// } +// return t; +// } +//} diff --git a/src/main/java/seedu/duke/TARBS.java b/src/main/java/seedu/duke/TARBS.java index c752bfbc9f..0f7a67265a 100644 --- a/src/main/java/seedu/duke/TARBS.java +++ b/src/main/java/seedu/duke/TARBS.java @@ -11,9 +11,15 @@ public static void main(String[] args) { } public static void run() { - Storage storage = new Storage("packages.txt", "reservations.txt"); - Packages packages = storage.createPackages(); - Reservations reservations = storage.createReservatons(); +// Storage storage = new Storage("packages.txt", "reservations.txt"); +// Packages packages = storage.createPackages(); +// Reservations reservations = storage.createReservatons(); + + //placeholder packages + Packages packages = new Packages(); + TravelPackage start = new TravelPackage("packagename", 0, "29/3/2022","29/4/2022","hotelname", 99.99,"countryname",20); + packages.addPackage(start); + boolean endProgram = false; System.out.println("Welcome to Travel Agency Booking Reservation System!"); Scanner sc = new Scanner(System.in); @@ -21,14 +27,15 @@ public static void run() { System.out.println("Please enter command: "); try { Command command = Parser.parse(sc.nextLine()); - command.execute(packages, reservations); +// command.execute(packages, reservations); + command.execute(packages); endProgram = command.getIsExit(); } catch (Exception ex) { System.out.println("Wrong format. All available" + " commands can be seen with the 'help' command"); } } - storage.convertListToFile(packages, reservations); +// storage.convertListToFile(packages, reservations); } } diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index f9b6e24999..536f1e9db5 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -1,9 +1,10 @@ package seedu.duke; -import java.util.Date; +import java.util.ArrayList; public class TravelPackage { public static final String EXAMPLENAME = "Switzerland - Conquer Summits"; + public static final int EXAMPLEID = 999; public static final String EXAMPLESTART = ""; public static final String EXAMPLEEND = ""; public static final String EXAMPLEHOTEL = "EXAMPLE HOTEL"; @@ -12,20 +13,21 @@ public class TravelPackage { public static final int EXAMPLEMAX = 10; private final String name; - private static int nextId = 1; private final int id; - private Date[] period; // [startDate,endDate] private final String startDate; private final String endDate; private final String hotel; private final double price; private final String country; private final int maxParticipants; - private final int numParticipants; + private int numParticipants; + private Reservations reservationList; - public TravelPackage(String name, String startDate, String endDate, + + public TravelPackage(String name,int id, String startDate, String endDate, String hotel, double price, String country, int maxParticipants) { this.name = name; + this.id = id; // this.period = [startDate,endDate]; this.startDate = startDate; this.endDate = endDate; @@ -34,15 +36,15 @@ public TravelPackage(String name, String startDate, String endDate, this.country = country; this.maxParticipants = maxParticipants; this.numParticipants = 0; - id = nextId++; + this.reservationList = new Reservations(); } public boolean isFull() { return this.numParticipants >= maxParticipants; } - public String getID() { - return "P" + this.id; + public int getID() { + return this.id; } public String getName() { @@ -73,6 +75,14 @@ public int getMaxParticipants() { return this.maxParticipants; } + public Reservations getReservationList() { + return this.reservationList; + }; + + public void setReservationList(Reservations r) { + this.reservationList = r; + } + public String toString() { return "Here are the details for " + this.name + ", Travel Package ID of " @@ -82,10 +92,19 @@ public String toString() { + this.hotel; } - public String toSave() { - return name + " | " + Integer.toString(nextId) + " | " + Integer.toString(id) + " | " + // startDate, endDate - hotel + " | " + Double.toString(price) + " | " + country + " | " + Integer.toString(maxParticipants) - + " | " + Integer.toString(numParticipants); - } + + + +// public String toSave() { +// return name + " | " + Integer.toString(nextId) + " | " + Integer.toString(id) + " | " + // startDate, endDate +// hotel + " | " + Double.toString(price) + " | " + country + " | " + Integer.toString(maxParticipants) +// + " | " + Integer.toString(numParticipants); +// } + + + + + + } \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java index f0d10525d6..cf018944e9 100644 --- a/src/main/java/seedu/duke/command/AddCommand.java +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -6,12 +6,14 @@ import seedu.duke.Reservations; import seedu.duke.TravelPackage; + +//creates a TravelPackage and adds to packages public class AddCommand extends Command { private TravelPackage newPackage; - public AddCommand(String name, String date1, String date2, String hotel, double price, String country, + public AddCommand(String name, int id,String date1, String date2, String hotel, double price, String country, int maxVacancies) { - this.newPackage = new TravelPackage(name, date1, date2, hotel, price, country, + this.newPackage = new TravelPackage(name, id,date1, date2, hotel, price, country, maxVacancies); } @@ -19,7 +21,7 @@ public TravelPackage getPackage() { return this.newPackage; } - public void execute(Packages packages, Reservations r) { + public void execute(Packages packages) { packages.addPackage(newPackage); } } diff --git a/src/main/java/seedu/duke/command/ByeCommand.java b/src/main/java/seedu/duke/command/ByeCommand.java index 80bc8519af..c86612b57e 100644 --- a/src/main/java/seedu/duke/command/ByeCommand.java +++ b/src/main/java/seedu/duke/command/ByeCommand.java @@ -8,7 +8,7 @@ public ByeCommand() { setIsExit(true); } - public void execute(Packages packages, Reservations r) { + public void execute(Packages packages) { System.out.println("Thank you for using TARBS. See you again!"); } } diff --git a/src/main/java/seedu/duke/command/Command.java b/src/main/java/seedu/duke/command/Command.java index 58b55b5beb..2a321debba 100644 --- a/src/main/java/seedu/duke/command/Command.java +++ b/src/main/java/seedu/duke/command/Command.java @@ -14,5 +14,7 @@ public void setIsExit(boolean isExit) { this.isExit = isExit; } - public abstract void execute(Packages packages, Reservations reservations); + public abstract void execute(Packages packages); + +// public abstract void execute(Packages packages, Reservations reservations); } diff --git a/src/main/java/seedu/duke/command/DeleteCommand.java b/src/main/java/seedu/duke/command/DeleteCommand.java index b8f558977c..a0d279274a 100644 --- a/src/main/java/seedu/duke/command/DeleteCommand.java +++ b/src/main/java/seedu/duke/command/DeleteCommand.java @@ -4,16 +4,16 @@ import seedu.duke.Reservations; public class DeleteCommand extends Command { - private final String id; + private final int id; - public DeleteCommand(String id) { + public DeleteCommand(int id) { this.id = id; } - public void execute(Packages packages, Reservations r) { + public void execute(Packages packages) { int numberOfPackages = packages.getSize(); for (int i = 0; i < numberOfPackages; i++) { - if (packages.getPackage(i).getID().equals(id)) { + if (packages.getPackage(i).getID() == (id)) { packages.removePackage(i); break; } diff --git a/src/main/java/seedu/duke/command/ErrorCommand.java b/src/main/java/seedu/duke/command/ErrorCommand.java index 12a70072a2..87c3a31241 100644 --- a/src/main/java/seedu/duke/command/ErrorCommand.java +++ b/src/main/java/seedu/duke/command/ErrorCommand.java @@ -10,9 +10,8 @@ public ErrorCommand(String input) { this.input = input; } - public void execute(Packages packages, Reservations r) { + public void execute(Packages packages) { System.out.println("Input not recognized: " + this.input); System.out.println("Use the help command to find out the valid commands."); - } } diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index f2d9f9452e..524c18ae80 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -6,7 +6,7 @@ public class HelpCommand extends Command { @Override - public void execute(Packages packages, Reservations r) { + public void execute(Packages packages) { final String SEPARATOR = "---------------------------------------------" + "--------------------------\n"; System.out.println(SEPARATOR + "SHOW ALL PACKAGES\nView a list of all available packages\n" + diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index f1052fb62d..8519fa2e9d 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -4,7 +4,7 @@ import seedu.duke.Reservations; public class PackagesCommand extends Command { - public void execute(Packages packages, Reservations r) { + public void execute(Packages packages) { for (int i = 0; i < packages.getSize(); i++) { System.out.println(packages.getPackage(i)); } diff --git a/src/main/java/seedu/duke/command/RemoveReservationCommand.java b/src/main/java/seedu/duke/command/RemoveReservationCommand.java new file mode 100644 index 0000000000..bda6eff288 --- /dev/null +++ b/src/main/java/seedu/duke/command/RemoveReservationCommand.java @@ -0,0 +1,31 @@ +package seedu.duke.command; + +import seedu.duke.Packages; +import seedu.duke.Reservation; +import seedu.duke.Reservations; + +public class RemoveReservationCommand extends Command{ + private int travelPackageID; + private String contact; + + public RemoveReservationCommand(int id,String contact){ + this.travelPackageID = id; + this.contact = contact; + } + public void execute(Packages packages) { + for (int i = 0; i < packages.getSize(); i++) { + if (packages.getPackage(i).getID() == this.travelPackageID) { + Reservations r = packages.getPackage(i).getReservationList(); + for (int j = 0; j < r.getReservationSize(); j++) { + if (this.contact.equals(r.getReservation(j).getContactNumber())){ + r.removeReservation(j); + break; + } + + } + + } + } + } + +} diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java index 86045be6a6..419b3926c8 100644 --- a/src/main/java/seedu/duke/command/ReservationCommand.java +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -2,82 +2,22 @@ import seedu.duke.Packages; import seedu.duke.Reservation; -import seedu.duke.Reservations; -import java.util.Scanner; +import java.util.Scanner; +//add reservation to TravelPackage using travelpackage id public class ReservationCommand extends Command { - public void execute(Packages packages, Reservations reservations) { - Scanner s = new Scanner(System.in); - System.out.println("Please choose which function you would like to perform for Reservations."); - System.out.println("1. Add Reservation"); - System.out.println("2. Remove Reservation"); - System.out.println("3. Check Reservations"); - int choice = Integer.parseInt(s.nextLine()); - switch (choice) { - case 1: - addReservation(reservations); - return; - case 2: - deleteReservation(reservations); - return; - case 3: - printReservation(reservations); - return; - default: - System.out.println("Please only enter numbers 1-3!"); - } - } - - public void printReservation(Reservations r) { - Scanner sc = new Scanner(System.in); - System.out.println("Enter Reservation ID to check details: "); - int index = sc.nextInt(); - boolean reservationFound = false; - for (int i = 0; i < r.getReservationSize(); i++) { - if (r.getReservation(i).getReservationID() == index) { - System.out.println(r.getReservation(i)); - reservationFound = true; - break; - } - } - if (!reservationFound) { - System.out.println("Reservation ID could not be found. Please try again with a valid ID."); - } - } + private Reservation newReservation; - public void addReservation(Reservations r) { - Scanner c = new Scanner(System.in); - System.out.println("Enter reservation ID: "); - final int rid = Integer.parseInt(c.nextLine()); - System.out.println("Enter customer name: "); - final String name = c.nextLine(); - System.out.println("Enter mobile number: "); - final String number = c.nextLine(); - System.out.println("Enter Travel Package ID: "); - final String tid = c.nextLine(); - System.out.println("Enter number of pax: "); - final int pax = Integer.parseInt(c.nextLine()); - - r.addReservation(new Reservation(rid, tid, name, number, pax)); + public ReservationCommand(int travelPackageID, String name, String number, int pax) { + this.newReservation = new Reservation(travelPackageID, name, number, pax); } - - public void deleteReservation(Reservations r) { - Scanner p = new Scanner(System.in); - System.out.println("Please enter the reservation ID to be deleted: "); - int index = p.nextInt(); - boolean deletionFound = false; - for (int i = 0; i < r.getReservationSize(); i++) { - if (r.getReservation(i).getReservationID() == index) { - System.out.println("Deleting Reservation"); - r.removeReservation(i); - deletionFound = true; - break; + public void execute(Packages packages) { + for (int i =0;i Date: Wed, 30 Mar 2022 22:38:23 +0800 Subject: [PATCH 045/131] Add exception handling and print reservations --- src/main/java/seedu/duke/Packages.java | 16 +++++++++--- src/main/java/seedu/duke/Parser.java | 23 +++++++++------- src/main/java/seedu/duke/Reservations.java | 26 ++++++++++++++----- .../java/seedu/duke/command/AddCommand.java | 13 +++++++--- .../command/PrintReservationsCommand.java | 21 +++++++++++++++ 5 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 src/main/java/seedu/duke/command/PrintReservationsCommand.java diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index 8cf997cb77..378a5c8b18 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -5,6 +5,7 @@ public class Packages { private ArrayList packages; + public Packages() { this.packages = new ArrayList<>(); } @@ -21,6 +22,15 @@ public TravelPackage getPackage(int index) { return packages.get(index); } + public TravelPackage getPackageByID(int id) { + for (TravelPackage travelPackage : packages) { + if (travelPackage.getID() == id) { + return travelPackage; + } + } + return null; + } + public void addPackage(TravelPackage newPackage) { packages.add(newPackage); } @@ -29,10 +39,10 @@ public void removePackage(int index) { packages.remove(index); } - - //check if packageID already exists. return true if already exists - unique IDs only! + // check if packageID already exists. return true if already exists - unique IDs + // only! public boolean idExists(int id) { - for (int i =0; i(); } + public Reservations(ArrayList r) { this.reservations = r; } @@ -22,21 +23,34 @@ public int getReservationSize() { return reservations.size(); } - public void printAllReservations(){ - for (int i = 0; i Date: Thu, 31 Mar 2022 13:31:56 +0800 Subject: [PATCH 046/131] Add override equals for testing --- build.gradle | 3 ++ src/main/java/seedu/duke/TravelPackage.java | 35 ++++++++++++++------- src/test/java/seedu/duke/ParserTest.java | 5 +-- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index 91fffd027d..4f9c8f5e70 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,9 @@ repositories { dependencies { testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' + testImplementation('org.junit.platform:junit-platform-launcher:1.5.2') + // testImplementation(platform('org.junit:junit-bom:5.8.2')) + // testImplementation('org.junit.jupiter:junit-jupiter') } test { diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 536f1e9db5..d3e9d1dccc 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -23,8 +23,7 @@ public class TravelPackage { private int numParticipants; private Reservations reservationList; - - public TravelPackage(String name,int id, String startDate, String endDate, + public TravelPackage(String name, int id, String startDate, String endDate, String hotel, double price, String country, int maxParticipants) { this.name = name; this.id = id; @@ -92,19 +91,31 @@ public String toString() { + this.hotel; } + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || obj.getClass() != this.getClass()) { + return false; + } + TravelPackage cur = (TravelPackage) obj; + return cur.getID() == this.getID() && cur.getName().equals(this.getName()) + && cur.getStartDate().equals(this.getStartDate()) + && cur.getEndDate().equals(this.getEndDate()) && cur.getHotel().equals(this.getHotel()) + && cur.getPrice() == this.getPrice() && + cur.getCountry().equals(this.getCountry()) && cur.getMaxParticipants() == this.getMaxParticipants(); -// public String toSave() { -// return name + " | " + Integer.toString(nextId) + " | " + Integer.toString(id) + " | " + // startDate, endDate -// hotel + " | " + Double.toString(price) + " | " + country + " | " + Integer.toString(maxParticipants) -// + " | " + Integer.toString(numParticipants); -// } - - - - - + } + // public String toSave() { + // return name + " | " + Integer.toString(nextId) + " | " + Integer.toString(id) + // + " | " + // startDate, endDate + // hotel + " | " + Double.toString(price) + " | " + country + " | " + + // Integer.toString(maxParticipants) + // + " | " + Integer.toString(numParticipants); + // } } \ No newline at end of file diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index 873b97ee0e..5cfd325aa4 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -60,8 +60,9 @@ private static TravelPackage generateTestTravelPackage() { * @return a string describing an {@code AddCommand}. */ private static String convertPersonToAddCommandString(TravelPackage t) { - String addCommand = "add " + t.getName() + " " + t.getStartDate() + " " + t.getEndDate() + " " + - t.getHotel() + " " + t.getPrice() + " " + t.getCountry() + " " + t.getMaxParticipants(); + String addCommand = "add " + t.getName() + "," + t.getID() + "," + t.getStartDate() + "," + t.getEndDate() + "," + + + t.getHotel() + "," + t.getPrice() + "," + t.getCountry() + "," + t.getMaxParticipants(); return addCommand; } From 6e0658cb7564715ca42db2556fc1bf33e4cbec9a Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Thu, 31 Mar 2022 15:02:56 +0800 Subject: [PATCH 047/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 03fad9d8d5..0dd449b83c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -94,6 +94,15 @@ The sequence diagram that shows how `Storage` is created and the data is loaded 4. A new `Package` object is constructed with the relevant data. 5. `storage` returns `package` object to `TARBS`. +#### Saving data +The sequence diagram that shows how `Storage` is used to save the current list of travel packages and reservations is shown below:
+ +![](SaveFilesSeqDiag.png) + +1. `TARBS` calls the `savePackages()` method of `storage`. +2. `storage` will then write the contents of the two ArrayLists of `Reservation` and `TravelPackages` objects into text files by calling the respective `save` methods. The exact implementation is not shown in the diagram. + + ## Feature - Parser The sequence diagram shows an example of how a user input is parsed and returns a new `Command`. From 86fc569664b10a40df45ae7c02aa8649727ef018 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Thu, 31 Mar 2022 15:03:47 +0800 Subject: [PATCH 048/131] Add files via upload --- docs/SaveFileSeqDiag.png | Bin 0 -> 17527 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/SaveFileSeqDiag.png diff --git a/docs/SaveFileSeqDiag.png b/docs/SaveFileSeqDiag.png new file mode 100644 index 0000000000000000000000000000000000000000..09ba074e7d72760737190a099e4601ab89cfef64 GIT binary patch literal 17527 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 z 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 aqrQJ>sic352mX@C83h>?RH4+v!2bafx?zO? literal 0 HcmV?d00001 From 57709594c4b25e359d485e24840015891f7ec498 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Thu, 31 Mar 2022 15:04:36 +0800 Subject: [PATCH 049/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0dd449b83c..a0beab3961 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -97,7 +97,7 @@ The sequence diagram that shows how `Storage` is created and the data is loaded #### Saving data The sequence diagram that shows how `Storage` is used to save the current list of travel packages and reservations is shown below:
-![](SaveFilesSeqDiag.png) +![](SaveFileSeqDiag.png) 1. `TARBS` calls the `savePackages()` method of `storage`. 2. `storage` will then write the contents of the two ArrayLists of `Reservation` and `TravelPackages` objects into text files by calling the respective `save` methods. The exact implementation is not shown in the diagram. From 24cd45692c67a3c8a69d4aaf6a5ceb005b7e4561 Mon Sep 17 00:00:00 2001 From: chintaiann Date: Thu, 31 Mar 2022 18:26:51 +0800 Subject: [PATCH 050/131] v2.0 1. implemented functionality of not allowing reservations to be added if exceeds maxParticipants 2. error message when travelID not found during adding/removing reservations 3. adding/deletion of reservations will correctly alter number of participants now --- src/main/java/seedu/duke/Parser.java | 1 - src/main/java/seedu/duke/TravelPackage.java | 17 +++++++++++++++-- .../command/RemoveReservationCommand.java | 19 ++++++++++++++++++- .../duke/command/ReservationCommand.java | 18 +++++++++++++++++- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index f61cbdd606..1a4b0809f2 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -6,7 +6,6 @@ public class Parser { public static Command parse(String input) { String[] inputArray = input.split(" "); String commandType = inputArray[0]; - System.out.println(commandType); int id; String start; String end; diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index d3e9d1dccc..18d3e33e17 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -74,10 +74,21 @@ public int getMaxParticipants() { return this.maxParticipants; } + public int getNumParticipants() {return this.numParticipants;} + public Reservations getReservationList() { return this.reservationList; }; + public void addParticipants(int addParticipants) { + this.numParticipants = this.numParticipants + addParticipants; + } + + public void removeParticipants(int removeParticipants) { + this.numParticipants = this.numParticipants - removeParticipants; + } + + public void setReservationList(Reservations r) { this.reservationList = r; } @@ -88,8 +99,10 @@ public String toString() { + this.getID() + "\nCountry: " + this.country + "\nPrice: " + this.price + "\nHotel: " - + this.hotel; - } + + this.hotel + "\nVacancies Filled: " + + this.numParticipants + "/" + this.maxParticipants + "\nTravel Period: " + + this.startDate + "-" + this.endDate + ;} @Override public boolean equals(Object obj) { diff --git a/src/main/java/seedu/duke/command/RemoveReservationCommand.java b/src/main/java/seedu/duke/command/RemoveReservationCommand.java index bda6eff288..3a8c853aa9 100644 --- a/src/main/java/seedu/duke/command/RemoveReservationCommand.java +++ b/src/main/java/seedu/duke/command/RemoveReservationCommand.java @@ -13,19 +13,36 @@ public RemoveReservationCommand(int id,String contact){ this.contact = contact; } public void execute(Packages packages) { + boolean foundID = false; for (int i = 0; i < packages.getSize(); i++) { if (packages.getPackage(i).getID() == this.travelPackageID) { Reservations r = packages.getPackage(i).getReservationList(); for (int j = 0; j < r.getReservationSize(); j++) { if (this.contact.equals(r.getReservation(j).getContactNumber())){ - r.removeReservation(j); + //check that numParticipants do not go below 0. + int result = packages.getPackage(i).getNumParticipants() - r.getReservation(j).getNumOfPax(); + if (( 0 <= result) && (result < packages.getPackage(i).getMaxParticipants())) { + packages.getPackage(i).removeParticipants(r.getReservation(j).getNumOfPax()); + r.removeReservation(j); + + } + else { + System.out.println("Removing too many participants. Please try again."); + } + foundID = true; break; } + } } } + if (!foundID) { + System.out.println("Travel Package ID or Mobile Phone not found. Please try again."); + } + + } } diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java index 419b3926c8..7066c72104 100644 --- a/src/main/java/seedu/duke/command/ReservationCommand.java +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -13,11 +13,27 @@ public ReservationCommand(int travelPackageID, String name, String number, int p this.newReservation = new Reservation(travelPackageID, name, number, pax); } public void execute(Packages packages) { + boolean foundID = false; for (int i =0;i packages.getPackage(i).getMaxParticipants()) { + System.out.println("Too many participants, maximum amount of participants will be exceeded. Please try again."); + } + else { + packages.getPackage(i).getReservationList().addReservation(this.newReservation); + packages.getPackage(i).addParticipants(newReservation.getNumOfPax()); + } + foundID = true; + break; + } } + if (!foundID) { + System.out.println("Travel Package ID not found. Please try again."); + } + + } } From b8da5d6f7485cf5a9a003cfb6bf8b01c319590a7 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Thu, 31 Mar 2022 18:45:57 +0800 Subject: [PATCH 051/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a0beab3961..a7fca06a4a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -74,10 +74,10 @@ | ------- | --------------- | |packages|packages| |info|info {num} (num < number of available packages)
e.g. info 2 | -|add|add {package_name} {country} {duration} {price} {vacancies}
e.g. add Skiing_Trip Sweden 15/2/2022-19/2/2022 800 100| +|add|add {package_name},{ID},{startDate},{endDate},{hotel},{price},{country},{vacancies}
e.g. add Skiing Trip,1,23/2/2022,24/2/2022,hotelName,90.99,Singapore,20| |delete|delete {num} (num < number of available packages)
e.g. delete 2| -|reserve|reserve {package_number} {contact_name} {contact_number} {number_pax}
e..g reserve 3 John 91234567 3 | -|remove|remove {reservation_id}
e..g remove R001| +|reserve|reserve {package_id},{contact_name},{contact_number},{number_pax}
e..g reserve 3,John,91234567,3| +|remove|remove {package_id},{contact_number}
e..g remove 1,8888888| |reservations|reservations {package_number}
eg. reservations 2| ## Feature - Help Command From c58d4351e30323cf89b47a06269dbad11fc0974f Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Thu, 31 Mar 2022 18:48:27 +0800 Subject: [PATCH 052/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a7fca06a4a..94eb51cb0f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -72,13 +72,13 @@ | Command | Format Examples | | ------- | --------------- | -|packages|packages| +|packages|packages
(prints details of all packages)| |info|info {num} (num < number of available packages)
e.g. info 2 | -|add|add {package_name},{ID},{startDate},{endDate},{hotel},{price},{country},{vacancies}
e.g. add Skiing Trip,1,23/2/2022,24/2/2022,hotelName,90.99,Singapore,20| -|delete|delete {num} (num < number of available packages)
e.g. delete 2| -|reserve|reserve {package_id},{contact_name},{contact_number},{number_pax}
e..g reserve 3,John,91234567,3| -|remove|remove {package_id},{contact_number}
e..g remove 1,8888888| -|reservations|reservations {package_number}
eg. reservations 2| +|add|add {package_name},{ID},{startDate},{endDate},{hotel},{price},{country},{vacancies}
e.g. add Skiing Trip,1,23/2/2022,24/2/2022,hotelName,90.99,Singapore,20
adds a TravelPackage| +|delete|delete {num} (num < number of available packages)
e.g. delete 2
delete a TravelPackage| +|reserve|reserve {package_id},{contact_name},{contact_number},{number_pax}
e.g reserve 3,John,91234567,3| +|remove|remove {package_id},{contact_number}
e.g remove 1,8888888
remove an existing reservation| +|reservations|reservations {package_number}
eg. reservations 2
print all reservations for a given travelPackageID| ## Feature - Help Command Aim: Displays a list of all available commands that the user can refer to as a guide From dcabde9a1dd5f72b9449ddfccc574000ecccd4a3 Mon Sep 17 00:00:00 2001 From: mafpovbul Date: Thu, 31 Mar 2022 19:25:12 +0800 Subject: [PATCH 053/131] Update storage --- data.txt | 1 + src/main/java/seedu/duke/Reservation.java | 7 +- src/main/java/seedu/duke/Storage.java | 270 ++++++++++---------- src/main/java/seedu/duke/TARBS.java | 13 +- src/main/java/seedu/duke/TravelPackage.java | 40 ++- 5 files changed, 170 insertions(+), 161 deletions(-) create mode 100644 data.txt diff --git a/data.txt b/data.txt new file mode 100644 index 0000000000..8cd1d8f418 --- /dev/null +++ b/data.txt @@ -0,0 +1 @@ +packagename | 0 | 29/3/2022 | 29/4/2022 | hotelname | 99.99 | countryname | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% diff --git a/src/main/java/seedu/duke/Reservation.java b/src/main/java/seedu/duke/Reservation.java index d06580af7b..2144c97716 100644 --- a/src/main/java/seedu/duke/Reservation.java +++ b/src/main/java/seedu/duke/Reservation.java @@ -38,8 +38,7 @@ public String toString() { + "Pax " + getNumOfPax() + "\n"; } -// public String toSave() { -// return Integer.toString(reservationID) + " | " + packageID + " | " + customerName + " | " + contactNumber -// + " | " + Integer.toString(numOfPax); -// } + public String toSave() { + return Integer.toString(packageID) + "," + customerName + "," + contactNumber + "," + Integer.toString(numOfPax); + } } diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index b6bfe0a0f8..1771e212bd 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -1,139 +1,131 @@ -//package seedu.duke; -// -//import java.io.File; -//import java.io.FileNotFoundException; -//import java.io.FileWriter; -//import java.io.IOException; -//import java.util.ArrayList; -//import java.util.Date; -//import java.util.Scanner; -// -///** -// * Represents the controller to parse and write to a save file for packages and -// * reservations -// */ -//public class Storage { -// private String packages_filePath; -// private String reservations_filePath; -// -// /** -// * String representation of the file path to the save file -// * -// * @param package_path, -// * reservations_path -// */ -// public Storage(String package_path, String reservations_path) { -// this.packages_filePath = package_path; -// this.reservations_filePath = reservations_path; -// } -// -// /** -// * Writes the tasks in task list to the save file -// * -// */ -// public void convertListToFile(Packages p, Reservations r) { -// String text = ""; -// for (int i = 0; i < p.getSize(); i++) { -// TravelPackage currentPackage = p.getPackage(i); -// text = text + currentPackage.toSave() + System.lineSeparator(); -// } -// try { -// FileWriter fw = new FileWriter(packages_filePath); -// fw.write(text); -// fw.close(); -// } catch (IOException e) { -// System.out.println(e.getMessage()); -// } -// -// String resText = ""; -// for (int i = 0; i < r.getReservationSize(); i++) { -// Reservation currentReservation = r.getReservation(i); -// resText = resText + currentReservation.toSave() + System.lineSeparator(); -// } -// try { -// FileWriter fw = new FileWriter(reservations_filePath); -// fw.write(resText); -// fw.close(); -// } catch (IOException e) { -// System.out.println(e.getMessage()); -// } -// } -// -// /** -// * Calls the functions to read packages and reservations saved files -// * -// * @return Packages object for Control class -// */ -// public Packages createPackages() { -// ArrayList t = parseTravelPackageFile(); -// Packages p = new Packages(t); -// return p; -// } -// -// public Reservations createReservatons() { -// ArrayList r = parseReservationFile(); -// Reservations reservations = new Reservations(r); -// return reservations; -// } -// -// /** -// * Parses the saved reservation file -// * -// * @return Arraylist of Reservations -// */ -// public ArrayList parseReservationFile() { -// File rFile = new File(reservations_filePath); -// ArrayList r = new ArrayList<>(); -// try { -// Scanner s = new Scanner(rFile); -// while (s.hasNext()) { -// String currentLine = s.nextLine(); -// String[] arrayElements = currentLine.split("\\|"); -// -// String packageID = arrayElements[0].trim(); -// int packageId2 = Integer.parseInt(packageID); -// String customerName = arrayElements[1].trim(); -// String customerNum = arrayElements[2].trim(); -// int numPax = Integer.parseInt(arrayElements[4].trim()); -// Reservation newReservation = new Reservation(packageId2, customerName, customerNum, -// numPax); -// r.add(newReservation); -// } -// } catch (FileNotFoundException e) { -// System.out.println(e.getMessage()); -// } -// return r; -// } -// -// /** -// * Parses the saved travel packages file -// * -// * @return Arraylist of TravelPackage -// */ -// public ArrayList parseTravelPackageFile() { -// ArrayList t = new ArrayList<>(); -// File pFile = new File(packages_filePath); -// try { -// Scanner s = new Scanner(pFile); -// while (s.hasNext()) { -// String currentLine = s.nextLine(); -// String[] arrayElements = currentLine.split("\\|"); -// String name = arrayElements[0].trim(); -// String sid = arrayElements[1].trim(); -// int id = Integer.parseInt(sid); -// String start = arrayElements[2].trim(); -// String end = arrayElements[3].trim(); -// String hotel = arrayElements[4].trim(); -// double price = Double.parseDouble(arrayElements[5].trim()); -// String country = arrayElements[6].trim(); -// int vacancies = Integer.parseInt(arrayElements[7].trim()); -// TravelPackage newPackage = new TravelPackage(name, id, start, end, hotel, price, -// country, vacancies); -// t.add(newPackage); -// } -// } catch (FileNotFoundException e) { -// System.out.println(e.getMessage()); -// } -// return t; -// } -//} +package seedu.duke; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +/** + * Represents the controller to parse and write to a save file for packages and + * reservations + */ +public class Storage { + private String filePath; + + /** + * String representation of the file path to the save file + * + * @param filePath + */ + public Storage(String filePath) { + this.filePath = filePath; + } + + /** + * Saves the data into text file specified in file_path + * + */ + public void savePackageToFile(Packages p) { + String text = ""; + for (int i = 0; i < p.getSize(); i++) { + TravelPackage currentPackage = p.getPackage(i); + text = text + currentPackage.saveTravelPackage() + System.lineSeparator(); + } + try { + FileWriter fw = new FileWriter(filePath); + fw.write(text); + fw.close(); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } + + /** + * Calls the functions to read saved files, creating a new Package object + * + * @return Packages object for Control class + */ + public Packages createPackages() { + ArrayList t = parseSavedFile(); + Packages p = new Packages(t); + return p; + } + + /** + * Calls the functions to read string data after splitting using regex + * + * @return ArrayList object for createPackages method + */ + public ArrayList parseSavedFile(){ + ArrayList t = new ArrayList<>(); + File pFile = new File(filePath); + try { + Scanner s = new Scanner(pFile); + while (s.hasNext()) { + String currentLine = s.nextLine(); + String[] arrayElements = currentLine.split("\\$"); + TravelPackage newPackage = parseTravelPackageFile(arrayElements[0]); + Reservations newReservations = parseReservationFile(arrayElements[1]); + newPackage.setReservationList(newReservations); + t.add(newPackage); + } + } catch (FileNotFoundException e) { + System.out.println(e.getMessage()); + } + return t; + } + + /** + * Iterates through the chunk of Reservation string data + * + * @return Reservations object + */ + public Reservations parseReservationFile(String str) { + Reservations rList = new Reservations(); + String[] arrayElements = str.split("%"); + for (int i=0; i< arrayElements.length; i++){ + Reservation newR = parseReservation(arrayElements[i]); + rList.addReservation(newR); + } + return rList; + } + + /** + * Parses individual reservation strings + * + * @return Reservation + */ + public Reservation parseReservation(String str){ + String[] arrayElements = str.split(","); + int packageID = Integer.parseInt(arrayElements[0].trim()); + String customerName = arrayElements[1].trim(); + String customerNum = arrayElements[2].trim(); + int numPax = Integer.parseInt(arrayElements[3].trim()); + Reservation r = new Reservation(packageID, customerName, customerNum, numPax); + return r; + } + + /** + * Parses the individual travel packages string + * + * @return TravelPackage object + */ + public TravelPackage parseTravelPackageFile(String str) { + String[] arrayElements = str.split("\\|"); + String name = arrayElements[0].trim(); + String sid = arrayElements[1].trim(); + int id = Integer.parseInt(sid); + String start = arrayElements[2].trim(); + String end = arrayElements[3].trim(); + String hotel = arrayElements[4].trim(); + double price = Double.parseDouble(arrayElements[5].trim()); + String country = arrayElements[6].trim(); + int vacancies = Integer.parseInt(arrayElements[7].trim()); + int numParticipants = Integer.parseInt(arrayElements[8].trim()); + TravelPackage newPackage = new TravelPackage(name, id, start, end, hotel, price, country, vacancies, numParticipants); + return newPackage; + } +} + diff --git a/src/main/java/seedu/duke/TARBS.java b/src/main/java/seedu/duke/TARBS.java index 0f7a67265a..ddd7438507 100644 --- a/src/main/java/seedu/duke/TARBS.java +++ b/src/main/java/seedu/duke/TARBS.java @@ -1,6 +1,5 @@ package seedu.duke; -import java.util.ArrayList; import java.util.Scanner; import seedu.duke.command.Command; @@ -11,14 +10,8 @@ public static void main(String[] args) { } public static void run() { -// Storage storage = new Storage("packages.txt", "reservations.txt"); -// Packages packages = storage.createPackages(); -// Reservations reservations = storage.createReservatons(); - - //placeholder packages - Packages packages = new Packages(); - TravelPackage start = new TravelPackage("packagename", 0, "29/3/2022","29/4/2022","hotelname", 99.99,"countryname",20); - packages.addPackage(start); + Storage storage = new Storage("data.txt"); + Packages packages = storage.createPackages(); boolean endProgram = false; System.out.println("Welcome to Travel Agency Booking Reservation System!"); @@ -35,7 +28,7 @@ public static void run() { " commands can be seen with the 'help' command"); } } -// storage.convertListToFile(packages, reservations); + storage.savePackageToFile(packages); } } diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 18d3e33e17..1f0bc08fd7 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -37,6 +37,20 @@ public TravelPackage(String name, int id, String startDate, String endDate, this.numParticipants = 0; this.reservationList = new Reservations(); } + public TravelPackage(String name, int id, String startDate, String endDate, + String hotel, double price, String country, int maxParticipants, int numParticipants) { + this.name = name; + this.id = id; + // this.period = [startDate,endDate]; + this.startDate = startDate; + this.endDate = endDate; + this.hotel = hotel; + this.price = price; + this.country = country; + this.maxParticipants = maxParticipants; + this.numParticipants = numParticipants; + this.reservationList = new Reservations(); + } public boolean isFull() { return this.numParticipants >= maxParticipants; @@ -123,12 +137,22 @@ public boolean equals(Object obj) { } - // public String toSave() { - // return name + " | " + Integer.toString(nextId) + " | " + Integer.toString(id) - // + " | " + // startDate, endDate - // hotel + " | " + Double.toString(price) + " | " + country + " | " + - // Integer.toString(maxParticipants) - // + " | " + Integer.toString(numParticipants); - // } + public String saveTravelPackage(){ + String str = toSave() + "$"; + for (int i=0; i Date: Thu, 31 Mar 2022 20:01:39 +0800 Subject: [PATCH 054/131] Update TARBS.java --- src/main/java/seedu/duke/TARBS.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/duke/TARBS.java b/src/main/java/seedu/duke/TARBS.java index ddd7438507..eac3081e8e 100644 --- a/src/main/java/seedu/duke/TARBS.java +++ b/src/main/java/seedu/duke/TARBS.java @@ -27,6 +27,7 @@ public static void run() { System.out.println("Wrong format. All available" + " commands can be seen with the 'help' command"); } + storage.savePackageToFile(packages); } storage.savePackageToFile(packages); } From 8876ca13ea019e5b4c7d1c5fa9133a06a1f8dab4 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Thu, 31 Mar 2022 20:31:27 +0800 Subject: [PATCH 055/131] Delete SaveFileSeqDiag.png --- docs/SaveFileSeqDiag.png | Bin 17527 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/SaveFileSeqDiag.png diff --git a/docs/SaveFileSeqDiag.png b/docs/SaveFileSeqDiag.png deleted file mode 100644 index 09ba074e7d72760737190a099e4601ab89cfef64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17527 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 z 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 aqrQJ>sic352mX@C83h>?RH4+v!2bafx?zO? From da2c5b8bbefcd1c0284a5347ca1f03230ae6c1c5 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Thu, 31 Mar 2022 20:31:33 +0800 Subject: [PATCH 056/131] Delete StorageSeqDiag.png --- docs/StorageSeqDiag.png | Bin 9932 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/StorageSeqDiag.png diff --git a/docs/StorageSeqDiag.png b/docs/StorageSeqDiag.png deleted file mode 100644 index 684bb8807e7ed1df06ce14019eb0c4085964bc7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9932 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 From 66050d929c787d8cd1d024ed129aee059d8b4106 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Thu, 31 Mar 2022 20:31:53 +0800 Subject: [PATCH 057/131] Add files via upload --- docs/LoadFileSeqDiag.png | Bin 0 -> 24095 bytes docs/SaveFileSeqDiag.png | Bin 0 -> 32425 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/LoadFileSeqDiag.png create mode 100644 docs/SaveFileSeqDiag.png diff --git a/docs/LoadFileSeqDiag.png b/docs/LoadFileSeqDiag.png new file mode 100644 index 0000000000000000000000000000000000000000..7843c8c490fbdc58883a9350a411bc89513b5ab4 GIT binary patch literal 24095 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 literal 0 HcmV?d00001 diff --git a/docs/SaveFileSeqDiag.png b/docs/SaveFileSeqDiag.png new file mode 100644 index 0000000000000000000000000000000000000000..cbfa0158f6be8a9305b29b725dc11d542267f71d GIT binary patch literal 32425 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

+OD~g&T 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 Date: Thu, 31 Mar 2022 20:32:56 +0800 Subject: [PATCH 058/131] Delete SaveFileSeqDiag.png --- docs/SaveFileSeqDiag.png | Bin 32425 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/SaveFileSeqDiag.png diff --git a/docs/SaveFileSeqDiag.png b/docs/SaveFileSeqDiag.png deleted file mode 100644 index cbfa0158f6be8a9305b29b725dc11d542267f71d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32425 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

+OD~g&T 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 Date: Thu, 31 Mar 2022 20:33:08 +0800 Subject: [PATCH 059/131] Add files via upload --- docs/SaveFilesSeqDiag.png | Bin 0 -> 32425 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/SaveFilesSeqDiag.png diff --git a/docs/SaveFilesSeqDiag.png b/docs/SaveFilesSeqDiag.png new file mode 100644 index 0000000000000000000000000000000000000000..cbfa0158f6be8a9305b29b725dc11d542267f71d GIT binary patch literal 32425 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

+OD~g&T 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 Date: Thu, 31 Mar 2022 20:38:55 +0800 Subject: [PATCH 060/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 94eb51cb0f..74bdb43daf 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -86,22 +86,22 @@ Aim: Displays a list of all available commands that the user can refer to as a g ## Feature - Storage #### Initialisation (Loading Data) The sequence diagram that shows how `Storage` is created and the data is loaded from the saved files when the program is initialised is shown below:
-![](StorageSeqDiag.png) +![](LoadFileSeqDiag.png) -1. `TARBS` creates a Storage object with the relevant file names. +1. `TARBS` creates a Storage object with the relevant file name (`filePath`). 2. `TARBS` then calls the `createPackages()` method of the Storage class -3. `storage` will then load the contents of the file in the `Reservation` and `TravelPackages` file calling the different `parse` methods. The exact implementation is not shown in the diagram. -4. A new `Package` object is constructed with the relevant data. -5. `storage` returns `package` object to `TARBS`. +3. `storage` will call the `parseSavedFile()` method, which initiates a while loop that iterates through the text file and processes the string data using the respective `parse` methods. +4. A new `TravelPackage` object is constructed with the relevant data. +5. A new `Packages` object is created using the `TravelPackage` object and returned back to `TARBS`. #### Saving data The sequence diagram that shows how `Storage` is used to save the current list of travel packages and reservations is shown below:
-![](SaveFileSeqDiag.png) - -1. `TARBS` calls the `savePackages()` method of `storage`. -2. `storage` will then write the contents of the two ArrayLists of `Reservation` and `TravelPackages` objects into text files by calling the respective `save` methods. The exact implementation is not shown in the diagram. +![](SaveFilesSeqDiag.png) +1. `TARBS` calls the `savePackageToFile()` method of `storage`, passing in the `packages` object. +2. `storage` will then use a loop to iteratively retrieve the data in string format from the individual `TravelPackage` objects. +3. `storage` will create a new `FileWriter` object to write the string data into a text file. ## Feature - Parser The sequence diagram shows an example of how a user input is parsed and returns a new `Command`. From 15874e3f23e0c1461d61530b48ce206b7508cc19 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Mar 2022 21:03:14 +0800 Subject: [PATCH 061/131] Add SLAP for parser --- src/main/java/seedu/duke/Parser.java | 157 ++++++++++++------ .../duke/command/WrongFormatCommand.java | 1 - 2 files changed, 102 insertions(+), 56 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 1a4b0809f2..3e7fa73744 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,79 +1,126 @@ package seedu.duke; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import seedu.duke.command.*; public class Parser { + + /** + * Used for initial separation of command word and args. + */ + public static final Pattern BASIC_COMMAND_FORMAT = Pattern.compile("(?\\S+)(?.*)"); + public static Command parse(String input) { - String[] inputArray = input.split(" "); - String commandType = inputArray[0]; - int id; - String start; - String end; - int vacancies; - double price; - String name; - String hotel; - String country; - - switch (commandType) { + final Matcher matcher = BASIC_COMMAND_FORMAT.matcher(input.trim()); + if (!matcher.matches()) { + return new WrongFormatCommand(input); + } + + final String commandWord = matcher.group("commandWord"); + final String arguments = matcher.group("arguments"); + + switch (commandWord) { case "bye": return new ByeCommand(); + case "help": return new HelpCommand(); + case "add": - String[] temp = input.split(" ", 2); // remove add from string - String[] temp1 = temp[1].split(","); // process the rest and split by comma - - System.out.println(temp.length); - if (temp1.length != 8) { - return new WrongFormatCommand(input); - } else { - final int nameIndex = 0; - final int idIndex = 1; - final int startIndex = 2; - final int endIndex = 3; - final int hotelIndex = 4; - final int priceIndex = 5; - final int countryIndex = 6; - final int vacanciesIndex = 7; - name = temp1[nameIndex]; - id = Integer.parseInt(temp1[idIndex]); - start = temp1[startIndex]; - end = temp1[endIndex]; - hotel = temp1[hotelIndex]; - price = Double.parseDouble(temp1[priceIndex]); - country = temp1[countryIndex]; - vacancies = Integer.parseInt(temp1[vacanciesIndex]); - return new AddCommand(name, id, start, end, hotel, price, country, vacancies); - } - case "delete": // delete TravelPackage by its ID - id = Integer.parseInt(inputArray[1]); - return new DeleteCommand(id); + return prepareAdd(arguments); + + case "delete": + // delete TravelPackage by its ID + return prepareDelete(arguments); case "packages": return new PackagesCommand(); - case "reserve": - temp = input.split(" ", 2); // remove reserve from string - temp1 = temp[1].split(","); // process the rest and split by comma - int packageID = Integer.parseInt(temp1[0]); - name = temp1[1]; - String number = temp1[2]; - int pax = Integer.parseInt(temp1[3]); - return new ReservationCommand(packageID, name, number, pax); + case "reserve": + return prepareReserve(arguments); case "remove": // delete reservation by giving travelpackage ID and contact number. - temp = input.split(" ", 2); - temp1 = temp[1].split(","); - packageID = Integer.parseInt(temp1[0]); - number = temp1[1]; - return new RemoveReservationCommand(packageID, number); + return prepareRemove(arguments); case "reservations": - id = Integer.parseInt(inputArray[1]); - return new PrintReservationsCommand(id); + return prepareReservations(arguments); default: return new ErrorCommand(input); } } + + private static Command prepareAdd(String args) { + String[] argsArray = args.trim().split(","); + if (argsArray.length != 8) { + return new WrongFormatCommand(args); + } + + try { + final int nameIndex = 0; + final int idIndex = 1; + final int startIndex = 2; + final int endIndex = 3; + final int hotelIndex = 4; + final int priceIndex = 5; + final int countryIndex = 6; + final int vacanciesIndex = 7; + String name = argsArray[nameIndex]; + int id = Integer.parseInt(argsArray[idIndex]); + String start = argsArray[startIndex]; + String end = argsArray[endIndex]; + String hotel = argsArray[hotelIndex]; + double price = Double.parseDouble(argsArray[priceIndex]); + String country = argsArray[countryIndex]; + int vacancies = Integer.parseInt(argsArray[vacanciesIndex]); + return new AddCommand(name, id, start, end, hotel, price, country, vacancies); + + } catch (Exception e) { + return new WrongFormatCommand(e.getMessage()); + } + } + + private static Command prepareDelete(String args) { + try { + int id = Integer.parseInt(args.trim()); + return new DeleteCommand(id); + } catch (Exception e) { + return new WrongFormatCommand(e.getMessage()); + } + } + + private static Command prepareReserve(String args) { + try { + String[] argsArray = args.trim().split(","); // process the rest and split by comma + int packageID = Integer.parseInt(argsArray[0]); + String name = argsArray[1]; + String number = argsArray[2]; + int pax = Integer.parseInt(argsArray[3]); + + return new ReservationCommand(packageID, name, number, pax); + } catch (Exception e) { + return new WrongFormatCommand(e.getMessage()); + } + } + + private static Command prepareRemove(String args) { + try { + String[] argsArray = args.trim().split(","); + int packageID = Integer.parseInt(argsArray[0]); + String number = argsArray[1]; + return new RemoveReservationCommand(packageID, number); + } catch (Exception e) { + return new WrongFormatCommand(e.getMessage()); + } + } + + private static Command prepareReservations(String args) { + try { + int id = Integer.parseInt(args.trim()); + return new PrintReservationsCommand(id); + } catch (Exception e) { + return new WrongFormatCommand(e.getMessage()); + } + } } diff --git a/src/main/java/seedu/duke/command/WrongFormatCommand.java b/src/main/java/seedu/duke/command/WrongFormatCommand.java index f7f36d2478..6410579eb6 100644 --- a/src/main/java/seedu/duke/command/WrongFormatCommand.java +++ b/src/main/java/seedu/duke/command/WrongFormatCommand.java @@ -1,7 +1,6 @@ package seedu.duke.command; import seedu.duke.Packages; -import seedu.duke.Reservations; public class WrongFormatCommand extends Command { From 8e581cbc7157378b07d5cc07f4a8ed306de0a3ab Mon Sep 17 00:00:00 2001 From: Brendan <53790951+bbawj@users.noreply.github.com> Date: Fri, 1 Apr 2022 00:21:15 +0800 Subject: [PATCH 062/131] Update UserGuide.md --- docs/UserGuide.md | 48 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index e89e66b7b9..3e48017cb4 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -15,19 +15,53 @@ {Give detailed description of each feature} -### Adding a todo: `todo` -Adds a new item to the list of todo items. +### Adding a package: `add` +Adds a new Travel Package to the list of Packages. -Format: `todo n/TODO_NAME d/DEADLINE` +Format: `add {package_name},{package_id},{startDate},{endDate},{hotel},{price},{country},{vacancies}` -* The `DEADLINE` can be in a natural language format. -* The `TODO_NAME` cannot contain punctuation. +* The `startDate` and `endDate` must be in the format DD/MM/YYYY. +* The `price` can only contain numbers or decimal points. Example of usage: -`todo n/Write the rest of the User Guide d/next week` +`add Skiing Trip,1,23/02/2022,24/02/2022,hotelName,90.99,Singapore,20` -`todo n/Refactor the User Guide to remove passive voice d/13/04/2020` +### Deleting a package: `delete` +Delete a Travel Package from the list of Packages based on the package ID. + +Format: `delete {package_id}` + +Example of usage: + +`delete 2` + +### Placing a reservation: `reserve` +Add a reservation to a Travel Package. + +Format: `reserve {package_id},{contact_name},{contact_number},{number_pax}` + +Example of usage: + +`reserve 3,John,91234567,3` + +### Removing a reservation: `remove` +Remove a reservation from a Travel Package. + +Format: `remove {package_id},{contact_number}` + +Example of usage: + +`remove 1,8888888` + +### View reservations: `reservations` +View reservations booked in a Travel Package. + +Format: `reservations {package_id}` + +Example of usage: + +`reservations 2` ## FAQ From 00ed778fd94f3025dd05d06bf160abc0ca36488b Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 1 Apr 2022 00:24:52 +0800 Subject: [PATCH 063/131] v2.0 - Edited packages command and added info command --- data.txt | 2 ++ src/main/java/seedu/duke/Parser.java | 14 +++++++++++ .../java/seedu/duke/command/InfoCommand.java | 25 +++++++++++++++++++ .../seedu/duke/command/PackagesCommand.java | 3 ++- 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/main/java/seedu/duke/command/InfoCommand.java diff --git a/data.txt b/data.txt index 8cd1d8f418..6f7747f300 100644 --- a/data.txt +++ b/data.txt @@ -1 +1,3 @@ packagename | 0 | 29/3/2022 | 29/4/2022 | hotelname | 99.99 | countryname | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% +Experience Seoul | 1 | 01/4/2022 |08/4/2022 | Marriott Seoul | 100.11 | Korea | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% +Conquer Summits | 2 | 05/5/2022 |11/5/2022 | Hotel Schweizerhof Luzern | 80.00 | Switzerland | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% \ No newline at end of file diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 3e7fa73744..3e8a0da891 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -37,6 +37,9 @@ public static Command parse(String input) { case "packages": return new PackagesCommand(); + case "info": + return prepareInfo(arguments); + case "reserve": return prepareReserve(arguments); @@ -115,6 +118,17 @@ private static Command prepareRemove(String args) { } } + private static Command prepareInfo(String args) { + try { + String[] argsArray = args.trim().split(","); + int packageID = Integer.parseInt(argsArray[0]); + //String number = argsArray[1]; + return new InfoCommand(packageID); + } catch (Exception e) { + return new WrongFormatCommand(e.getMessage()); + } + } + private static Command prepareReservations(String args) { try { int id = Integer.parseInt(args.trim()); diff --git a/src/main/java/seedu/duke/command/InfoCommand.java b/src/main/java/seedu/duke/command/InfoCommand.java new file mode 100644 index 0000000000..0080238cbc --- /dev/null +++ b/src/main/java/seedu/duke/command/InfoCommand.java @@ -0,0 +1,25 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public class InfoCommand extends Command{ + + private int travelPackageID; + + public InfoCommand (int id){ + this.travelPackageID = id; + } + + public void execute(Packages packages) { + if(travelPackageID < packages.getSize()){ + System.out.println("Package " + travelPackageID + " found: "); + System.out.println(packages.getPackage(travelPackageID).getCountry() + " - " + packages.getPackage(travelPackageID).getName()); + } + else{ + System.out.println("Package not found."); + } + } +} + + + diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index 8519fa2e9d..0e988629f8 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -6,7 +6,8 @@ public class PackagesCommand extends Command { public void execute(Packages packages) { for (int i = 0; i < packages.getSize(); i++) { - System.out.println(packages.getPackage(i)); + System.out.println(i + ". " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); + //System.out.println(packages.getPackage(i)); } } } From 340d229bca35e3cb30dc8083b5cf9031398b79d2 Mon Sep 17 00:00:00 2001 From: timchang27 <64303732+timchang27@users.noreply.github.com> Date: Fri, 1 Apr 2022 01:12:59 +0800 Subject: [PATCH 064/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 74bdb43daf..b8ac8d05ff 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,3 +1,4 @@ +# Travel Agency Reservation Booking System (TARBS) # Developer Guide ## Acknowledgements @@ -80,9 +81,30 @@ |remove|remove {package_id},{contact_number}
e.g remove 1,8888888
remove an existing reservation| |reservations|reservations {package_number}
eg. reservations 2
print all reservations for a given travelPackageID| +### Test Case 1 + +New employees can enter `packages` to view all available packages by the agency. + +Additionally, they can enter `info {package number}` to view more in-depth information about the package. + +![image](https://user-images.githubusercontent.com/64303732/161110520-8ed18ddc-b356-43d5-95ed-7df5ca2de91d.png) + +Employees can also input new reservations using `reserve {package_id},{contact_name},{contact_number},{number_pax}` + +They can then view and verify reservations for that package using `reservation {package_number}` + +![image](https://user-images.githubusercontent.com/64303732/161111482-a2f9600d-d1f0-45b1-9a51-ef28848e4b57.png) + +![image](https://user-images.githubusercontent.com/64303732/161111551-c1acfd1e-90f3-426e-b8e3-175f050dba42.png) + + ## Feature - Help Command Aim: Displays a list of all available commands that the user can refer to as a guide +![image](https://user-images.githubusercontent.com/64303732/161110894-f9226a6c-e9f2-4cf3-9158-72cc8df19604.png) + + + ## Feature - Storage #### Initialisation (Loading Data) The sequence diagram that shows how `Storage` is created and the data is loaded from the saved files when the program is initialised is shown below:
From 2c872a506d8a41d179f6a312ec43f71067d050dd Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 1 Apr 2022 01:14:19 +0800 Subject: [PATCH 065/131] v2.0 - Edited packages command and added info command --- data.txt | 6 +++--- src/main/java/seedu/duke/command/InfoCommand.java | 5 +++-- src/main/java/seedu/duke/command/PackagesCommand.java | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/data.txt b/data.txt index 6f7747f300..d44eb56eb0 100644 --- a/data.txt +++ b/data.txt @@ -1,3 +1,3 @@ -packagename | 0 | 29/3/2022 | 29/4/2022 | hotelname | 99.99 | countryname | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% -Experience Seoul | 1 | 01/4/2022 |08/4/2022 | Marriott Seoul | 100.11 | Korea | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% -Conquer Summits | 2 | 05/5/2022 |11/5/2022 | Hotel Schweizerhof Luzern | 80.00 | Switzerland | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% \ No newline at end of file +Experience Seoul | 1 | 01/4/2022 | 08/4/2022 | Marriott Seoul | 100.11 | Korea | 20 | 16$0,Tim,98765432,3%0,Brendan,12345,3%1,Tim,91234567,10% +Conquer Summits | 2 | 05/5/2022 | 11/5/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% +Back To Our Roots | 3 | 01/4/2022 | 20/4/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$0,Tim,98765432,3%0,Brendan,12345,3% diff --git a/src/main/java/seedu/duke/command/InfoCommand.java b/src/main/java/seedu/duke/command/InfoCommand.java index 0080238cbc..4e7f3a363a 100644 --- a/src/main/java/seedu/duke/command/InfoCommand.java +++ b/src/main/java/seedu/duke/command/InfoCommand.java @@ -11,9 +11,10 @@ public InfoCommand (int id){ } public void execute(Packages packages) { - if(travelPackageID < packages.getSize()){ + if(travelPackageID-1 < packages.getSize()){ System.out.println("Package " + travelPackageID + " found: "); - System.out.println(packages.getPackage(travelPackageID).getCountry() + " - " + packages.getPackage(travelPackageID).getName()); + //System.out.println(packages.getPackage(travelPackageID-1).getCountry() + " - " + packages.getPackage(travelPackageID-1).getName()); + System.out.println(packages.getPackage(travelPackageID-1)); } else{ System.out.println("Package not found."); diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index 0e988629f8..7a2ae2326c 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -6,7 +6,7 @@ public class PackagesCommand extends Command { public void execute(Packages packages) { for (int i = 0; i < packages.getSize(); i++) { - System.out.println(i + ". " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); + System.out.println(i+1 + ". " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); //System.out.println(packages.getPackage(i)); } } From 0020ae1d3b9b0dc9a3d74ccb9c4181b67a1dfe3f Mon Sep 17 00:00:00 2001 From: mafpovbul Date: Fri, 1 Apr 2022 09:16:15 +0800 Subject: [PATCH 066/131] Exception handling --- data.txt | 6 +++--- src/main/java/seedu/duke/Parser.java | 11 ++++++++--- src/main/java/seedu/duke/Reservations.java | 4 ++++ src/main/java/seedu/duke/Storage.java | 4 +++- src/main/java/seedu/duke/TARBS.java | 2 +- .../java/seedu/duke/command/DeleteCommand.java | 5 +++-- .../java/seedu/duke/command/HelpCommand.java | 18 +++++++++--------- .../seedu/duke/command/PackagesCommand.java | 3 +++ 8 files changed, 34 insertions(+), 19 deletions(-) diff --git a/data.txt b/data.txt index d44eb56eb0..e97cc5caa6 100644 --- a/data.txt +++ b/data.txt @@ -1,3 +1,3 @@ -Experience Seoul | 1 | 01/4/2022 | 08/4/2022 | Marriott Seoul | 100.11 | Korea | 20 | 16$0,Tim,98765432,3%0,Brendan,12345,3%1,Tim,91234567,10% -Conquer Summits | 2 | 05/5/2022 | 11/5/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$0,Tim,98765432,3%0,Brendan,12345,3% -Back To Our Roots | 3 | 01/4/2022 | 20/4/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$0,Tim,98765432,3%0,Brendan,12345,3% +Experience Seoul | 1 | 01/4/2022 | 08/4/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$1,Tim,98765432,3%1,Brendan,12345,3%1,Tim,91234567,10%1,Bren,2468,3% +Conquer Summits | 2 | 05/5/2022 | 11/5/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% +Back To Our Roots | 3 | 01/4/2022 | 20/4/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 3e8a0da891..fb1a2aef80 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -95,7 +95,10 @@ private static Command prepareDelete(String args) { private static Command prepareReserve(String args) { try { - String[] argsArray = args.trim().split(","); // process the rest and split by comma + String[] argsArray = args.trim().split(","); + if (argsArray.length != 4) { + return new WrongFormatCommand(args); + } int packageID = Integer.parseInt(argsArray[0]); String name = argsArray[1]; String number = argsArray[2]; @@ -110,6 +113,9 @@ private static Command prepareReserve(String args) { private static Command prepareRemove(String args) { try { String[] argsArray = args.trim().split(","); + if (argsArray.length != 2) { + return new WrongFormatCommand(args); + } int packageID = Integer.parseInt(argsArray[0]); String number = argsArray[1]; return new RemoveReservationCommand(packageID, number); @@ -120,8 +126,7 @@ private static Command prepareRemove(String args) { private static Command prepareInfo(String args) { try { - String[] argsArray = args.trim().split(","); - int packageID = Integer.parseInt(argsArray[0]); + int packageID = Integer.parseInt(args.trim()); //String number = argsArray[1]; return new InfoCommand(packageID); } catch (Exception e) { diff --git a/src/main/java/seedu/duke/Reservations.java b/src/main/java/seedu/duke/Reservations.java index 124c8c194f..45a92dff03 100644 --- a/src/main/java/seedu/duke/Reservations.java +++ b/src/main/java/seedu/duke/Reservations.java @@ -29,6 +29,10 @@ public void printAllReservations() { } } + public void initReservation(Reservation newReservation) { + reservations.add(newReservation); + } + public void addReservation(Reservation newReservation) { if (sameContactExist(newReservation.getContactNumber())) { System.out.println("Reservation under this number already exists! Please try again."); diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 1771e212bd..aee98856cc 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -48,8 +48,10 @@ public void savePackageToFile(Packages p) { * @return Packages object for Control class */ public Packages createPackages() { + System.out.println("Loading save file..."); ArrayList t = parseSavedFile(); Packages p = new Packages(t); + System.out.println("Loaded!"); return p; } @@ -87,7 +89,7 @@ public Reservations parseReservationFile(String str) { String[] arrayElements = str.split("%"); for (int i=0; i< arrayElements.length; i++){ Reservation newR = parseReservation(arrayElements[i]); - rList.addReservation(newR); + rList.initReservation(newR); } return rList; } diff --git a/src/main/java/seedu/duke/TARBS.java b/src/main/java/seedu/duke/TARBS.java index eac3081e8e..72be5efc18 100644 --- a/src/main/java/seedu/duke/TARBS.java +++ b/src/main/java/seedu/duke/TARBS.java @@ -17,6 +17,7 @@ public static void run() { System.out.println("Welcome to Travel Agency Booking Reservation System!"); Scanner sc = new Scanner(System.in); while (!endProgram) { + storage.savePackageToFile(packages); System.out.println("Please enter command: "); try { Command command = Parser.parse(sc.nextLine()); @@ -27,7 +28,6 @@ public static void run() { System.out.println("Wrong format. All available" + " commands can be seen with the 'help' command"); } - storage.savePackageToFile(packages); } storage.savePackageToFile(packages); } diff --git a/src/main/java/seedu/duke/command/DeleteCommand.java b/src/main/java/seedu/duke/command/DeleteCommand.java index a0d279274a..b0e20823ec 100644 --- a/src/main/java/seedu/duke/command/DeleteCommand.java +++ b/src/main/java/seedu/duke/command/DeleteCommand.java @@ -15,9 +15,10 @@ public void execute(Packages packages) { for (int i = 0; i < numberOfPackages; i++) { if (packages.getPackage(i).getID() == (id)) { packages.removePackage(i); - break; + System.out.println("Travel package deleted!"); + return; } } - + System.out.println("Package not found!"); } } diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index 524c18ae80..fd98727754 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -10,22 +10,22 @@ public void execute(Packages packages) { final String SEPARATOR = "---------------------------------------------" + "--------------------------\n"; System.out.println(SEPARATOR + "SHOW ALL PACKAGES\nView a list of all available packages\n" + - "Format/Usage: packages\n" + SEPARATOR + "SHOW CHOSEN PACKAGE\nDisplays the " + + "Usage: packages\n" + SEPARATOR + "SHOW CHOSEN PACKAGE\nDisplays the " + "detailed information of a specific travel " + "package from\nthe " + "'packages' page Able to print out specific details of any package\n" + - "Format: info {package_id}\n" + "Usage: info P2\n" + SEPARATOR + "ADD PACKAGE\n" + + "Format: info {package_id}\n" + "Usage: info 2\n" + SEPARATOR + "ADD PACKAGE\n" + "Allows the user to add a new travel package\ninto the list of available packages\n" + - "Format: add {package_name}, {country}, {duration}, {price}, {vacancies}\n" + - "Usage: add Skiing Trip, Sweden, 15/2/2022-19/2/2022, 800, 100\n" + SEPARATOR + + "Format: add {package_name},{country},{duration},{price},,{vacancies}\n" + + "Usage: add Skiing Trip,Sweden,15/2/2022-19/2/2022,800,100\n" + SEPARATOR + "DELETE PACKAGE\nAllows the user to delete an existing travel package\nfrom the " + - "list of available packages\nFormat: delete {package_id}\nUsage: delete P2\n" + + "list of available packages\nFormat: delete {package_id}\nUsage: delete 2\n" + SEPARATOR + "SHOW RESERVATIONS\nShows reservations of the user for " + "a specified travel package\nfrom the packages page\nFormat: reservations " + "{package_id}\nUsage: reservations 3\n" + SEPARATOR + "MAKE RESERVATION" + "\nCreates a reservation for a travel package from the packages page\nFormat: " + - "reserve {package_id} {contact_name} {contact_number} {pax}\nUsage: reserve 3 " + - "John Doe 91234567 3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + - "for a travel package from the packages page\nFormat: remove {reservation_id}" + - "\nUsage: remove R3\n" + SEPARATOR); + "reserve {package_id},{contact_name},{contact_number},{pax}\nUsage: reserve 3," + + "John Doe,91234567,3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + + "for a travel package from the packages page\nFormat: remove {package_id},{contact_number}" + + "\nUsage: remove 2,98765432\n" + SEPARATOR); } } diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index 7a2ae2326c..4a65bd5a0b 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -5,6 +5,9 @@ public class PackagesCommand extends Command { public void execute(Packages packages) { + if (packages.getSize() == 0){ + System.out.println("No packages found!"); + } for (int i = 0; i < packages.getSize(); i++) { System.out.println(i+1 + ". " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); //System.out.println(packages.getPackage(i)); From 39e9523c0811510841e9f02ebe89a138ac040c9c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Apr 2022 12:01:30 +0800 Subject: [PATCH 067/131] Add Date support --- data.txt | 6 +- src/main/java/seedu/duke/Parser.java | 95 +++++++++++-------- src/main/java/seedu/duke/Storage.java | 15 +-- src/main/java/seedu/duke/TravelPackage.java | 53 ++++++----- .../java/seedu/duke/command/AddCommand.java | 6 +- .../duke/command/WrongFormatCommand.java | 13 ++- src/test/java/seedu/duke/ParserTest.java | 7 +- 7 files changed, 113 insertions(+), 82 deletions(-) diff --git a/data.txt b/data.txt index e97cc5caa6..08cecdcd9d 100644 --- a/data.txt +++ b/data.txt @@ -1,3 +1,3 @@ -Experience Seoul | 1 | 01/4/2022 | 08/4/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$1,Tim,98765432,3%1,Brendan,12345,3%1,Tim,91234567,10%1,Bren,2468,3% -Conquer Summits | 2 | 05/5/2022 | 11/5/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% -Back To Our Roots | 3 | 01/4/2022 | 20/4/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% +Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$1,Tim,98765432,3%1,Brendan,12345,3%1,Tim,91234567,10%1,Bren,2468,3% +Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% +Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index fb1a2aef80..da5d4cf0c6 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,5 +1,7 @@ package seedu.duke; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -12,6 +14,18 @@ public class Parser { */ public static final Pattern BASIC_COMMAND_FORMAT = Pattern.compile("(?\\S+)(?.*)"); + public static final Pattern PACKAGE_DATA_ARGS_FORMAT = Pattern.compile( + "(?.+),(?[\\d]+),(?.+),(?.+),(?.+),(?.+),(?.+),(?[\\d]+)"); + + public static final Pattern RESERVATION_DATA_ARGS_FORMAT = Pattern.compile( + "(?[\\d]+),(?.+),(?[\\d]+),(?[\\d]+)"); + + public static final Pattern REMOVE_RESERVATION_ARGS_FORMAT = Pattern.compile("(?[\\d]+),(?[\\d]+)"); + + public static final Pattern ONE_ARGS_FORMAT = Pattern.compile("(?[\\d]+)"); + + public static DateTimeFormatter PARSE_FORMAT = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + public static Command parse(String input) { final Matcher matcher = BASIC_COMMAND_FORMAT.matcher(input.trim()); if (!matcher.matches()) { @@ -55,29 +69,24 @@ public static Command parse(String input) { } private static Command prepareAdd(String args) { - String[] argsArray = args.trim().split(","); - if (argsArray.length != 8) { + + final Matcher matcher = PACKAGE_DATA_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { return new WrongFormatCommand(args); } try { - final int nameIndex = 0; - final int idIndex = 1; - final int startIndex = 2; - final int endIndex = 3; - final int hotelIndex = 4; - final int priceIndex = 5; - final int countryIndex = 6; - final int vacanciesIndex = 7; - String name = argsArray[nameIndex]; - int id = Integer.parseInt(argsArray[idIndex]); - String start = argsArray[startIndex]; - String end = argsArray[endIndex]; - String hotel = argsArray[hotelIndex]; - double price = Double.parseDouble(argsArray[priceIndex]); - String country = argsArray[countryIndex]; - int vacancies = Integer.parseInt(argsArray[vacanciesIndex]); - return new AddCommand(name, id, start, end, hotel, price, country, vacancies); + String name = matcher.group("name"); + int id = Integer.parseInt(matcher.group("id")); + String start = matcher.group("startDate"); + LocalDate startDate = LocalDate.from(PARSE_FORMAT.parse(start)); + String end = matcher.group("endDate"); + LocalDate endDate = LocalDate.from(PARSE_FORMAT.parse(end)); + String hotel = matcher.group("hotel"); + double price = Double.parseDouble(matcher.group("price")); + String country = matcher.group("country"); + int vacancies = Integer.parseInt(matcher.group("vacancies")); + return new AddCommand(name, id, startDate, endDate, hotel, price, country, vacancies); } catch (Exception e) { return new WrongFormatCommand(e.getMessage()); @@ -85,8 +94,12 @@ private static Command prepareAdd(String args) { } private static Command prepareDelete(String args) { + final Matcher matcher = ONE_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + return new WrongFormatCommand(args); + } try { - int id = Integer.parseInt(args.trim()); + int id = Integer.parseInt(matcher.group("id")); return new DeleteCommand(id); } catch (Exception e) { return new WrongFormatCommand(e.getMessage()); @@ -94,16 +107,15 @@ private static Command prepareDelete(String args) { } private static Command prepareReserve(String args) { + final Matcher matcher = RESERVATION_DATA_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + return new WrongFormatCommand(args); + } try { - String[] argsArray = args.trim().split(","); - if (argsArray.length != 4) { - return new WrongFormatCommand(args); - } - int packageID = Integer.parseInt(argsArray[0]); - String name = argsArray[1]; - String number = argsArray[2]; - int pax = Integer.parseInt(argsArray[3]); - + int packageID = Integer.parseInt(matcher.group("id")); + String name = matcher.group("name"); + String number = matcher.group("number"); + int pax = Integer.parseInt(matcher.group("pax")); return new ReservationCommand(packageID, name, number, pax); } catch (Exception e) { return new WrongFormatCommand(e.getMessage()); @@ -111,13 +123,13 @@ private static Command prepareReserve(String args) { } private static Command prepareRemove(String args) { + final Matcher matcher = REMOVE_RESERVATION_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + return new WrongFormatCommand(args); + } try { - String[] argsArray = args.trim().split(","); - if (argsArray.length != 2) { - return new WrongFormatCommand(args); - } - int packageID = Integer.parseInt(argsArray[0]); - String number = argsArray[1]; + int packageID = Integer.parseInt(matcher.group("id")); + String number = matcher.group("number"); return new RemoveReservationCommand(packageID, number); } catch (Exception e) { return new WrongFormatCommand(e.getMessage()); @@ -125,9 +137,12 @@ private static Command prepareRemove(String args) { } private static Command prepareInfo(String args) { + final Matcher matcher = ONE_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + return new WrongFormatCommand(args); + } try { - int packageID = Integer.parseInt(args.trim()); - //String number = argsArray[1]; + int packageID = Integer.parseInt(matcher.group("id")); return new InfoCommand(packageID); } catch (Exception e) { return new WrongFormatCommand(e.getMessage()); @@ -135,8 +150,12 @@ private static Command prepareInfo(String args) { } private static Command prepareReservations(String args) { + final Matcher matcher = ONE_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + return new WrongFormatCommand(args); + } try { - int id = Integer.parseInt(args.trim()); + int id = Integer.parseInt(matcher.group("id")); return new PrintReservationsCommand(id); } catch (Exception e) { return new WrongFormatCommand(e.getMessage()); diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index aee98856cc..27c82a4839 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -4,6 +4,7 @@ import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Scanner; @@ -17,7 +18,7 @@ public class Storage { /** * String representation of the file path to the save file * - * @param filePath + * @param filePath */ public Storage(String filePath) { this.filePath = filePath; @@ -60,7 +61,7 @@ public Packages createPackages() { * * @return ArrayList object for createPackages method */ - public ArrayList parseSavedFile(){ + public ArrayList parseSavedFile() { ArrayList t = new ArrayList<>(); File pFile = new File(filePath); try { @@ -87,7 +88,7 @@ public ArrayList parseSavedFile(){ public Reservations parseReservationFile(String str) { Reservations rList = new Reservations(); String[] arrayElements = str.split("%"); - for (int i=0; i< arrayElements.length; i++){ + for (int i = 0; i < arrayElements.length; i++) { Reservation newR = parseReservation(arrayElements[i]); rList.initReservation(newR); } @@ -99,7 +100,7 @@ public Reservations parseReservationFile(String str) { * * @return Reservation */ - public Reservation parseReservation(String str){ + public Reservation parseReservation(String str) { String[] arrayElements = str.split(","); int packageID = Integer.parseInt(arrayElements[0].trim()); String customerName = arrayElements[1].trim(); @@ -120,14 +121,16 @@ public TravelPackage parseTravelPackageFile(String str) { String sid = arrayElements[1].trim(); int id = Integer.parseInt(sid); String start = arrayElements[2].trim(); + LocalDate startDate = LocalDate.from(Parser.PARSE_FORMAT.parse(start)); String end = arrayElements[3].trim(); + LocalDate endDate = LocalDate.from(Parser.PARSE_FORMAT.parse(end)); String hotel = arrayElements[4].trim(); double price = Double.parseDouble(arrayElements[5].trim()); String country = arrayElements[6].trim(); int vacancies = Integer.parseInt(arrayElements[7].trim()); int numParticipants = Integer.parseInt(arrayElements[8].trim()); - TravelPackage newPackage = new TravelPackage(name, id, start, end, hotel, price, country, vacancies, numParticipants); + TravelPackage newPackage = new TravelPackage(name, id, startDate, endDate, hotel, price, country, vacancies, + numParticipants); return newPackage; } } - diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 1f0bc08fd7..0fe8bcbec6 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -1,21 +1,24 @@ package seedu.duke; -import java.util.ArrayList; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; public class TravelPackage { public static final String EXAMPLENAME = "Switzerland - Conquer Summits"; public static final int EXAMPLEID = 999; - public static final String EXAMPLESTART = ""; - public static final String EXAMPLEEND = ""; + public static final String EXAMPLESTART = "13/09/2022"; + public static final String EXAMPLEEND = "22/10/2022"; public static final String EXAMPLEHOTEL = "EXAMPLE HOTEL"; public static final double EXAMPLEPRICE = 99.99; public static final String EXAMPLECOUNTRY = "Switzerland"; public static final int EXAMPLEMAX = 10; + private static DateTimeFormatter printFormat = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + private final String name; private final int id; - private final String startDate; - private final String endDate; + private final LocalDate startDate; + private final LocalDate endDate; private final String hotel; private final double price; private final String country; @@ -23,11 +26,10 @@ public class TravelPackage { private int numParticipants; private Reservations reservationList; - public TravelPackage(String name, int id, String startDate, String endDate, + public TravelPackage(String name, int id, LocalDate startDate, LocalDate endDate, String hotel, double price, String country, int maxParticipants) { this.name = name; this.id = id; - // this.period = [startDate,endDate]; this.startDate = startDate; this.endDate = endDate; this.hotel = hotel; @@ -37,11 +39,11 @@ public TravelPackage(String name, int id, String startDate, String endDate, this.numParticipants = 0; this.reservationList = new Reservations(); } - public TravelPackage(String name, int id, String startDate, String endDate, - String hotel, double price, String country, int maxParticipants, int numParticipants) { + + public TravelPackage(String name, int id, LocalDate startDate, LocalDate endDate, + String hotel, double price, String country, int maxParticipants, int numParticipants) { this.name = name; this.id = id; - // this.period = [startDate,endDate]; this.startDate = startDate; this.endDate = endDate; this.hotel = hotel; @@ -65,11 +67,11 @@ public String getName() { } public String getStartDate() { - return this.startDate; + return this.startDate.format(printFormat); } public String getEndDate() { - return this.endDate; + return this.endDate.format(printFormat); } public String getHotel() { @@ -88,21 +90,22 @@ public int getMaxParticipants() { return this.maxParticipants; } - public int getNumParticipants() {return this.numParticipants;} + public int getNumParticipants() { + return this.numParticipants; + } public Reservations getReservationList() { return this.reservationList; }; public void addParticipants(int addParticipants) { - this.numParticipants = this.numParticipants + addParticipants; + this.numParticipants = this.numParticipants + addParticipants; } public void removeParticipants(int removeParticipants) { - this.numParticipants = this.numParticipants - removeParticipants; + this.numParticipants = this.numParticipants - removeParticipants; } - public void setReservationList(Reservations r) { this.reservationList = r; } @@ -115,8 +118,8 @@ public String toString() { + this.price + "\nHotel: " + this.hotel + "\nVacancies Filled: " + this.numParticipants + "/" + this.maxParticipants + "\nTravel Period: " - + this.startDate + "-" + this.endDate - ;} + + this.startDate + "-" + this.endDate; + } @Override public boolean equals(Object obj) { @@ -137,9 +140,9 @@ public boolean equals(Object obj) { } - public String saveTravelPackage(){ + public String saveTravelPackage() { String str = toSave() + "$"; - for (int i=0; i Date: Fri, 1 Apr 2022 14:26:31 +0800 Subject: [PATCH 068/131] Add .jar to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 6364bde48c..104a328ed9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ /build/ src/main/resources/docs/ +*.jar + # MacOS custom attributes files created by Finder .DS_Store *.iml From e3b8a3760ccd5dc05ceeb782150483144124d188 Mon Sep 17 00:00:00 2001 From: mafpovbul Date: Fri, 1 Apr 2022 23:54:54 +0800 Subject: [PATCH 069/131] Exception handling for storage --- data.txt | 2 +- src/main/java/META-INF/MANIFEST.MF | 3 + src/main/java/seedu/duke/Customer.java | 6 +- src/main/java/seedu/duke/Help.java | 2 +- src/main/java/seedu/duke/Packages.java | 2 +- src/main/java/seedu/duke/Reservation.java | 2 +- src/main/java/seedu/duke/Reservations.java | 2 +- src/main/java/seedu/duke/Storage.java | 151 +++++++++++++----- src/main/java/seedu/duke/TravelPackage.java | 12 +- .../java/seedu/duke/command/AddCommand.java | 2 +- .../java/seedu/duke/command/ErrorCommand.java | 2 +- .../java/seedu/duke/command/InfoCommand.java | 2 +- .../command/PrintReservationsCommand.java | 2 +- .../command/RemoveReservationCommand.java | 4 +- .../duke/command/ReservationCommand.java | 2 +- .../duke/command/WrongFormatCommand.java | 2 +- .../duke/exception/InvalidInputException.java | 12 ++ 17 files changed, 146 insertions(+), 64 deletions(-) create mode 100644 src/main/java/META-INF/MANIFEST.MF create mode 100644 src/main/java/seedu/duke/exception/InvalidInputException.java diff --git a/data.txt b/data.txt index 08cecdcd9d..8291a78b3f 100644 --- a/data.txt +++ b/data.txt @@ -1,3 +1,3 @@ -Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$1,Tim,98765432,3%1,Brendan,12345,3%1,Tim,91234567,10%1,Bren,2468,3% +Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..182e949e6b --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: seedu.duke.TARBS + diff --git a/src/main/java/seedu/duke/Customer.java b/src/main/java/seedu/duke/Customer.java index 951c421123..94ece5664d 100644 --- a/src/main/java/seedu/duke/Customer.java +++ b/src/main/java/seedu/duke/Customer.java @@ -1,9 +1,9 @@ package seedu.duke; public class Customer { - private String customerID; - private String name; - private String contactNumber; + private final String customerID; + private final String name; + private final String contactNumber; public Customer(String customerID, String name, String contactNumber){ this.customerID = customerID; diff --git a/src/main/java/seedu/duke/Help.java b/src/main/java/seedu/duke/Help.java index 0ba463cdbf..c72d41fc62 100644 --- a/src/main/java/seedu/duke/Help.java +++ b/src/main/java/seedu/duke/Help.java @@ -2,7 +2,7 @@ import java.util.ArrayList; public class Help { - private ArrayList desc; + private final ArrayList desc; public Help(){ this.desc = new ArrayList<>(); diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index 378a5c8b18..8b6e047b98 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -4,7 +4,7 @@ //Packages include arrayList packages to hold all TravelPackages public class Packages { - private ArrayList packages; + private final ArrayList packages; public Packages() { this.packages = new ArrayList<>(); diff --git a/src/main/java/seedu/duke/Reservation.java b/src/main/java/seedu/duke/Reservation.java index 2144c97716..e0f75362a4 100644 --- a/src/main/java/seedu/duke/Reservation.java +++ b/src/main/java/seedu/duke/Reservation.java @@ -39,6 +39,6 @@ public String toString() { } public String toSave() { - return Integer.toString(packageID) + "," + customerName + "," + contactNumber + "," + Integer.toString(numOfPax); + return packageID + "," + customerName + "," + contactNumber + "," + numOfPax; } } diff --git a/src/main/java/seedu/duke/Reservations.java b/src/main/java/seedu/duke/Reservations.java index 45a92dff03..00fad83fd9 100644 --- a/src/main/java/seedu/duke/Reservations.java +++ b/src/main/java/seedu/duke/Reservations.java @@ -5,7 +5,7 @@ //arrayList of reservations //handle adding, deletion of reservations. Used in TravelPackage class. public class Reservations { - private ArrayList reservations; + private final ArrayList reservations; public Reservations() { this.reservations = new ArrayList<>(); diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 27c82a4839..55d6cb10f0 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -1,5 +1,7 @@ package seedu.duke; +import seedu.duke.exception.InvalidInputException; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; @@ -13,7 +15,22 @@ * reservations */ public class Storage { - private String filePath; + private final String filePath; + + static final int travelPackageNameIndex = 0; + static final int travelPackageIDIndex = 1; + static final int travelPackageStartDateIndex = 2; + static final int travelPackageEndDateIndex = 3; + static final int travelPackageHotelIndex = 4; + static final int travelPackagePriceIndex = 5; + static final int travelPackageCountryIndex = 6; + static final int travelPackageVacanciesIndex = 7; + static final int travelPackageNumParticipantsIndex = 8; + + static final int reservationPackageIDIndex = 0; + static final int reservationCustomerNameIndex = 1; + static final int reservationCustomerNumberIndex = 2; + static final int reservationNumPaxIndex = 3; /** * String representation of the file path to the save file @@ -43,6 +60,7 @@ public void savePackageToFile(Packages p) { } } + /** * Calls the functions to read saved files, creating a new Package object * @@ -50,10 +68,25 @@ public void savePackageToFile(Packages p) { */ public Packages createPackages() { System.out.println("Loading save file..."); - ArrayList t = parseSavedFile(); - Packages p = new Packages(t); - System.out.println("Loaded!"); - return p; + try { + ArrayList t = parseSavedFile(); + Packages p = new Packages(t); + System.out.println("Loaded!"); + return p; + } catch (InvalidInputException e) { + String errorMessage = e.getMessage(); + String errorDisplay = "ERROR '" + errorMessage + "'"; + System.out.println(errorDisplay); + Boolean newFileFlag = makeNewSaveFile(); + if (newFileFlag) { + return new Packages(); + } + else { + System.out.println("Thank you for using TARBS. See you again!"); + System.exit(0); + } + } + return null; } /** @@ -61,18 +94,24 @@ public Packages createPackages() { * * @return ArrayList object for createPackages method */ - public ArrayList parseSavedFile() { + public ArrayList parseSavedFile() throws InvalidInputException { ArrayList t = new ArrayList<>(); File pFile = new File(filePath); try { Scanner s = new Scanner(pFile); while (s.hasNext()) { - String currentLine = s.nextLine(); - String[] arrayElements = currentLine.split("\\$"); - TravelPackage newPackage = parseTravelPackageFile(arrayElements[0]); - Reservations newReservations = parseReservationFile(arrayElements[1]); - newPackage.setReservationList(newReservations); - t.add(newPackage); + try{ + String currentLine = s.nextLine(); + String[] arrayElements = currentLine.split("\\$"); + TravelPackage newPackage = parseTravelPackageFile(arrayElements[0]); + if (arrayElements.length > 1){ + Reservations newReservations = parseReservationFile(arrayElements[1]); + newPackage.setReservationList(newReservations); + } + t.add(newPackage); + } catch (Exception e) { + throw new InvalidInputException(e.getMessage()); + } } } catch (FileNotFoundException e) { System.out.println(e.getMessage()); @@ -85,14 +124,18 @@ public ArrayList parseSavedFile() { * * @return Reservations object */ - public Reservations parseReservationFile(String str) { + public Reservations parseReservationFile(String str) throws InvalidInputException { Reservations rList = new Reservations(); String[] arrayElements = str.split("%"); - for (int i = 0; i < arrayElements.length; i++) { - Reservation newR = parseReservation(arrayElements[i]); - rList.initReservation(newR); + try { + for (int i = 0; i < arrayElements.length; i++) { + Reservation newR = parseReservation(arrayElements[i]); + rList.initReservation(newR); + } + return rList; + } catch (Exception e) { + throw new InvalidInputException(e.getMessage()); } - return rList; } /** @@ -100,14 +143,18 @@ public Reservations parseReservationFile(String str) { * * @return Reservation */ - public Reservation parseReservation(String str) { - String[] arrayElements = str.split(","); - int packageID = Integer.parseInt(arrayElements[0].trim()); - String customerName = arrayElements[1].trim(); - String customerNum = arrayElements[2].trim(); - int numPax = Integer.parseInt(arrayElements[3].trim()); - Reservation r = new Reservation(packageID, customerName, customerNum, numPax); - return r; + public Reservation parseReservation(String str) throws InvalidInputException { + try { + String[] arrayElements = str.split(","); + int packageID = Integer.parseInt(arrayElements[reservationPackageIDIndex].trim()); + String customerName = arrayElements[reservationCustomerNameIndex].trim(); + String customerNum = arrayElements[reservationCustomerNumberIndex].trim(); + int numPax = Integer.parseInt(arrayElements[reservationNumPaxIndex].trim()); + Reservation r = new Reservation(packageID, customerName, customerNum, numPax); + return r; + } catch (Exception e) { + throw new InvalidInputException(e.getMessage()); + } } /** @@ -115,22 +162,42 @@ public Reservation parseReservation(String str) { * * @return TravelPackage object */ - public TravelPackage parseTravelPackageFile(String str) { - String[] arrayElements = str.split("\\|"); - String name = arrayElements[0].trim(); - String sid = arrayElements[1].trim(); - int id = Integer.parseInt(sid); - String start = arrayElements[2].trim(); - LocalDate startDate = LocalDate.from(Parser.PARSE_FORMAT.parse(start)); - String end = arrayElements[3].trim(); - LocalDate endDate = LocalDate.from(Parser.PARSE_FORMAT.parse(end)); - String hotel = arrayElements[4].trim(); - double price = Double.parseDouble(arrayElements[5].trim()); - String country = arrayElements[6].trim(); - int vacancies = Integer.parseInt(arrayElements[7].trim()); - int numParticipants = Integer.parseInt(arrayElements[8].trim()); - TravelPackage newPackage = new TravelPackage(name, id, startDate, endDate, hotel, price, country, vacancies, - numParticipants); - return newPackage; + public TravelPackage parseTravelPackageFile(String str) throws InvalidInputException { + try{ + String[] arrayElements = str.split("\\|"); + String name = arrayElements[travelPackageNameIndex].trim(); + String sid = arrayElements[travelPackageIDIndex].trim(); + int id = Integer.parseInt(sid); + String start = arrayElements[travelPackageStartDateIndex].trim(); + LocalDate startDate = LocalDate.from(Parser.PARSE_FORMAT.parse(start)); + String end = arrayElements[travelPackageEndDateIndex].trim(); + LocalDate endDate = LocalDate.from(Parser.PARSE_FORMAT.parse(end)); + String hotel = arrayElements[travelPackageHotelIndex].trim(); + double price = Double.parseDouble(arrayElements[travelPackagePriceIndex].trim()); + String country = arrayElements[travelPackageCountryIndex].trim(); + int vacancies = Integer.parseInt(arrayElements[travelPackageVacanciesIndex].trim()); + int numParticipants = Integer.parseInt(arrayElements[travelPackageNumParticipantsIndex].trim()); + TravelPackage newPackage = new TravelPackage(name, id, startDate, endDate, hotel, price, country, vacancies, numParticipants); + return newPackage; + } catch (Exception e) { + throw new InvalidInputException(e.getMessage()); + } } + + public boolean makeNewSaveFile() { + System.out.println("Uh oh, it seems like your file has been corrupted!"); + System.out.println("Would you like to restart with a new file? Your previous data will be wiped out. (Y/N)"); + Scanner sc = new Scanner(System.in); + while (true) { + String input = sc.nextLine(); + if (input.trim().equalsIgnoreCase("Y")) { + return true; + } else if (input.trim().equalsIgnoreCase("N")) { + return false; + } + System.out.println("Invalid input! Please enter 'Y' or 'N'."); + + } + } + } diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 0fe8bcbec6..1b363dbd41 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -13,7 +13,7 @@ public class TravelPackage { public static final String EXAMPLECOUNTRY = "Switzerland"; public static final int EXAMPLEMAX = 10; - private static DateTimeFormatter printFormat = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + private static final DateTimeFormatter printFormat = DateTimeFormatter.ofPattern("dd/MM/yyyy"); private final String name; private final int id; @@ -96,7 +96,7 @@ public int getNumParticipants() { public Reservations getReservationList() { return this.reservationList; - }; + } public void addParticipants(int addParticipants) { this.numParticipants = this.numParticipants + addParticipants; @@ -149,11 +149,11 @@ public String saveTravelPackage() { } public String toSave() { - return name + " | " + Integer.toString(id) + + return name + " | " + id + " | " + startDate.format(Parser.PARSE_FORMAT) + " | " + endDate.format(Parser.PARSE_FORMAT) + " | " + - hotel + " | " + Double.toString(price) + " | " + country + " | " + - Integer.toString(maxParticipants) - + " | " + Integer.toString(numParticipants); + hotel + " | " + price + " | " + country + " | " + + maxParticipants + + " | " + numParticipants; } } diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java index a91f5317da..4c6c0b0b5e 100644 --- a/src/main/java/seedu/duke/command/AddCommand.java +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -7,7 +7,7 @@ //creates a TravelPackage and adds to packages public class AddCommand extends Command { - private TravelPackage newPackage; + private final TravelPackage newPackage; public AddCommand(String name, int id, LocalDate date1, LocalDate date2, String hotel, double price, String country, diff --git a/src/main/java/seedu/duke/command/ErrorCommand.java b/src/main/java/seedu/duke/command/ErrorCommand.java index 87c3a31241..ebb4ed6ebb 100644 --- a/src/main/java/seedu/duke/command/ErrorCommand.java +++ b/src/main/java/seedu/duke/command/ErrorCommand.java @@ -4,7 +4,7 @@ import seedu.duke.Reservations; public class ErrorCommand extends Command { - private String input; + private final String input; public ErrorCommand(String input) { this.input = input; diff --git a/src/main/java/seedu/duke/command/InfoCommand.java b/src/main/java/seedu/duke/command/InfoCommand.java index 4e7f3a363a..6229d37a5b 100644 --- a/src/main/java/seedu/duke/command/InfoCommand.java +++ b/src/main/java/seedu/duke/command/InfoCommand.java @@ -4,7 +4,7 @@ public class InfoCommand extends Command{ - private int travelPackageID; + private final int travelPackageID; public InfoCommand (int id){ this.travelPackageID = id; diff --git a/src/main/java/seedu/duke/command/PrintReservationsCommand.java b/src/main/java/seedu/duke/command/PrintReservationsCommand.java index 013ef41185..285b405e16 100644 --- a/src/main/java/seedu/duke/command/PrintReservationsCommand.java +++ b/src/main/java/seedu/duke/command/PrintReservationsCommand.java @@ -4,7 +4,7 @@ import seedu.duke.TravelPackage; public class PrintReservationsCommand extends Command { - private int packageID; + private final int packageID; public PrintReservationsCommand(int packageID) { this.packageID = packageID; diff --git a/src/main/java/seedu/duke/command/RemoveReservationCommand.java b/src/main/java/seedu/duke/command/RemoveReservationCommand.java index 3a8c853aa9..82d7cdf77f 100644 --- a/src/main/java/seedu/duke/command/RemoveReservationCommand.java +++ b/src/main/java/seedu/duke/command/RemoveReservationCommand.java @@ -5,8 +5,8 @@ import seedu.duke.Reservations; public class RemoveReservationCommand extends Command{ - private int travelPackageID; - private String contact; + private final int travelPackageID; + private final String contact; public RemoveReservationCommand(int id,String contact){ this.travelPackageID = id; diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java index 7066c72104..fadec527f4 100644 --- a/src/main/java/seedu/duke/command/ReservationCommand.java +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -7,7 +7,7 @@ import java.util.Scanner; //add reservation to TravelPackage using travelpackage id public class ReservationCommand extends Command { - private Reservation newReservation; + private final Reservation newReservation; public ReservationCommand(int travelPackageID, String name, String number, int pax) { this.newReservation = new Reservation(travelPackageID, name, number, pax); diff --git a/src/main/java/seedu/duke/command/WrongFormatCommand.java b/src/main/java/seedu/duke/command/WrongFormatCommand.java index ff356d3abd..466d89d621 100644 --- a/src/main/java/seedu/duke/command/WrongFormatCommand.java +++ b/src/main/java/seedu/duke/command/WrongFormatCommand.java @@ -4,7 +4,7 @@ public class WrongFormatCommand extends Command { - private String feedback; + private final String feedback; public WrongFormatCommand(String feedback) { this.feedback = feedback; diff --git a/src/main/java/seedu/duke/exception/InvalidInputException.java b/src/main/java/seedu/duke/exception/InvalidInputException.java new file mode 100644 index 0000000000..f6c0817653 --- /dev/null +++ b/src/main/java/seedu/duke/exception/InvalidInputException.java @@ -0,0 +1,12 @@ +package seedu.duke.exception; + +public class InvalidInputException extends Exception{ + + public InvalidInputException(String message) { + super(message); + } + + public InvalidInputException() { + + } +} From bab17d81f9549788d4a335f75206b4846b9e1b2d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Apr 2022 10:09:52 +0800 Subject: [PATCH 070/131] Update help command, closes #77, closes #73, closes #51 --- src/main/java/seedu/duke/command/HelpCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index fd98727754..c4bda02010 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -15,8 +15,8 @@ public void execute(Packages packages) { "'packages' page Able to print out specific details of any package\n" + "Format: info {package_id}\n" + "Usage: info 2\n" + SEPARATOR + "ADD PACKAGE\n" + "Allows the user to add a new travel package\ninto the list of available packages\n" + - "Format: add {package_name},{country},{duration},{price},,{vacancies}\n" + - "Usage: add Skiing Trip,Sweden,15/2/2022-19/2/2022,800,100\n" + SEPARATOR + + "Format: add {package_name},{country},{duration},{price},{vacancies}\n" + + "Usage: add Skiing Trip,Sweden,15/2/2022,19/2/2022,800,100\n" + SEPARATOR + "DELETE PACKAGE\nAllows the user to delete an existing travel package\nfrom the " + "list of available packages\nFormat: delete {package_id}\nUsage: delete 2\n" + SEPARATOR + "SHOW RESERVATIONS\nShows reservations of the user for " + From eb94f626083413b372ab23c4cfac7bc72beefc18 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Apr 2022 11:21:09 +0800 Subject: [PATCH 071/131] Code review closes #26 --- src/main/java/seedu/duke/Parser.java | 20 ++++----- src/main/java/seedu/duke/TravelPackage.java | 37 +++++++++++++--- .../java/seedu/duke/command/AddCommand.java | 3 ++ .../java/seedu/duke/command/ByeCommand.java | 4 +- .../seedu/duke/command/DeleteCommand.java | 3 +- .../java/seedu/duke/command/ErrorCommand.java | 1 - .../java/seedu/duke/command/HelpCommand.java | 3 +- .../java/seedu/duke/command/InfoCommand.java | 19 ++++---- .../seedu/duke/command/PackagesCommand.java | 11 +++-- .../command/PrintReservationsCommand.java | 2 + .../command/RemoveReservationCommand.java | 19 ++++---- .../duke/command/ReservationCommand.java | 43 ++++++++++--------- 12 files changed, 101 insertions(+), 64 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index da5d4cf0c6..0bd340fd9e 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -36,31 +36,31 @@ public static Command parse(String input) { final String arguments = matcher.group("arguments"); switch (commandWord) { - case "bye": + case ByeCommand.COMMAND_WORD: return new ByeCommand(); - case "help": + case HelpCommand.COMMAND_WORD: return new HelpCommand(); - case "add": + case AddCommand.COMMAND_WORD: return prepareAdd(arguments); - case "delete": - // delete TravelPackage by its ID + case DeleteCommand.COMMAND_WORD: return prepareDelete(arguments); - case "packages": + + case PackagesCommand.COMMAND_WORD: return new PackagesCommand(); - case "info": + case InfoCommand.COMMAND_WORD: return prepareInfo(arguments); - case "reserve": + case ReservationCommand.COMMAND_WORD: return prepareReserve(arguments); - case "remove": // delete reservation by giving travelpackage ID and contact number. + case RemoveReservationCommand.COMMAND_WORD: return prepareRemove(arguments); - case "reservations": + case PrintReservationsCommand.COMMAND_WORD: return prepareReservations(arguments); default: diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 1b363dbd41..2a10e5cd84 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -132,12 +132,39 @@ public boolean equals(Object obj) { TravelPackage cur = (TravelPackage) obj; - return cur.getID() == this.getID() && cur.getName().equals(this.getName()) - && cur.getStartDate().equals(this.getStartDate()) - && cur.getEndDate().equals(this.getEndDate()) && cur.getHotel().equals(this.getHotel()) - && cur.getPrice() == this.getPrice() && - cur.getCountry().equals(this.getCountry()) && cur.getMaxParticipants() == this.getMaxParticipants(); + if (cur.getID() != this.getID()) { + return false; + } + + if (!cur.getName().equals(this.getName())) { + return false; + } + + if (!cur.getStartDate().equals(this.getStartDate())) { + return false; + } + + if (!cur.getEndDate().equals(this.getEndDate())) { + return false; + } + + if (!cur.getHotel().equals(this.getHotel())) { + return false; + } + + if (cur.getPrice() != this.getPrice()) { + return false; + } + + if (!cur.getCountry().equals(this.getCountry())) { + return false; + } + + if (cur.getMaxParticipants() != this.getMaxParticipants()) { + return false; + } + return true; } public String saveTravelPackage() { diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java index 4c6c0b0b5e..20401d06bc 100644 --- a/src/main/java/seedu/duke/command/AddCommand.java +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -7,6 +7,9 @@ //creates a TravelPackage and adds to packages public class AddCommand extends Command { + + public static final String COMMAND_WORD = "add"; + private final TravelPackage newPackage; public AddCommand(String name, int id, LocalDate date1, LocalDate date2, String hotel, double price, diff --git a/src/main/java/seedu/duke/command/ByeCommand.java b/src/main/java/seedu/duke/command/ByeCommand.java index c86612b57e..91e0385adb 100644 --- a/src/main/java/seedu/duke/command/ByeCommand.java +++ b/src/main/java/seedu/duke/command/ByeCommand.java @@ -1,9 +1,11 @@ package seedu.duke.command; import seedu.duke.Packages; -import seedu.duke.Reservations; public class ByeCommand extends Command { + + public static final String COMMAND_WORD = "bye"; + public ByeCommand() { setIsExit(true); } diff --git a/src/main/java/seedu/duke/command/DeleteCommand.java b/src/main/java/seedu/duke/command/DeleteCommand.java index b0e20823ec..f00e0fad99 100644 --- a/src/main/java/seedu/duke/command/DeleteCommand.java +++ b/src/main/java/seedu/duke/command/DeleteCommand.java @@ -1,9 +1,10 @@ package seedu.duke.command; import seedu.duke.Packages; -import seedu.duke.Reservations; public class DeleteCommand extends Command { + + public static final String COMMAND_WORD = "delete"; private final int id; public DeleteCommand(int id) { diff --git a/src/main/java/seedu/duke/command/ErrorCommand.java b/src/main/java/seedu/duke/command/ErrorCommand.java index ebb4ed6ebb..2d792292d0 100644 --- a/src/main/java/seedu/duke/command/ErrorCommand.java +++ b/src/main/java/seedu/duke/command/ErrorCommand.java @@ -1,7 +1,6 @@ package seedu.duke.command; import seedu.duke.Packages; -import seedu.duke.Reservations; public class ErrorCommand extends Command { private final String input; diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index c4bda02010..002ab5d029 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -1,10 +1,11 @@ package seedu.duke.command; import seedu.duke.Packages; -import seedu.duke.Reservations; public class HelpCommand extends Command { + public static final String COMMAND_WORD = "help"; + @Override public void execute(Packages packages) { final String SEPARATOR = "---------------------------------------------" + diff --git a/src/main/java/seedu/duke/command/InfoCommand.java b/src/main/java/seedu/duke/command/InfoCommand.java index 6229d37a5b..ad19964901 100644 --- a/src/main/java/seedu/duke/command/InfoCommand.java +++ b/src/main/java/seedu/duke/command/InfoCommand.java @@ -2,25 +2,24 @@ import seedu.duke.Packages; -public class InfoCommand extends Command{ +public class InfoCommand extends Command { + + public static final String COMMAND_WORD = "info"; private final int travelPackageID; - public InfoCommand (int id){ + public InfoCommand(int id) { this.travelPackageID = id; } public void execute(Packages packages) { - if(travelPackageID-1 < packages.getSize()){ + if (travelPackageID - 1 < packages.getSize()) { System.out.println("Package " + travelPackageID + " found: "); - //System.out.println(packages.getPackage(travelPackageID-1).getCountry() + " - " + packages.getPackage(travelPackageID-1).getName()); - System.out.println(packages.getPackage(travelPackageID-1)); - } - else{ + // System.out.println(packages.getPackage(travelPackageID-1).getCountry() + " - + // " + packages.getPackage(travelPackageID-1).getName()); + System.out.println(packages.getPackage(travelPackageID - 1)); + } else { System.out.println("Package not found."); } } } - - - diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index 4a65bd5a0b..9aabb7563b 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -1,16 +1,19 @@ package seedu.duke.command; import seedu.duke.Packages; -import seedu.duke.Reservations; public class PackagesCommand extends Command { + + public static final String COMMAND_WORD = "packages"; + public void execute(Packages packages) { - if (packages.getSize() == 0){ + if (packages.getSize() == 0) { System.out.println("No packages found!"); } for (int i = 0; i < packages.getSize(); i++) { - System.out.println(i+1 + ". " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); - //System.out.println(packages.getPackage(i)); + System.out.println( + i + 1 + ". " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); + // System.out.println(packages.getPackage(i)); } } } diff --git a/src/main/java/seedu/duke/command/PrintReservationsCommand.java b/src/main/java/seedu/duke/command/PrintReservationsCommand.java index 285b405e16..99bf160bca 100644 --- a/src/main/java/seedu/duke/command/PrintReservationsCommand.java +++ b/src/main/java/seedu/duke/command/PrintReservationsCommand.java @@ -4,6 +4,8 @@ import seedu.duke.TravelPackage; public class PrintReservationsCommand extends Command { + + public static final String COMMAND_WORD = "reservations"; private final int packageID; public PrintReservationsCommand(int packageID) { diff --git a/src/main/java/seedu/duke/command/RemoveReservationCommand.java b/src/main/java/seedu/duke/command/RemoveReservationCommand.java index 82d7cdf77f..5a82975a71 100644 --- a/src/main/java/seedu/duke/command/RemoveReservationCommand.java +++ b/src/main/java/seedu/duke/command/RemoveReservationCommand.java @@ -1,39 +1,39 @@ package seedu.duke.command; import seedu.duke.Packages; -import seedu.duke.Reservation; import seedu.duke.Reservations; -public class RemoveReservationCommand extends Command{ +public class RemoveReservationCommand extends Command { + + public static final String COMMAND_WORD = "remove"; private final int travelPackageID; private final String contact; - public RemoveReservationCommand(int id,String contact){ + public RemoveReservationCommand(int id, String contact) { this.travelPackageID = id; this.contact = contact; } + public void execute(Packages packages) { boolean foundID = false; for (int i = 0; i < packages.getSize(); i++) { if (packages.getPackage(i).getID() == this.travelPackageID) { Reservations r = packages.getPackage(i).getReservationList(); for (int j = 0; j < r.getReservationSize(); j++) { - if (this.contact.equals(r.getReservation(j).getContactNumber())){ - //check that numParticipants do not go below 0. + if (this.contact.equals(r.getReservation(j).getContactNumber())) { + // check that numParticipants do not go below 0. int result = packages.getPackage(i).getNumParticipants() - r.getReservation(j).getNumOfPax(); - if (( 0 <= result) && (result < packages.getPackage(i).getMaxParticipants())) { + if ((0 <= result) && (result < packages.getPackage(i).getMaxParticipants())) { packages.getPackage(i).removeParticipants(r.getReservation(j).getNumOfPax()); r.removeReservation(j); - } - else { + } else { System.out.println("Removing too many participants. Please try again."); } foundID = true; break; } - } } @@ -42,7 +42,6 @@ public void execute(Packages packages) { System.out.println("Travel Package ID or Mobile Phone not found. Please try again."); } - } } diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java index fadec527f4..00a42d8e31 100644 --- a/src/main/java/seedu/duke/command/ReservationCommand.java +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -3,37 +3,38 @@ import seedu.duke.Packages; import seedu.duke.Reservation; - -import java.util.Scanner; //add reservation to TravelPackage using travelpackage id public class ReservationCommand extends Command { + + public static final String COMMAND_WORD = "reserve"; + private final Reservation newReservation; public ReservationCommand(int travelPackageID, String name, String number, int pax) { this.newReservation = new Reservation(travelPackageID, name, number, pax); } - public void execute(Packages packages) { - boolean foundID = false; - for (int i =0;i packages.getPackage(i).getMaxParticipants()) { - System.out.println("Too many participants, maximum amount of participants will be exceeded. Please try again."); - } - else { - packages.getPackage(i).getReservationList().addReservation(this.newReservation); - packages.getPackage(i).addParticipants(newReservation.getNumOfPax()); - } - foundID = true; - break; + public void execute(Packages packages) { + boolean foundID = false; + for (int i = 0; i < packages.getSize(); i++) { + if (packages.getPackage(i).getID() == newReservation.getPackageID()) { + // handle participant overflow + if (newReservation.getNumOfPax() + packages.getPackage(i).getNumParticipants() > packages.getPackage(i) + .getMaxParticipants()) { + System.out.println( + "Too many participants, maximum amount of participants will be exceeded. Please try again."); + } else { + packages.getPackage(i).getReservationList().addReservation(this.newReservation); + packages.getPackage(i).addParticipants(newReservation.getNumOfPax()); } + foundID = true; + break; + } - if (!foundID) { - System.out.println("Travel Package ID not found. Please try again."); } - - + if (!foundID) { + System.out.println("Travel Package ID not found. Please try again."); } - } + } +} From be7cda6d86fa4c0e088b920177f19b64e6fe9613 Mon Sep 17 00:00:00 2001 From: Justyn Date: Sat, 2 Apr 2022 14:43:52 +0800 Subject: [PATCH 072/131] Date exception handling --- data.txt | 4 +-- src/main/java/seedu/duke/Parser.java | 35 +++++++++++++++++-- src/main/java/seedu/duke/Reservations.java | 9 +++-- .../seedu/duke/command/PackagesCommand.java | 2 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/data.txt b/data.txt index 8291a78b3f..cddc82f1ff 100644 --- a/data.txt +++ b/data.txt @@ -1,3 +1 @@ -Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ -Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% -Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% +ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 0bd340fd9e..8240e3e118 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,11 +1,15 @@ package seedu.duke; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.regex.Matcher; import java.util.regex.Pattern; import seedu.duke.command.*; +import seedu.duke.exception.InvalidDateException; public class Parser { @@ -79,15 +83,26 @@ private static Command prepareAdd(String args) { String name = matcher.group("name"); int id = Integer.parseInt(matcher.group("id")); String start = matcher.group("startDate"); - LocalDate startDate = LocalDate.from(PARSE_FORMAT.parse(start)); String end = matcher.group("endDate"); + boolean startDateValid = isDateValid(start); + boolean endDateValid = isDateValid(end); + if (!startDateValid){ + throw new InvalidDateException("Start date not valid!"); + } else if (!endDateValid) { + throw new InvalidDateException("End date not valid!"); + } + LocalDate startDate = LocalDate.from(PARSE_FORMAT.parse(start)); LocalDate endDate = LocalDate.from(PARSE_FORMAT.parse(end)); + if (!dateStartEndValid(startDate, endDate)){ + throw new InvalidDateException("End date cannot be before start date!"); + } String hotel = matcher.group("hotel"); double price = Double.parseDouble(matcher.group("price")); String country = matcher.group("country"); int vacancies = Integer.parseInt(matcher.group("vacancies")); return new AddCommand(name, id, startDate, endDate, hotel, price, country, vacancies); - + } catch (InvalidDateException e) { + return new InvalidDateCommand(e.getMessage()); } catch (Exception e) { return new WrongFormatCommand(e.getMessage()); } @@ -161,4 +176,20 @@ private static Command prepareReservations(String args) { return new WrongFormatCommand(e.getMessage()); } } + + public static boolean isDateValid(String date) { + String DATE_FORMAT = "dd/MM/yyyy"; + try { + DateFormat df = new SimpleDateFormat(DATE_FORMAT); + df.setLenient(false); + df.parse(date); + return true; + } catch (ParseException e) { + return false; + } + } + + public static boolean dateStartEndValid(LocalDate startDate, LocalDate endDate) { + return endDate.isAfter(startDate); + } } diff --git a/src/main/java/seedu/duke/Reservations.java b/src/main/java/seedu/duke/Reservations.java index 00fad83fd9..f26524762a 100644 --- a/src/main/java/seedu/duke/Reservations.java +++ b/src/main/java/seedu/duke/Reservations.java @@ -24,8 +24,13 @@ public int getReservationSize() { } public void printAllReservations() { - for (int i = 0; i < reservations.size(); i++) { - System.out.println(i + ". " + reservations.get(i).toString()); + if (reservations.size() == 0) { + System.out.println("No reservations added yet!"); + } + else { + for (int i = 0; i < reservations.size(); i++) { + System.out.println(i + ". " + reservations.get(i).toString()); + } } } diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index 9aabb7563b..769ad14dcb 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -12,7 +12,7 @@ public void execute(Packages packages) { } for (int i = 0; i < packages.getSize(); i++) { System.out.println( - i + 1 + ". " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); + packages.getPackage(i).getID() + ". " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); // System.out.println(packages.getPackage(i)); } } From 40ed8a85ce9bbeee7d452165398ea4a2826c4624 Mon Sep 17 00:00:00 2001 From: Justyn Date: Sat, 2 Apr 2022 14:44:23 +0800 Subject: [PATCH 073/131] Date exception handling --- .../duke/command/InvalidDateCommand.java | 23 +++++++++++++++++++ .../duke/exception/InvalidDateException.java | 12 ++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/main/java/seedu/duke/command/InvalidDateCommand.java create mode 100644 src/main/java/seedu/duke/exception/InvalidDateException.java diff --git a/src/main/java/seedu/duke/command/InvalidDateCommand.java b/src/main/java/seedu/duke/command/InvalidDateCommand.java new file mode 100644 index 0000000000..0a59cd8b14 --- /dev/null +++ b/src/main/java/seedu/duke/command/InvalidDateCommand.java @@ -0,0 +1,23 @@ +package seedu.duke.command; + +import seedu.duke.Packages; + +public class InvalidDateCommand extends Command { + + private final String feedback; + + public InvalidDateCommand(String feedback) { + this.feedback = feedback; + } + + public String getFeedback() { + return this.feedback; + } + + public void execute(Packages packages) { + System.out.println(this.feedback); + System.out.println("Use the help command to find out the valid commands."); + + } + +} diff --git a/src/main/java/seedu/duke/exception/InvalidDateException.java b/src/main/java/seedu/duke/exception/InvalidDateException.java new file mode 100644 index 0000000000..86ea21f7a1 --- /dev/null +++ b/src/main/java/seedu/duke/exception/InvalidDateException.java @@ -0,0 +1,12 @@ +package seedu.duke.exception; + +public class InvalidDateException extends Exception{ + + public InvalidDateException(String message) { + super(message); + } + + public InvalidDateException() { + + } +} From a690e3b6422c00d331b3ad2729abb6a4c919a68d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Apr 2022 15:17:10 +0800 Subject: [PATCH 074/131] Add exception handling and tests, closes #42, closes #69, closes #66 --- src/main/java/seedu/duke/Parser.java | 8 +++++- src/test/java/seedu/duke/ParserTest.java | 33 +++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 0bd340fd9e..966a425933 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -2,10 +2,12 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.time.format.ResolverStyle; import java.util.regex.Matcher; import java.util.regex.Pattern; import seedu.duke.command.*; +import seedu.duke.exception.InvalidInputException; public class Parser { @@ -24,7 +26,8 @@ public class Parser { public static final Pattern ONE_ARGS_FORMAT = Pattern.compile("(?[\\d]+)"); - public static DateTimeFormatter PARSE_FORMAT = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + public static DateTimeFormatter PARSE_FORMAT = DateTimeFormatter.ofPattern("dd/MM/uuuu") + .withResolverStyle(ResolverStyle.STRICT); public static Command parse(String input) { final Matcher matcher = BASIC_COMMAND_FORMAT.matcher(input.trim()); @@ -84,6 +87,9 @@ private static Command prepareAdd(String args) { LocalDate endDate = LocalDate.from(PARSE_FORMAT.parse(end)); String hotel = matcher.group("hotel"); double price = Double.parseDouble(matcher.group("price")); + if (price <= 0) { + throw new InvalidInputException("Price should not be less than or equal to 0!"); + } String country = matcher.group("country"); int vacancies = Integer.parseInt(matcher.group("vacancies")); return new AddCommand(name, id, startDate, endDate, hotel, price, country, vacancies); diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index e5029cbd2a..78142b427e 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -10,6 +10,7 @@ import seedu.duke.command.ByeCommand; import seedu.duke.command.Command; import seedu.duke.command.HelpCommand; +import seedu.duke.command.WrongFormatCommand; public class ParserTest { @@ -26,13 +27,43 @@ public void parse_helpCommand_parsedCorrectly() { } @Test - public void parse_addCommandValidPersonData_parsedCorrectly() { + public void parse_addCommandValidPackageData_parsedCorrectly() { final TravelPackage testPackage = generateTestTravelPackage(); final String input = convertPersonToAddCommandString(testPackage); final AddCommand result = parseAndAssertCommandType(input, AddCommand.class); assertEquals(result.getPackage(), testPackage); } + @Test + public void parse_addCommandInvalidPackageData_errorMessage() { + final double negativePrice = -99.99; + final String invalidDate = "31/02/2022"; + final String addCommandFormatString = "add %s,%s,%s,%s,%s,%s,%s,%s"; + final String[] inputs = { + String.format(addCommandFormatString, + TravelPackage.EXAMPLENAME, + TravelPackage.EXAMPLEID, + TravelPackage.EXAMPLESTART, + TravelPackage.EXAMPLEEND, + TravelPackage.EXAMPLEHOTEL, + negativePrice, + TravelPackage.EXAMPLECOUNTRY, + TravelPackage.EXAMPLEMAX), + String.format(addCommandFormatString, + TravelPackage.EXAMPLENAME, + TravelPackage.EXAMPLEID, + invalidDate, + TravelPackage.EXAMPLEEND, + TravelPackage.EXAMPLEHOTEL, + TravelPackage.EXAMPLEPRICE, + TravelPackage.EXAMPLECOUNTRY, + TravelPackage.EXAMPLEMAX) + }; + for (String input : inputs) { + parseAndAssertCommandType(input, WrongFormatCommand.class); + } + } + /** * Generates an instance of a {@code TravelPackage} from valid test data. * From 7181984c19852280c41da1838c5fee87d40ace3f Mon Sep 17 00:00:00 2001 From: Justyn Date: Sat, 2 Apr 2022 15:19:45 +0800 Subject: [PATCH 075/131] Find package logic, added error messages --- data.txt | 3 +++ src/main/java/seedu/duke/Reservations.java | 2 +- src/main/java/seedu/duke/Storage.java | 23 +++++++++++-------- .../java/seedu/duke/command/InfoCommand.java | 19 +++++++++------ .../seedu/duke/command/PackagesCommand.java | 2 +- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/data.txt b/data.txt index cddc82f1ff..de1993a576 100644 --- a/data.txt +++ b/data.txt @@ -1 +1,4 @@ +Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ +Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% +Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ diff --git a/src/main/java/seedu/duke/Reservations.java b/src/main/java/seedu/duke/Reservations.java index f26524762a..1c0d6326cf 100644 --- a/src/main/java/seedu/duke/Reservations.java +++ b/src/main/java/seedu/duke/Reservations.java @@ -29,7 +29,7 @@ public void printAllReservations() { } else { for (int i = 0; i < reservations.size(); i++) { - System.out.println(i + ". " + reservations.get(i).toString()); + System.out.println(i + 1 + ". " + reservations.get(i).toString()); } } } diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 55d6cb10f0..b0889dbb97 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -71,13 +71,18 @@ public Packages createPackages() { try { ArrayList t = parseSavedFile(); Packages p = new Packages(t); - System.out.println("Loaded!"); + System.out.println("Save file loaded!"); + return p; + } catch (FileNotFoundException e) { + Packages p = new Packages(); + System.out.println("Save file not found!"); + System.out.println("New save file 'data.txt' created!"); return p; } catch (InvalidInputException e) { String errorMessage = e.getMessage(); String errorDisplay = "ERROR '" + errorMessage + "'"; System.out.println(errorDisplay); - Boolean newFileFlag = makeNewSaveFile(); + boolean newFileFlag = makeNewSaveFile(); if (newFileFlag) { return new Packages(); } @@ -94,7 +99,7 @@ public Packages createPackages() { * * @return ArrayList object for createPackages method */ - public ArrayList parseSavedFile() throws InvalidInputException { + public ArrayList parseSavedFile() throws InvalidInputException,FileNotFoundException { ArrayList t = new ArrayList<>(); File pFile = new File(filePath); try { @@ -114,7 +119,7 @@ public ArrayList parseSavedFile() throws InvalidInputException { } } } catch (FileNotFoundException e) { - System.out.println(e.getMessage()); + throw new FileNotFoundException(e.getMessage()); } return t; } @@ -128,8 +133,8 @@ public Reservations parseReservationFile(String str) throws InvalidInputExceptio Reservations rList = new Reservations(); String[] arrayElements = str.split("%"); try { - for (int i = 0; i < arrayElements.length; i++) { - Reservation newR = parseReservation(arrayElements[i]); + for (String arrayElement : arrayElements) { + Reservation newR = parseReservation(arrayElement); rList.initReservation(newR); } return rList; @@ -150,8 +155,7 @@ public Reservation parseReservation(String str) throws InvalidInputException { String customerName = arrayElements[reservationCustomerNameIndex].trim(); String customerNum = arrayElements[reservationCustomerNumberIndex].trim(); int numPax = Integer.parseInt(arrayElements[reservationNumPaxIndex].trim()); - Reservation r = new Reservation(packageID, customerName, customerNum, numPax); - return r; + return new Reservation(packageID, customerName, customerNum, numPax); } catch (Exception e) { throw new InvalidInputException(e.getMessage()); } @@ -177,8 +181,7 @@ public TravelPackage parseTravelPackageFile(String str) throws InvalidInputExcep String country = arrayElements[travelPackageCountryIndex].trim(); int vacancies = Integer.parseInt(arrayElements[travelPackageVacanciesIndex].trim()); int numParticipants = Integer.parseInt(arrayElements[travelPackageNumParticipantsIndex].trim()); - TravelPackage newPackage = new TravelPackage(name, id, startDate, endDate, hotel, price, country, vacancies, numParticipants); - return newPackage; + return new TravelPackage(name, id, startDate, endDate, hotel, price, country, vacancies, numParticipants); } catch (Exception e) { throw new InvalidInputException(e.getMessage()); } diff --git a/src/main/java/seedu/duke/command/InfoCommand.java b/src/main/java/seedu/duke/command/InfoCommand.java index ad19964901..2ff9994fae 100644 --- a/src/main/java/seedu/duke/command/InfoCommand.java +++ b/src/main/java/seedu/duke/command/InfoCommand.java @@ -1,6 +1,7 @@ package seedu.duke.command; import seedu.duke.Packages; +import seedu.duke.TravelPackage; public class InfoCommand extends Command { @@ -13,13 +14,17 @@ public InfoCommand(int id) { } public void execute(Packages packages) { - if (travelPackageID - 1 < packages.getSize()) { - System.out.println("Package " + travelPackageID + " found: "); - // System.out.println(packages.getPackage(travelPackageID-1).getCountry() + " - - // " + packages.getPackage(travelPackageID-1).getName()); - System.out.println(packages.getPackage(travelPackageID - 1)); - } else { - System.out.println("Package not found."); + if (packages.getSize() == 0) { + System.out.println("No packages added yet!"); } + for (int i=0; i Date: Sat, 2 Apr 2022 15:43:28 +0800 Subject: [PATCH 076/131] Error checking when loading storage data --- src/main/java/seedu/duke/Storage.java | 11 +++++++++++ src/main/java/seedu/duke/TARBS.java | 1 + 2 files changed, 12 insertions(+) diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index b0889dbb97..0402c4a104 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -1,5 +1,6 @@ package seedu.duke; +import seedu.duke.exception.InvalidDateException; import seedu.duke.exception.InvalidInputException; import java.io.File; @@ -176,8 +177,14 @@ public TravelPackage parseTravelPackageFile(String str) throws InvalidInputExcep LocalDate startDate = LocalDate.from(Parser.PARSE_FORMAT.parse(start)); String end = arrayElements[travelPackageEndDateIndex].trim(); LocalDate endDate = LocalDate.from(Parser.PARSE_FORMAT.parse(end)); + if (!dateStartEndValid(startDate, endDate)) { + throw new InvalidInputException("End date cannot be before start date!"); + } String hotel = arrayElements[travelPackageHotelIndex].trim(); double price = Double.parseDouble(arrayElements[travelPackagePriceIndex].trim()); + if (price <= 0) { + throw new InvalidInputException("Price should not be less than or equal to 0!"); + } String country = arrayElements[travelPackageCountryIndex].trim(); int vacancies = Integer.parseInt(arrayElements[travelPackageVacanciesIndex].trim()); int numParticipants = Integer.parseInt(arrayElements[travelPackageNumParticipantsIndex].trim()); @@ -203,4 +210,8 @@ public boolean makeNewSaveFile() { } } + public boolean dateStartEndValid(LocalDate startDate, LocalDate endDate) { + return endDate.isAfter(startDate); + } + } diff --git a/src/main/java/seedu/duke/TARBS.java b/src/main/java/seedu/duke/TARBS.java index 72be5efc18..9fa827dee5 100644 --- a/src/main/java/seedu/duke/TARBS.java +++ b/src/main/java/seedu/duke/TARBS.java @@ -18,6 +18,7 @@ public static void run() { Scanner sc = new Scanner(System.in); while (!endProgram) { storage.savePackageToFile(packages); + System.out.println(); System.out.println("Please enter command: "); try { Command command = Parser.parse(sc.nextLine()); From 231b364f149f763b1afa729dc22a8c43178ca784 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Sat, 2 Apr 2022 15:51:18 +0800 Subject: [PATCH 077/131] v2.0 - Removed Unused Command Classes and Deleted Dead Code --- .../duke/command/AddReservationCommand.java | 19 ---------------- src/main/java/seedu/duke/command/Command.java | 1 - .../command/DeleteReservationCommand.java | 22 ------------------- .../duke/command/FindReservationsCommand.java | 16 -------------- .../seedu/duke/command/PackagesCommand.java | 1 - 5 files changed, 59 deletions(-) delete mode 100644 src/main/java/seedu/duke/command/AddReservationCommand.java delete mode 100644 src/main/java/seedu/duke/command/DeleteReservationCommand.java delete mode 100644 src/main/java/seedu/duke/command/FindReservationsCommand.java diff --git a/src/main/java/seedu/duke/command/AddReservationCommand.java b/src/main/java/seedu/duke/command/AddReservationCommand.java deleted file mode 100644 index 30feded0fc..0000000000 --- a/src/main/java/seedu/duke/command/AddReservationCommand.java +++ /dev/null @@ -1,19 +0,0 @@ -//package seedu.duke.command; -// -//import seedu.duke.Reservations; -//import seedu.duke.Reservation; -// -// -//public class AddReservationCommand extends ReservationCommand { -// private Reservation newReservation; -// -// public AddReservationCommand(int reservationID, int packageID, String customerName, String contactNumber, int numOfPax) { -// super(false); -// this.newReservation = new Reservation(reservationID, packageID, customerName, contactNumber, numOfPax); -// } -// -// public void execute(Reservations reservations) { -// reservations.addReservation(newReservation); -// } -// -//} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/Command.java b/src/main/java/seedu/duke/command/Command.java index 2a321debba..307a7dd7cb 100644 --- a/src/main/java/seedu/duke/command/Command.java +++ b/src/main/java/seedu/duke/command/Command.java @@ -16,5 +16,4 @@ public void setIsExit(boolean isExit) { public abstract void execute(Packages packages); -// public abstract void execute(Packages packages, Reservations reservations); } diff --git a/src/main/java/seedu/duke/command/DeleteReservationCommand.java b/src/main/java/seedu/duke/command/DeleteReservationCommand.java deleted file mode 100644 index d09709008c..0000000000 --- a/src/main/java/seedu/duke/command/DeleteReservationCommand.java +++ /dev/null @@ -1,22 +0,0 @@ -//package seedu.duke.command; -//import seedu.duke.Reservations; -//import seedu.duke.Reservation; -// -// -//public class DeleteReservationCommand extends ReservationCommand { -// private int id; -// -// public DeleteReservationCommand(int id) { -// super(false); -// this.id = id; -// -// -// public void execute(Reservations reservations) { -// for (int i = 0; i < reservations.getSize(); i++) { -// if (reservations.getReservation(i).getReservationID() == id) { -// reservations.removeReservation(i); -// break; -// } -// } -// } -//} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/FindReservationsCommand.java b/src/main/java/seedu/duke/command/FindReservationsCommand.java deleted file mode 100644 index 3a34e6d9ec..0000000000 --- a/src/main/java/seedu/duke/command/FindReservationsCommand.java +++ /dev/null @@ -1,16 +0,0 @@ -//package seedu.duke.command; -// -//import seedu.duke.Reservations; -// -// -//public class FindReservationsCommand extends ReservationCommand { -// public FindReservationsCommand() { -// super(false); -// } -// -// public void execute(Reservations reservations) { -// for (int i = 0; i < reservations.getSize(); i++) { -// reservations.getReservation(i).toString(); -// } -// } -//} \ No newline at end of file diff --git a/src/main/java/seedu/duke/command/PackagesCommand.java b/src/main/java/seedu/duke/command/PackagesCommand.java index d959e6b2c7..d90055a9c6 100644 --- a/src/main/java/seedu/duke/command/PackagesCommand.java +++ b/src/main/java/seedu/duke/command/PackagesCommand.java @@ -13,7 +13,6 @@ public void execute(Packages packages) { for (int i = 0; i < packages.getSize(); i++) { System.out.println( i + 1 + ". PackageID-" + packages.getPackage(i).getID() + " | " + packages.getPackage(i).getCountry() + " - " + packages.getPackage(i).getName()); - // System.out.println(packages.getPackage(i)); } } } From 4c09fe00cd69961bf81c8758e07ef044e1fb67ec Mon Sep 17 00:00:00 2001 From: Justyn Date: Sat, 2 Apr 2022 18:26:23 +0800 Subject: [PATCH 078/131] Add storage test code --- src/main/java/seedu/duke/Storage.java | 12 +-- src/main/java/seedu/duke/TravelPackage.java | 25 ++++--- src/test/data/StorageFileTest/InvalidData.txt | 4 + src/test/data/StorageFileTest/ValidData.txt | 1 + src/test/java/seedu/duke/StorageTest.java | 73 +++++++++++++++++++ testFile.txt | 1 + 6 files changed, 99 insertions(+), 17 deletions(-) create mode 100644 src/test/data/StorageFileTest/InvalidData.txt create mode 100644 src/test/data/StorageFileTest/ValidData.txt create mode 100644 src/test/java/seedu/duke/StorageTest.java create mode 100644 testFile.txt diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 0402c4a104..548a2c79f4 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -130,15 +130,15 @@ public ArrayList parseSavedFile() throws InvalidInputException,Fi * * @return Reservations object */ - public Reservations parseReservationFile(String str) throws InvalidInputException { - Reservations rList = new Reservations(); - String[] arrayElements = str.split("%"); + public Reservations parseReservationFile(String savedReservations) throws InvalidInputException { + Reservations reservationsList = new Reservations(); + String[] arrayElements = savedReservations.split("%"); try { for (String arrayElement : arrayElements) { - Reservation newR = parseReservation(arrayElement); - rList.initReservation(newR); + Reservation newReservation = parseReservation(arrayElement); + reservationsList.initReservation(newReservation); } - return rList; + return reservationsList; } catch (Exception e) { throw new InvalidInputException(e.getMessage()); } diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 2a10e5cd84..6e5aaf37ea 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -2,8 +2,11 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.time.format.ResolverStyle; public class TravelPackage { + public static DateTimeFormatter PARSE_FORMAT = DateTimeFormatter.ofPattern("dd/MM/uuuu") + .withResolverStyle(ResolverStyle.STRICT); public static final String EXAMPLENAME = "Switzerland - Conquer Summits"; public static final int EXAMPLEID = 999; public static final String EXAMPLESTART = "13/09/2022"; @@ -118,7 +121,7 @@ public String toString() { + this.price + "\nHotel: " + this.hotel + "\nVacancies Filled: " + this.numParticipants + "/" + this.maxParticipants + "\nTravel Period: " - + this.startDate + "-" + this.endDate; + + this.startDate + " to " + this.endDate; } @Override @@ -160,11 +163,7 @@ public boolean equals(Object obj) { return false; } - if (cur.getMaxParticipants() != this.getMaxParticipants()) { - return false; - } - - return true; + return cur.getMaxParticipants() == this.getMaxParticipants(); } public String saveTravelPackage() { @@ -176,11 +175,15 @@ public String saveTravelPackage() { } public String toSave() { - return name + " | " + id + - " | " + startDate.format(Parser.PARSE_FORMAT) + " | " + endDate.format(Parser.PARSE_FORMAT) + " | " + - hotel + " | " + price + " | " + country + " | " + - maxParticipants - + " | " + numParticipants; + return name + " | " + + id + " | " + + startDate.format(Parser.PARSE_FORMAT) + " | " + + endDate.format(Parser.PARSE_FORMAT) + " | " + + hotel + " | " + + price + " | " + + country + " | " + + maxParticipants + " | " + + numParticipants; } } diff --git a/src/test/data/StorageFileTest/InvalidData.txt b/src/test/data/StorageFileTest/InvalidData.txt new file mode 100644 index 0000000000..bc4db00207 --- /dev/null +++ b/src/test/data/StorageFileTest/InvalidData.txt @@ -0,0 +1,4 @@ +Experience Seoul | 1 | 35/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ +Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% +Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% +ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ diff --git a/src/test/data/StorageFileTest/ValidData.txt b/src/test/data/StorageFileTest/ValidData.txt new file mode 100644 index 0000000000..798a3e01ba --- /dev/null +++ b/src/test/data/StorageFileTest/ValidData.txt @@ -0,0 +1 @@ +Switzerland - Conquer Summits | 999 | 13/09/2022 | 22/10/2022 | EXAMPLE HOTEL | 99.99 | Switzerland | 10 | 0$ diff --git a/src/test/java/seedu/duke/StorageTest.java b/src/test/java/seedu/duke/StorageTest.java new file mode 100644 index 0000000000..2c49d183d3 --- /dev/null +++ b/src/test/java/seedu/duke/StorageTest.java @@ -0,0 +1,73 @@ +package seedu.duke; + +import org.junit.jupiter.api.Test; + +import java.io.File; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.LocalDate; +import java.util.ArrayList; + +public class StorageTest { + + private static final String TEST_DATA_FOLDER = "StorageFileTest"; + private static final String NON_EXISTENT_FILE_NAME = "ThisFileDoesNotExist.txt"; + + @Test + public void writeSaveData_expectFileCreated() { + File testFile = new File("testFile.txt"); + if (testFile.exists()) { + testFile.delete(); + } + try { + Storage storage = new Storage("testFile.txt"); + TravelPackage newTPackage = new TravelPackage( + TravelPackage.EXAMPLENAME, + TravelPackage.EXAMPLEID, + LocalDate.from(Parser.PARSE_FORMAT.parse(TravelPackage.EXAMPLESTART)), + LocalDate.from(Parser.PARSE_FORMAT.parse(TravelPackage.EXAMPLEEND)), + TravelPackage.EXAMPLEHOTEL, + TravelPackage.EXAMPLEPRICE, + TravelPackage.EXAMPLECOUNTRY, + TravelPackage.EXAMPLEMAX); + ArrayList newTPackageList = new ArrayList<>(); + newTPackageList.add(newTPackage); + Packages newPackage = new Packages(newTPackageList); + storage.savePackageToFile(newPackage); + } catch (Exception e) { + e.printStackTrace(); + } + assertTrue(testFile.exists()); + } + + @Test + public void load_expectPackage() { + writeSaveData_expectFileCreated(); + try { + Storage storage = new Storage("testFile.txt"); + Packages newPackage = storage.createPackages(); + TravelPackage newTP = newPackage.getPackage(0); + assertEquals(newTP.getName(), TravelPackage.EXAMPLENAME); + assertEquals(newTP.getID(), TravelPackage.EXAMPLEID); + assertEquals(newTP.getStartDate(), TravelPackage.EXAMPLESTART); + assertEquals(newTP.getEndDate(), TravelPackage.EXAMPLEEND); + assertEquals(newTP.getHotel(), TravelPackage.EXAMPLEHOTEL); + assertEquals(newTP.getPrice(), TravelPackage.EXAMPLEPRICE); + assertEquals(newTP.getCountry(), TravelPackage.EXAMPLECOUNTRY); + assertEquals(newTP.getMaxParticipants(), TravelPackage.EXAMPLEMAX); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void load_nonExistentFile_returnsEmptyPackage() { + Storage tempStorage = new Storage(NON_EXISTENT_FILE_NAME); + Packages actualPackage = tempStorage.createPackages(); + Packages expectedPackage = new Packages(); + assertEquals(actualPackage.getSize(), expectedPackage.getSize()); + } + +} + diff --git a/testFile.txt b/testFile.txt new file mode 100644 index 0000000000..798a3e01ba --- /dev/null +++ b/testFile.txt @@ -0,0 +1 @@ +Switzerland - Conquer Summits | 999 | 13/09/2022 | 22/10/2022 | EXAMPLE HOTEL | 99.99 | Switzerland | 10 | 0$ From 733bd633f9fbee50c4b6d96fa46876d6c63667f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Apr 2022 19:14:38 +0800 Subject: [PATCH 079/131] Add date range test --- src/test/java/seedu/duke/ParserTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/seedu/duke/ParserTest.java b/src/test/java/seedu/duke/ParserTest.java index 78142b427e..cec03ae723 100644 --- a/src/test/java/seedu/duke/ParserTest.java +++ b/src/test/java/seedu/duke/ParserTest.java @@ -10,6 +10,7 @@ import seedu.duke.command.ByeCommand; import seedu.duke.command.Command; import seedu.duke.command.HelpCommand; +import seedu.duke.command.InvalidDateCommand; import seedu.duke.command.WrongFormatCommand; public class ParserTest { @@ -64,6 +65,22 @@ public void parse_addCommandInvalidPackageData_errorMessage() { } } + @Test + public void parse_addCommandInvalidDateRange_errorMessage() { + final String endDate = "01/01/1999"; + final String addCommandFormatString = "add %s,%s,%s,%s,%s,%s,%s,%s"; + final String input = String.format(addCommandFormatString, + TravelPackage.EXAMPLENAME, + TravelPackage.EXAMPLEID, + TravelPackage.EXAMPLESTART, + endDate, + TravelPackage.EXAMPLEHOTEL, + TravelPackage.EXAMPLEPRICE, + TravelPackage.EXAMPLECOUNTRY, + TravelPackage.EXAMPLEMAX); + parseAndAssertCommandType(input, InvalidDateCommand.class); + } + /** * Generates an instance of a {@code TravelPackage} from valid test data. * From b6b8dde292fbd5c1d70627ea4f8b9685a689a9aa Mon Sep 17 00:00:00 2001 From: chintaiann Date: Mon, 4 Apr 2022 18:02:16 +0800 Subject: [PATCH 080/131] small fix closes #27 --- .../seedu/duke/command/RemoveReservationCommand.java | 12 +++--------- .../java/seedu/duke/command/ReservationCommand.java | 6 +++--- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/seedu/duke/command/RemoveReservationCommand.java b/src/main/java/seedu/duke/command/RemoveReservationCommand.java index 5a82975a71..b59c0493a0 100644 --- a/src/main/java/seedu/duke/command/RemoveReservationCommand.java +++ b/src/main/java/seedu/duke/command/RemoveReservationCommand.java @@ -15,33 +15,27 @@ public RemoveReservationCommand(int id, String contact) { } public void execute(Packages packages) { - boolean foundID = false; + boolean isFoundID = false; for (int i = 0; i < packages.getSize(); i++) { if (packages.getPackage(i).getID() == this.travelPackageID) { Reservations r = packages.getPackage(i).getReservationList(); for (int j = 0; j < r.getReservationSize(); j++) { if (this.contact.equals(r.getReservation(j).getContactNumber())) { - // check that numParticipants do not go below 0. int result = packages.getPackage(i).getNumParticipants() - r.getReservation(j).getNumOfPax(); if ((0 <= result) && (result < packages.getPackage(i).getMaxParticipants())) { packages.getPackage(i).removeParticipants(r.getReservation(j).getNumOfPax()); r.removeReservation(j); - } else { System.out.println("Removing too many participants. Please try again."); } - foundID = true; + isFoundID = true; break; } - } - } } - if (!foundID) { + if (!isFoundID) { System.out.println("Travel Package ID or Mobile Phone not found. Please try again."); } - } - } diff --git a/src/main/java/seedu/duke/command/ReservationCommand.java b/src/main/java/seedu/duke/command/ReservationCommand.java index 00a42d8e31..deef27f880 100644 --- a/src/main/java/seedu/duke/command/ReservationCommand.java +++ b/src/main/java/seedu/duke/command/ReservationCommand.java @@ -15,7 +15,7 @@ public ReservationCommand(int travelPackageID, String name, String number, int p } public void execute(Packages packages) { - boolean foundID = false; + boolean isFoundID = false; for (int i = 0; i < packages.getSize(); i++) { if (packages.getPackage(i).getID() == newReservation.getPackageID()) { // handle participant overflow @@ -27,12 +27,12 @@ public void execute(Packages packages) { packages.getPackage(i).getReservationList().addReservation(this.newReservation); packages.getPackage(i).addParticipants(newReservation.getNumOfPax()); } - foundID = true; + isFoundID = true; break; } } - if (!foundID) { + if (!isFoundID) { System.out.println("Travel Package ID not found. Please try again."); } From b60b0aed42aa6295c848f5b97abc979af7a28e07 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Thu, 7 Apr 2022 01:37:35 +0800 Subject: [PATCH 081/131] Update chintaiann.md --- docs/team/chintaiann.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/team/chintaiann.md b/docs/team/chintaiann.md index c1db15bd38..93aedb2be9 100644 --- a/docs/team/chintaiann.md +++ b/docs/team/chintaiann.md @@ -1,6 +1,18 @@ # Tai Ann - Project Portfolio Page ## Overview +Our project, Travel Agency Reservation Booking System (TARBS) was developed to allow staff of a Travel Agency to easily record, update and check travel reservations made by customers. -### Summary of Contributions \ No newline at end of file + +### Summary of Contributions + +RepoSense Link +https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=chintaiann&breakdown=true&sort=groupTitle&sortWithin=title&since=2022-02-18&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other + +Contributions +1. Started the project off by implementing a simple application using TravelPackage class - which we further improved by including OOP concepts. +2. Implementation of Reservation after v1.0 +3. Further improvement in user experience by tweaking input to be separated by commas +4. UG - Updated the UG after improvements were made in (3). +5. UG - Added comments to clearly explain each command in our /help function From 15f00bdb68c6add9a68a29cf56e87d70e47ae1db Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Thu, 7 Apr 2022 10:09:46 +0800 Subject: [PATCH 082/131] Create justyn.md --- docs/team/justyn.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 docs/team/justyn.md diff --git a/docs/team/justyn.md b/docs/team/justyn.md new file mode 100644 index 0000000000..03786db0ed --- /dev/null +++ b/docs/team/justyn.md @@ -0,0 +1,6 @@ +# Justyn - Project Portfolio Page + +## Overview + + +### Summary of Contributions From 2764c3e4fd6b23d6f65ac2fcc30154299248b7da Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Thu, 7 Apr 2022 10:20:56 +0800 Subject: [PATCH 083/131] Update justyn.md --- docs/team/justyn.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/team/justyn.md b/docs/team/justyn.md index 03786db0ed..4f027526a2 100644 --- a/docs/team/justyn.md +++ b/docs/team/justyn.md @@ -1,6 +1,24 @@ # Justyn - Project Portfolio Page ## Overview - +Our project, Travel Agency Reservation Booking System (TARBS) was developed to allow staff of a Travel Agency to easily record, update and check travel reservations made by customers. ### Summary of Contributions +### Code contributed +[RepoSense Link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=mafpovbul&breakdown=true&sort=groupTitle&sortWithin=title&since=2022-02-18&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) + +### Features and enhancements implemented + +- Implemented the `Storage` feature in TARBS + - Implemented the encoding of `TravelPackage` and `Reservations` to a text file. + - Implemented the decoding of saved text files to `TravelPackge` and `Reservations`. + - Implemented handling of invalid save data (if data is tampered with in the saved file) + +- Added JUnit tests for `Storage` + +#### Contributions to Developer Guide: +- Added explanation for `Storage` +- Added sequence diagrams to explain how save files are loaded, stored and how invalid save data is handled + +#### Contributions to User Guide: +- Added quick guide table for commands From 8154180a48bd85b3f1c25be85c1bcb3786bdbfdb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Apr 2022 13:59:23 +0800 Subject: [PATCH 084/131] Add Brendan PPP --- docs/team/brendan.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/team/brendan.md b/docs/team/brendan.md index e69de29bb2..66d4a9da48 100644 --- a/docs/team/brendan.md +++ b/docs/team/brendan.md @@ -0,0 +1,30 @@ +# Brendan - Project Portfolio Page + +## Overview + +Our project, Travel Agency Reservation Booking System (TARBS) was developed to allow staff of a Travel Agency to easily record, update and check travel reservations made by customers. + +### Summary of Contributions + +### Code contributed + +[RepoSense Link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18&tabOpen=true&tabType=authorship&tabAuthor=bbawj&tabRepo=AY2122S2-CS2113-F10-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other&authorshipIsBinaryFileTypeChecked=false) + +### Features and enhancements implemented + +- Implemented the `Parser` class and feature in TARBS + + - Handle user input and parsing into appropriate commands used by TARBS + - Handle incorrect user inputs and parsing into appropriate `InvalidInputCommand` or error messages + +- Added JUnit tests under `ParserTest` + +#### Contributions to Developer Guide: + +- Added an basic overview Class diagram for TARBS +- Added explanation for `Parser` +- Added sequence diagrams to explain the methods and classes used in the parsing of a simple `ByeCommand` + +#### Contributions to User Guide: + +- Added format and examples for some commands to the User Guide. From ece052220e38e3efe4fb6a4ef4435a286828cf09 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Thu, 7 Apr 2022 22:20:51 +0800 Subject: [PATCH 085/131] Fix the same package bug --- src/main/java/seedu/duke/Packages.java | 19 +++++++++++++++++-- .../java/seedu/duke/command/AddCommand.java | 9 +++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/seedu/duke/Packages.java b/src/main/java/seedu/duke/Packages.java index 8b6e047b98..94c150f352 100644 --- a/src/main/java/seedu/duke/Packages.java +++ b/src/main/java/seedu/duke/Packages.java @@ -1,5 +1,6 @@ package seedu.duke; +import java.time.LocalDate; import java.util.ArrayList; //Packages include arrayList packages to hold all TravelPackages @@ -42,12 +43,26 @@ public void removePackage(int index) { // check if packageID already exists. return true if already exists - unique IDs // only! public boolean idExists(int id) { - for (int i = 0; i < packages.size(); i++) { - if (packages.get(i).getID() == id) { + for (TravelPackage aPackage : packages) { + if (aPackage.getID() == id) { return true; } } + return false; + } + public boolean isContainSamePackage(TravelPackage newPackage) { + for (TravelPackage aPackage : packages) { + if (aPackage.getName().equals(newPackage.getName()) && + aPackage.getStartDate().equals(newPackage.getStartDate()) && + aPackage.getEndDate().equals(newPackage.getEndDate()) && + aPackage.getHotel().equals(newPackage.getHotel()) && + aPackage.getPrice() == newPackage.getPrice() && + aPackage.getCountry().equals(newPackage.getCountry()) && + aPackage.getMaxParticipants() == newPackage.getMaxParticipants()) { + return true; + } + } return false; } diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java index 20401d06bc..bdcafb94d0 100644 --- a/src/main/java/seedu/duke/command/AddCommand.java +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -28,8 +28,13 @@ public void execute(Packages packages) { if (packages.idExists(newPackage.getID())) { System.out.println("Package with this ID already exists! Please try again."); } else { - packages.addPackage(newPackage); - System.out.println("Package successfully added!"); + if (packages.isContainSamePackage(newPackage)) { + System.out.println("Same package is already exists! Please try again."); + } + else { + packages.addPackage(newPackage); + System.out.println("Package successfully added!"); + } } } } From 9e0ab99df5c37b54cf2aa6a5a4a20262eebfca40 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Thu, 7 Apr 2022 22:33:28 +0800 Subject: [PATCH 086/131] Fix the big integer delete bug --- src/main/java/seedu/duke/Parser.java | 3 ++- src/main/java/seedu/duke/command/WrongFormatCommand.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index d2b04bb2b3..bb357294a7 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -1,5 +1,6 @@ package seedu.duke; +import java.math.BigInteger; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.ResolverStyle; @@ -110,7 +111,7 @@ private static Command prepareDelete(String args) { return new WrongFormatCommand(args); } try { - int id = Integer.parseInt(matcher.group("id")); + int id = new BigInteger(matcher.group("id")).intValueExact(); return new DeleteCommand(id); } catch (Exception e) { return new WrongFormatCommand(e.getMessage()); diff --git a/src/main/java/seedu/duke/command/WrongFormatCommand.java b/src/main/java/seedu/duke/command/WrongFormatCommand.java index 466d89d621..a638cd0d3a 100644 --- a/src/main/java/seedu/duke/command/WrongFormatCommand.java +++ b/src/main/java/seedu/duke/command/WrongFormatCommand.java @@ -18,7 +18,6 @@ public void execute(Packages packages) { System.out.println("Input in wrong format: "); System.out.println(this.feedback); System.out.println("Use the help command to find out the valid commands."); - } } From d7d75b87cf2531a300240335bfbd9e48ab494273 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Thu, 7 Apr 2022 22:35:27 +0800 Subject: [PATCH 087/131] Update Project Portfolio Page --- docs/team/johndoe.md | 6 ------ docs/team/timothy.md | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) delete mode 100644 docs/team/johndoe.md create mode 100644 docs/team/timothy.md diff --git a/docs/team/johndoe.md b/docs/team/johndoe.md deleted file mode 100644 index ab75b391b8..0000000000 --- a/docs/team/johndoe.md +++ /dev/null @@ -1,6 +0,0 @@ -# John Doe - Project Portfolio Page - -## Overview - - -### Summary of Contributions diff --git a/docs/team/timothy.md b/docs/team/timothy.md new file mode 100644 index 0000000000..eeea45ccf9 --- /dev/null +++ b/docs/team/timothy.md @@ -0,0 +1,24 @@ +# Timothy - Project Portfolio Page + +## Overview + + +### Summary of Contributions +#### Code Contributed +[RepoSense Link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18&tabOpen=true&tabType=authorship&tabAuthor=timchang27&tabRepo=AY2122S2-CS2113-F10-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code&authorshipIsBinaryFileTypeChecked=false) + +#### Enhancements Implemented +Implementation of `Reservation` Class in and after v1.0 + +Implemented `Help` Feature in TARBS +- `Help` and `HelpCommand` Class + +#### Contributions to the UG + +#### Contributions to the DG +- Charted out User Stories discussed in v.10 +- Added more User Stories for v2.0 and v2.1 +- Specified Non-Functional Requirements for the team to follow +- Did up Glossary of terms used in our project +- Provided Instructions for Manual Testing +- Included Test Cases From ab804e0251658467c2edbe3048d9bac6c3a3c562 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Thu, 7 Apr 2022 22:38:37 +0800 Subject: [PATCH 088/131] Fix exit command documentation bug --- src/main/java/seedu/duke/command/HelpCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index 002ab5d029..553a6cf854 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -27,6 +27,6 @@ public void execute(Packages packages) { "reserve {package_id},{contact_name},{contact_number},{pax}\nUsage: reserve 3," + "John Doe,91234567,3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + "for a travel package from the packages page\nFormat: remove {package_id},{contact_number}" + - "\nUsage: remove 2,98765432\n" + SEPARATOR); + "\nUsage: remove 2,98765432\n" + SEPARATOR + "EXIT PROGRAM\nFormat/Usage: bye\n" + SEPARATOR); } } From e065dc5971747abc2332f6b75d0d5682f7d56370 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Thu, 7 Apr 2022 22:54:20 +0800 Subject: [PATCH 089/131] Update user guide and help documentation --- docs/UserGuide.md | 4 ++-- src/main/java/seedu/duke/command/HelpCommand.java | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 3e48017cb4..ecfbec3249 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -2,14 +2,14 @@ ## Introduction -{Give a product intro} +{Travel Agency Reservation Booking System (TARBS) is a desktop app for managing reservations for travel packages and tourist attractions, optimised for use via a Command Line Interface (CLI). If you can type fast, TARBS can help to improve efficiency of adding and editing reservations, amongst many other features.} ## Quick Start {Give steps to get started quickly} 1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Duke` from [here](http://link.to/duke). +1. Down the latest version of `TARBS` from [here](https://github.com/AY2122S2-CS2113-F10-3/tp/releases). ## Features diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index 553a6cf854..1f9dd88b83 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -16,16 +16,17 @@ public void execute(Packages packages) { "'packages' page Able to print out specific details of any package\n" + "Format: info {package_id}\n" + "Usage: info 2\n" + SEPARATOR + "ADD PACKAGE\n" + "Allows the user to add a new travel package\ninto the list of available packages\n" + - "Format: add {package_name},{country},{duration},{price},{vacancies}\n" + - "Usage: add Skiing Trip,Sweden,15/2/2022,19/2/2022,800,100\n" + SEPARATOR + + "Format: add {package_name},{package_id},{startDate},{endDate},{hotel},{price}," + + "{country},{vacancies}\n" + + "Usage: add Skiing Trip,1,23/02/2022,24/02/2022,hotelName,90.99,Singapore,20\n" + SEPARATOR + "DELETE PACKAGE\nAllows the user to delete an existing travel package\nfrom the " + "list of available packages\nFormat: delete {package_id}\nUsage: delete 2\n" + - SEPARATOR + "SHOW RESERVATIONS\nShows reservations of the user for " + + SEPARATOR + "VIEW RESERVATIONS\nShows reservations of the user for " + "a specified travel package\nfrom the packages page\nFormat: reservations " + "{package_id}\nUsage: reservations 3\n" + SEPARATOR + "MAKE RESERVATION" + "\nCreates a reservation for a travel package from the packages page\nFormat: " + - "reserve {package_id},{contact_name},{contact_number},{pax}\nUsage: reserve 3," + - "John Doe,91234567,3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + + "reserve {package_id},{contact_name},{contact_number},{number_pax}\nUsage: reserve 3," + + "John,91234567,3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + "for a travel package from the packages page\nFormat: remove {package_id},{contact_number}" + "\nUsage: remove 2,98765432\n" + SEPARATOR + "EXIT PROGRAM\nFormat/Usage: bye\n" + SEPARATOR); } From 44cce7b7eb03ecf7fd9e840fe1401788b941b075 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Thu, 7 Apr 2022 22:55:26 +0800 Subject: [PATCH 090/131] Fix documentation issue --- docs/UserGuide.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index ecfbec3249..317075fee3 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -71,15 +71,15 @@ Example of usage: ## Command Summary -| Command | Syntax | -| --- | :--- | -| packages | packages | -| info | info {num} | -| add | add {package_name} {country} {duration} {price} {vacancies} | -| delete | delete {num} | +| Command | Syntax | +| --- |:----------------------------------------------------------------------| +| packages | packages | +| info | info {num} | +| add | add {package_name} {country} {duration} {price} {vacancies} | +| delete | delete {package_number} | | reserve | reserve {package_number} {contact_name} {contact_number} {number_pax} | -| remove | remove {reservation_id} | -| reservations | reservations {package_number} | +| remove | remove {reservation_id} | +| reservations | reservations {package_number} | From 0a820cacb93701c911ec7da18542cba82880f469 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Thu, 7 Apr 2022 23:29:07 +0800 Subject: [PATCH 091/131] Update documentation --- docs/UserGuide.md | 27 ++++++++++++------ docs/team/edemirkirkan.md | 28 +++++++++++++++++++ docs/team/ege.md | 0 .../java/seedu/duke/command/HelpCommand.java | 7 ++--- 4 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 docs/team/edemirkirkan.md delete mode 100644 docs/team/ege.md diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 317075fee3..82334a648e 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -27,6 +27,15 @@ Example of usage: `add Skiing Trip,1,23/02/2022,24/02/2022,hotelName,90.99,Singapore,20` +### Viewing a package: `info` +View a specified Travel Package from the list of Packages based on the package ID. + +Format: `info {package_id}` + +Example of usage: + +`info 2` + ### Deleting a package: `delete` Delete a Travel Package from the list of Packages based on the package ID. @@ -71,15 +80,15 @@ Example of usage: ## Command Summary -| Command | Syntax | -| --- |:----------------------------------------------------------------------| -| packages | packages | -| info | info {num} | -| add | add {package_name} {country} {duration} {price} {vacancies} | -| delete | delete {package_number} | -| reserve | reserve {package_number} {contact_name} {contact_number} {number_pax} | -| remove | remove {reservation_id} | -| reservations | reservations {package_number} | +| Command | Syntax | +| --- |:-------------------------------------------------------------------------| +| packages | packages | +| info | info {num} | +| add | add {package_name} {country} {start_date} {end_date] {price} {vacancies} | +| delete | delete {package_number} | +| reserve | reserve {package_number} {contact_name} {contact_number} {number_pax} | +| remove | remove {reservation_id} {contact_number} | +| reservations | reservations {package_number} | diff --git a/docs/team/edemirkirkan.md b/docs/team/edemirkirkan.md new file mode 100644 index 0000000000..e9052705b5 --- /dev/null +++ b/docs/team/edemirkirkan.md @@ -0,0 +1,28 @@ +# Ege - Project Portfolio Page + +## Overview + +Our project, Travel Agency Reservation Booking System (TARBS) was developed to allow staff of a Travel Agency to easily record, update and check travel reservations made by customers. + +### Summary of Contributions + +### Code contributed + +[RepoSense Link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=edemirkirkan&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18&tabOpen=true&tabType=authorship&zFR=false&tabAuthor=edemirkirkan&tabRepo=AY2122S2-CS2113-F10-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code&authorshipIsBinaryFileTypeChecked=false) + +### Features and enhancements implemented + +- Implemented the `HelpCommand` class and feature in TARBS + + - Displays the all user documentation in the command line interface + +- Revised coding and style conventions continuously +- Fix most of the PED bugs + +#### Contributions to Developer Guide: + +- Added some user stories, and examples for some commands. + +#### Contributions to User Guide: + +- Added introduction, format, and examples for some commands. diff --git a/docs/team/ege.md b/docs/team/ege.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index 1f9dd88b83..098ec27d25 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -11,10 +11,9 @@ public void execute(Packages packages) { final String SEPARATOR = "---------------------------------------------" + "--------------------------\n"; System.out.println(SEPARATOR + "SHOW ALL PACKAGES\nView a list of all available packages\n" + - "Usage: packages\n" + SEPARATOR + "SHOW CHOSEN PACKAGE\nDisplays the " + - "detailed information of a specific travel " + "package from\nthe " + - "'packages' page Able to print out specific details of any package\n" + - "Format: info {package_id}\n" + "Usage: info 2\n" + SEPARATOR + "ADD PACKAGE\n" + + "Usage: packages\n" + SEPARATOR + "VIEW PACKAGE\nView a specified Travel Package from " + + "the list of Packages based on the package ID\nFormat: info {package_id}\nUsage: info 2\n" + + SEPARATOR + "ADD PACKAGE\n" + "Allows the user to add a new travel package\ninto the list of available packages\n" + "Format: add {package_name},{package_id},{startDate},{endDate},{hotel},{price}," + "{country},{vacancies}\n" + From 142421e2b0d4f4253306e6feffe4dcf584d9806d Mon Sep 17 00:00:00 2001 From: timchang27 Date: Thu, 7 Apr 2022 23:32:50 +0800 Subject: [PATCH 092/131] Resolve Issue --- src/main/java/seedu/duke/Help.java | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/java/seedu/duke/Help.java b/src/main/java/seedu/duke/Help.java index c72d41fc62..5f4059c77b 100644 --- a/src/main/java/seedu/duke/Help.java +++ b/src/main/java/seedu/duke/Help.java @@ -1,24 +1,33 @@ package seedu.duke; +import seedu.duke.command.*; + import java.util.ArrayList; public class Help { private final ArrayList desc; + public static final String PACKAGE_HELP = "View all available packages"; + public static final String INFO_HELP = "View package details"; + public static final String ADD_HELP = "Add a new package"; + public static final String DELETE_HELP = "Delete a package"; + public static final String RESERVE_HELP = "Create a reservation for a package"; + public static final String REMOVE_HELP = "Remove a reservation"; + public static final String RESERVATIONS_HELP = "Shows all reservations for a package"; public Help(){ this.desc = new ArrayList<>(); - String[] packages = {"View all available packages", "packages"}; + String[] packages = {Help.PACKAGE_HELP, PackagesCommand.COMMAND_WORD}; desc.add(packages); - String[] info = {"View package details", "info {num}"}; + String[] info = {Help.INFO_HELP, InfoCommand.COMMAND_WORD}; desc.add(info); - String[] add = {"Add a new package", "add {package_name} {country} {duration} {price} {vacancies}"}; + String[] add = {Help.ADD_HELP, AddCommand.COMMAND_WORD + "{package_name} {country} {duration} {price} {vacancies}"}; desc.add(add); - String[] delete = {"Delete a package", "delete {num}"}; + String[] delete = {Help.DELETE_HELP, DeleteCommand.COMMAND_WORD + "{num}"}; desc.add(delete); - String[] reserve = {"Create a reservation for a package", "reserve {package_number},{contact_name},{contact_number},{number_pax}"}; + String[] reserve = {Help.RESERVE_HELP, ReservationCommand.COMMAND_WORD + "{package_number},{contact_name},{contact_number},{number_pax}"}; desc.add(reserve); - String[] remove = {"Remove a reservation","remove {travelpackageID},{contact_number}"}; + String[] remove = {Help.REMOVE_HELP, RemoveReservationCommand.COMMAND_WORD + "{travelpackageID},{contact_number}"}; desc.add(remove); - String[] reservations = {"Shows all reservations for a package", "reservations {package_number}"}; + String[] reservations = {Help.RESERVATIONS_HELP, PrintReservationsCommand.COMMAND_WORD + "{package_number}"}; desc.add(reservations); } From 2b954f0ad97d1719a60d752915c2f75ae60b2a74 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 8 Apr 2022 00:14:19 +0800 Subject: [PATCH 093/131] Improved Help and HelpCommand, Corrected Add Instructions --- data.txt | 4 -- src/main/java/seedu/duke/TARBS.java | 8 ++- .../java/seedu/duke/command/HelpCommand.java | 61 +++++++++++++------ 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/data.txt b/data.txt index de1993a576..e69de29bb2 100644 --- a/data.txt +++ b/data.txt @@ -1,4 +0,0 @@ -Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ -Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% -Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% -ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ diff --git a/src/main/java/seedu/duke/TARBS.java b/src/main/java/seedu/duke/TARBS.java index 9fa827dee5..cd13a8f9fa 100644 --- a/src/main/java/seedu/duke/TARBS.java +++ b/src/main/java/seedu/duke/TARBS.java @@ -14,11 +14,13 @@ public static void run() { Packages packages = storage.createPackages(); boolean endProgram = false; + printDivider(); System.out.println("Welcome to Travel Agency Booking Reservation System!"); Scanner sc = new Scanner(System.in); while (!endProgram) { storage.savePackageToFile(packages); - System.out.println(); + //System.out.println(); + printDivider(); System.out.println("Please enter command: "); try { Command command = Parser.parse(sc.nextLine()); @@ -33,4 +35,8 @@ public static void run() { storage.savePackageToFile(packages); } + public static void printDivider() { + System.out.println("_______________________________________________________________________"); + } + } diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index 002ab5d029..e3793fd8f3 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -5,28 +5,53 @@ public class HelpCommand extends Command { public static final String COMMAND_WORD = "help"; + public static final String PACKAGES_FORMAT = "SHOW ALL PACKAGES\n" + + "View a list of all available packages\n" + + "Usage: packages\n"; + public static final String INFO_FORMAT = "SHOW CHOSEN PACKAGE\n" + + "Displays the detailed information of a specific travel package from\nthe " + + "'packages' page Able to print out specific details of any package\n" + + "Format: info {package_id}\n" + + "Usage: info 2\n"; + + public static final String ADD_FORMAT = "ADD PACKAGE\n" + + "Allows the user to add a new travel package\ninto the list of available packages\n" + + "Format: add {package_name},{id},{date1},{date2},{hotel},{price},\n" + + " {country},{vacancies}\n" + + "Usage: add Skiing Trip,1,15/02/2022,19/02/2022,Hotel1,100,Sweden,10\n"; + + public static final String DELETE_FORMAT = "DELETE PACKAGE\n" + + "Allows the user to delete an existing travel package\nfrom the list of available packages\n" + + "Format: delete {package_id}\n" + + "Usage: delete 2\n"; + + public static final String RESERVATIONS_FORMAT = "SHOW RESERVATIONS\n" + + "Shows reservations of the user for a specified travel package\nfrom the packages page\n" + + "Format: reservations {package_id}\n" + + "Usage: reservations 3\n"; + + public static final String RESERVE_FORMAT = "MAKE RESERVATION\n" + + "Creates a reservation for a travel package from the packages page\n" + + "Format: reserve {package_id},{contact_name},{contact_number},{pax}\n" + + "Usage: reserve 3,John Doe,91234567,3\n" ; + + public static final String REMOVE_FORMAT = "REMOVE RESERVATION\n" + + "Deletes a reservation for a travel package from the packages page\n" + + "Format: remove {package_id},{contact_number}" + + "\nUsage: remove 2,98765432\n"; + @Override public void execute(Packages packages) { final String SEPARATOR = "---------------------------------------------" + "--------------------------\n"; - System.out.println(SEPARATOR + "SHOW ALL PACKAGES\nView a list of all available packages\n" + - "Usage: packages\n" + SEPARATOR + "SHOW CHOSEN PACKAGE\nDisplays the " + - "detailed information of a specific travel " + "package from\nthe " + - "'packages' page Able to print out specific details of any package\n" + - "Format: info {package_id}\n" + "Usage: info 2\n" + SEPARATOR + "ADD PACKAGE\n" + - "Allows the user to add a new travel package\ninto the list of available packages\n" + - "Format: add {package_name},{country},{duration},{price},{vacancies}\n" + - "Usage: add Skiing Trip,Sweden,15/2/2022,19/2/2022,800,100\n" + SEPARATOR + - "DELETE PACKAGE\nAllows the user to delete an existing travel package\nfrom the " + - "list of available packages\nFormat: delete {package_id}\nUsage: delete 2\n" + - SEPARATOR + "SHOW RESERVATIONS\nShows reservations of the user for " + - "a specified travel package\nfrom the packages page\nFormat: reservations " + - "{package_id}\nUsage: reservations 3\n" + SEPARATOR + "MAKE RESERVATION" + - "\nCreates a reservation for a travel package from the packages page\nFormat: " + - "reserve {package_id},{contact_name},{contact_number},{pax}\nUsage: reserve 3," + - "John Doe,91234567,3\n" + SEPARATOR + "REMOVE RESERVATION\nDeletes a reservation " + - "for a travel package from the packages page\nFormat: remove {package_id},{contact_number}" + - "\nUsage: remove 2,98765432\n" + SEPARATOR); + System.out.println(SEPARATOR + + PACKAGES_FORMAT + SEPARATOR + + INFO_FORMAT + SEPARATOR + + ADD_FORMAT + SEPARATOR + + DELETE_FORMAT + SEPARATOR + + RESERVATIONS_FORMAT + SEPARATOR + + RESERVE_FORMAT + SEPARATOR + + REMOVE_FORMAT + SEPARATOR); } } From 0a94da323479253091ba4841854d47e518a1acd2 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 8 Apr 2022 00:15:02 +0800 Subject: [PATCH 094/131] Format Data --- data.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data.txt b/data.txt index e69de29bb2..7b9331e7ec 100644 --- a/data.txt +++ b/data.txt @@ -0,0 +1,4 @@ +Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ +Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% +Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% +ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ \ No newline at end of file From 885c839dea42b0a042693d48fe0318fdf80f21b6 Mon Sep 17 00:00:00 2001 From: timchang27 <64303732+timchang27@users.noreply.github.com> Date: Fri, 8 Apr 2022 00:25:37 +0800 Subject: [PATCH 095/131] Update UserGuide.md --- docs/UserGuide.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 3e48017cb4..0c80f80fa7 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -2,18 +2,22 @@ ## Introduction -{Give a product intro} +Travel Agency Reservation Booking System (TARBS) is a system for employees of travel agencies to track and record customers’ booking of travel packages. -## Quick Start +### Why do we need TARBS? +Travel agencies often have to manage multiple customers and their respective bookings or plans. -{Give steps to get started quickly} +## Quick Start 1. Ensure that you have Java 11 or above installed. 1. Down the latest version of `Duke` from [here](http://link.to/duke). ## Features -{Give detailed description of each feature} +### Quick Help: `help` +Print detailed instructions on the available commands that users may input + +Format: `help` ### Adding a package: `add` Adds a new Travel Package to the list of Packages. @@ -73,6 +77,7 @@ Example of usage: | Command | Syntax | | --- | :--- | +| help | help | | packages | packages | | info | info {num} | | add | add {package_name} {country} {duration} {price} {vacancies} | From 6f3ee1a2d0ebd2543a62cca9db4948f644102d01 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Fri, 8 Apr 2022 00:28:10 +0800 Subject: [PATCH 096/131] Added PPP --- docs/team/timothy.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/team/timothy.md b/docs/team/timothy.md index eeea45ccf9..9e6575f11a 100644 --- a/docs/team/timothy.md +++ b/docs/team/timothy.md @@ -8,13 +8,20 @@ [RepoSense Link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18&tabOpen=true&tabType=authorship&tabAuthor=timchang27&tabRepo=AY2122S2-CS2113-F10-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code&authorshipIsBinaryFileTypeChecked=false) #### Enhancements Implemented -Implementation of `Reservation` Class in and after v1.0 +- Implementation of `Reservation` Class in and after v1.0 + +- Implemented `Help` Feature in TARBS + - `Help` and `HelpCommand` Class + +- Added Improvements in Formatting for Help messages +- Improved Readability of Interface -Implemented `Help` Feature in TARBS -- `Help` and `HelpCommand` Class #### Contributions to the UG +- Writeup on Project Introduction +- Writeup on some Project Features + #### Contributions to the DG - Charted out User Stories discussed in v.10 - Added more User Stories for v2.0 and v2.1 From 17b7f092b16644d3d074e10898f8266970f3af62 Mon Sep 17 00:00:00 2001 From: timchang27 <64303732+timchang27@users.noreply.github.com> Date: Fri, 8 Apr 2022 00:34:46 +0800 Subject: [PATCH 097/131] Update UserGuide.md --- docs/UserGuide.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 0c80f80fa7..b522ab48b7 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -17,7 +17,21 @@ Travel agencies often have to manage multiple customers and their respective boo ### Quick Help: `help` Print detailed instructions on the available commands that users may input -Format: `help` +Usage: `help` + +### Show all packages: `packages` + +View a list of all available packages + +Usage: `packages` + +### Get info on a specific package: `info` + +Displays the detailed information of a specific travel package + +Format: `info {num}` + +Usage: `info 2` ### Adding a package: `add` Adds a new Travel Package to the list of Packages. From ba84d08d89e82cfc614f503e7391342dccd85d52 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Apr 2022 12:29:25 +0800 Subject: [PATCH 098/131] Rename brendan PPP --- docs/team/{brendan.md => bbawj.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/team/{brendan.md => bbawj.md} (100%) diff --git a/docs/team/brendan.md b/docs/team/bbawj.md similarity index 100% rename from docs/team/brendan.md rename to docs/team/bbawj.md From 0d5af471090d05528cde13ec63f948f9d103343b Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sat, 9 Apr 2022 12:30:05 +0800 Subject: [PATCH 099/131] Update justyn.md --- docs/team/justyn.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/team/justyn.md b/docs/team/justyn.md index 4f027526a2..037cfdb72b 100644 --- a/docs/team/justyn.md +++ b/docs/team/justyn.md @@ -15,6 +15,7 @@ Our project, Travel Agency Reservation Booking System (TARBS) was developed to a - Implemented handling of invalid save data (if data is tampered with in the saved file) - Added JUnit tests for `Storage` +- Fixed bugs for PE dry run #### Contributions to Developer Guide: - Added explanation for `Storage` From 55e6f2aca259a563e672cb50a503d1ab2f0df63a Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Sat, 9 Apr 2022 12:32:01 +0800 Subject: [PATCH 100/131] Rename justyn.md to mafpovbul.md --- docs/team/{justyn.md => mafpovbul.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/team/{justyn.md => mafpovbul.md} (100%) diff --git a/docs/team/justyn.md b/docs/team/mafpovbul.md similarity index 100% rename from docs/team/justyn.md rename to docs/team/mafpovbul.md From 0002a5e9447c443869275fb8e61e33c38a4f32d1 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Sun, 10 Apr 2022 02:54:57 +0800 Subject: [PATCH 101/131] Rename timothy.md to timchang27.md --- docs/team/{timothy.md => timchang27.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/team/{timothy.md => timchang27.md} (100%) diff --git a/docs/team/timothy.md b/docs/team/timchang27.md similarity index 100% rename from docs/team/timothy.md rename to docs/team/timchang27.md From 57de34d9e546d23a93a2e79f2c645d579d314afe Mon Sep 17 00:00:00 2001 From: timchang27 Date: Sun, 10 Apr 2022 03:47:26 +0800 Subject: [PATCH 102/131] Added Hotel and Country Class --- data.txt | 3 +- src/main/java/seedu/duke/Country.java | 50 +++++++++++++++ src/main/java/seedu/duke/Hotel.java | 36 +++++++++++ src/main/java/seedu/duke/Hotels.java | 64 +++++++++++++++++++ src/main/java/seedu/duke/Storage.java | 5 ++ src/main/java/seedu/duke/TravelPackage.java | 2 +- .../java/seedu/duke/command/AddCommand.java | 6 +- 7 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 src/main/java/seedu/duke/Country.java create mode 100644 src/main/java/seedu/duke/Hotel.java create mode 100644 src/main/java/seedu/duke/Hotels.java diff --git a/data.txt b/data.txt index 7b9331e7ec..2f684f7c66 100644 --- a/data.txt +++ b/data.txt @@ -1,4 +1,5 @@ Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% -ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ \ No newline at end of file +ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ +Trip1 | 10 | 15/02/2022 | 19/02/2022 | Hotel1 | 100.0 | Sweden | 10 | 0$ diff --git a/src/main/java/seedu/duke/Country.java b/src/main/java/seedu/duke/Country.java new file mode 100644 index 0000000000..1364ed99dd --- /dev/null +++ b/src/main/java/seedu/duke/Country.java @@ -0,0 +1,50 @@ +package seedu.duke; + +import java.util.ArrayList; + +public class Country { + private String countryName; + private final ArrayList hotels; + + public Country(String countryName){ + this.countryName = countryName; + this.hotels = new ArrayList<>(); + } + public Country(ArrayList h) { + this.hotels = h; + } + + public String getCountryName(){ + return countryName; + } + + public void addHotel(Hotel newHotel) { + hotels.add(newHotel); + } + + public void removePackage(int index) { + hotels.remove(index); + } + + public boolean idExists(int id) { + for (Hotel aHotel : hotels) { + if (aHotel.getHotelID() == id) { + return true; + } + } + return false; + } + + public boolean isContainSameHotel(Hotel newHotel) { + for (Hotel aHotel : hotels) { + if (aHotel.getHotelID() == newHotel.getHotelID() && + aHotel.getHotelName().equals(newHotel.getHotelName()) && + aHotel.getCountry().equals((newHotel.getCountry())) && + aHotel.getPrice() == newHotel.getPrice() + ) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/seedu/duke/Hotel.java b/src/main/java/seedu/duke/Hotel.java new file mode 100644 index 0000000000..e8e4c478e7 --- /dev/null +++ b/src/main/java/seedu/duke/Hotel.java @@ -0,0 +1,36 @@ +package seedu.duke; + +public class Hotel { + + public static final String EXAMPLEHOTELID = "456"; + public static final String EXAMPLEHOTELNAME = "Hotel Schweizerhof Luzern"; + public static final String EXAMPLEHOTELCOUNTRY = "Switzerland"; + + private int hotelID; + private String hotelName; + private Country country; + private int price; + + public Hotel(int hotelID, String hotelName, Country country, int price){ + this.hotelID = hotelID; + this.hotelName = hotelName; + this.country = country; + this.price = price; + } + + public int getHotelID(){ + return hotelID; + } + + public String getHotelName(){ + return hotelName; + } + + public Country getCountry(){ + return country; + } + + public int getPrice(){ + return price; + } +} diff --git a/src/main/java/seedu/duke/Hotels.java b/src/main/java/seedu/duke/Hotels.java new file mode 100644 index 0000000000..93c03199b3 --- /dev/null +++ b/src/main/java/seedu/duke/Hotels.java @@ -0,0 +1,64 @@ +package seedu.duke; + +import java.util.ArrayList; + +public class Hotels { + + private final ArrayList hotels; + + public Hotels() { + this.hotels = new ArrayList<>(); + } + + public Hotels(ArrayList h) { + this.hotels = h; + } + + public int getSize() { + return hotels.size(); + } + + public Hotel getHotel(int index) { + return hotels.get(index); + } + + public Hotel getHotelByID(int id) { + for (Hotel hotel : hotels) { + if (hotel.getHotelID() == id) { + return hotel; + } + } + return null; + } + + public void addHotel(Hotel newHotel) { + hotels.add(newHotel); + } + + public void removeHotel(int index) { + hotels.remove(index); + } + + public boolean idExists(int id) { + for (Hotel aHotel : hotels) { + if (aHotel.getHotelID() == id) { + return true; + } + } + return false; + } + + public boolean isContainSameHotel(Hotel newHotel) { + for (Hotel aHotel : hotels) { + if (aHotel.getHotelID() == newHotel.getHotelID() && + aHotel.getHotelName().equals(newHotel.getHotelName()) && + aHotel.getCountry().equals((newHotel.getCountry())) && + aHotel.getPrice() == newHotel.getPrice() + ) { + return true; + } + } + return false; + } + +} diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 548a2c79f4..6dbcb3ad44 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -33,6 +33,11 @@ public class Storage { static final int reservationCustomerNumberIndex = 2; static final int reservationNumPaxIndex = 3; + static final int hotelIDIndex = 0; + static final int hotelNameIndex = 1; + static final int hotelCountryIndex = 2; + static final int hotelPriceIndex = 3; + /** * String representation of the file path to the save file * diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index 6e5aaf37ea..fa1638b69e 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -30,7 +30,7 @@ public class TravelPackage { private Reservations reservationList; public TravelPackage(String name, int id, LocalDate startDate, LocalDate endDate, - String hotel, double price, String country, int maxParticipants) { + String hotel, double price, String country, int maxParticipants) { this.name = name; this.id = id; this.startDate = startDate; diff --git a/src/main/java/seedu/duke/command/AddCommand.java b/src/main/java/seedu/duke/command/AddCommand.java index bdcafb94d0..c7d0dd7881 100644 --- a/src/main/java/seedu/duke/command/AddCommand.java +++ b/src/main/java/seedu/duke/command/AddCommand.java @@ -2,6 +2,8 @@ import java.time.LocalDate; +import seedu.duke.Country; +import seedu.duke.Hotel; import seedu.duke.Packages; import seedu.duke.TravelPackage; @@ -13,8 +15,8 @@ public class AddCommand extends Command { private final TravelPackage newPackage; public AddCommand(String name, int id, LocalDate date1, LocalDate date2, String hotel, double price, - String country, - int maxVacancies) { + String country, + int maxVacancies) { this.newPackage = new TravelPackage(name, id, date1, date2, hotel, price, country, maxVacancies); } From ea1ce11797a2afd670f4a970d21012483686d3fa Mon Sep 17 00:00:00 2001 From: timchang27 <64303732+timchang27@users.noreply.github.com> Date: Sun, 10 Apr 2022 03:58:19 +0800 Subject: [PATCH 103/131] Update timchang27.md --- docs/team/timchang27.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/team/timchang27.md b/docs/team/timchang27.md index 9e6575f11a..e3b56cdf85 100644 --- a/docs/team/timchang27.md +++ b/docs/team/timchang27.md @@ -9,12 +9,13 @@ #### Enhancements Implemented - Implementation of `Reservation` Class in and after v1.0 - +- Implemented `Hotel` and `Country` Classes for v2.1 - Implemented `Help` Feature in TARBS - `Help` and `HelpCommand` Class - Added Improvements in Formatting for Help messages - Improved Readability of Interface +- Fixed bugs for PE Dry-Run #### Contributions to the UG From 76eb9104730656ab021f7798b848f97eae93ee47 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Sun, 10 Apr 2022 21:39:26 +0800 Subject: [PATCH 104/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b8ac8d05ff..9094d095cf 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,13 +1,9 @@ # Travel Agency Reservation Booking System (TARBS) # Developer Guide -## Acknowledgements -{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} ## Design & implementation - -{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} ### Basic Class Diagram ![image](https://user-images.githubusercontent.com/53790951/160271319-4a351f51-afd7-4e04-9451-f04143146551.png) @@ -73,6 +69,7 @@ | Command | Format Examples | | ------- | --------------- | +|help|help
(prints details of all commands)| |packages|packages
(prints details of all packages)| |info|info {num} (num < number of available packages)
e.g. info 2 | |add|add {package_name},{ID},{startDate},{endDate},{hotel},{price},{country},{vacancies}
e.g. add Skiing Trip,1,23/2/2022,24/2/2022,hotelName,90.99,Singapore,20
adds a TravelPackage| From 4f0cdcfc18fc08bda304c7422520043e0022c8d0 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Sun, 10 Apr 2022 22:03:41 +0800 Subject: [PATCH 105/131] Add and View Hotels Command --- src/main/java/seedu/duke/Country.java | 3 +- src/main/java/seedu/duke/Hotel.java | 28 ++++++++++--- src/main/java/seedu/duke/Hotels.java | 15 +++++++ src/main/java/seedu/duke/Parser.java | 41 +++++++++++++++++++ src/main/java/seedu/duke/Storage.java | 33 +++++++++++++++ src/main/java/seedu/duke/TravelPackage.java | 11 +++++ .../seedu/duke/command/AddHotelCommand.java | 32 +++++++++++++++ .../duke/command/PrintHotelsCommand.java | 31 ++++++++++++++ 8 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 src/main/java/seedu/duke/command/AddHotelCommand.java create mode 100644 src/main/java/seedu/duke/command/PrintHotelsCommand.java diff --git a/src/main/java/seedu/duke/Country.java b/src/main/java/seedu/duke/Country.java index 1364ed99dd..2521ae2c23 100644 --- a/src/main/java/seedu/duke/Country.java +++ b/src/main/java/seedu/duke/Country.java @@ -40,7 +40,8 @@ public boolean isContainSameHotel(Hotel newHotel) { if (aHotel.getHotelID() == newHotel.getHotelID() && aHotel.getHotelName().equals(newHotel.getHotelName()) && aHotel.getCountry().equals((newHotel.getCountry())) && - aHotel.getPrice() == newHotel.getPrice() + aHotel.getPrice() == newHotel.getPrice() && + aHotel.getPackageID() == newHotel.getPackageID() ) { return true; } diff --git a/src/main/java/seedu/duke/Hotel.java b/src/main/java/seedu/duke/Hotel.java index e8e4c478e7..d396e46ddd 100644 --- a/src/main/java/seedu/duke/Hotel.java +++ b/src/main/java/seedu/duke/Hotel.java @@ -8,14 +8,16 @@ public class Hotel { private int hotelID; private String hotelName; - private Country country; - private int price; + private String country; + private int packageID; + private double price; - public Hotel(int hotelID, String hotelName, Country country, int price){ + public Hotel(int hotelID, String hotelName, String country, double price, int packageID){ this.hotelID = hotelID; this.hotelName = hotelName; this.country = country; this.price = price; + this.packageID = packageID; } public int getHotelID(){ @@ -26,11 +28,27 @@ public String getHotelName(){ return hotelName; } - public Country getCountry(){ + public String getCountry(){ return country; } - public int getPrice(){ + public double getPrice(){ return price; } + + public int getPackageID() { + return packageID; + } + + public String toString() { + return "Package " + getPackageID() + "\n" + + "ID " + getHotelID() + "\n" + + "Name " + getHotelName() + "\n" + + "Country " + getCountry() + "\n" + + "Price " + getPrice() + "\n"; + } + + public String toSave() { + return hotelID + "," + hotelName + "," + country + "," + price + "," + packageID; + } } diff --git a/src/main/java/seedu/duke/Hotels.java b/src/main/java/seedu/duke/Hotels.java index 93c03199b3..c35189ee37 100644 --- a/src/main/java/seedu/duke/Hotels.java +++ b/src/main/java/seedu/duke/Hotels.java @@ -39,6 +39,17 @@ public void removeHotel(int index) { hotels.remove(index); } + public void printAllHotels() { + if (hotels.size() == 0) { + System.out.println("No hotels added yet!"); + } + else { + for (int i = 0; i < hotels.size(); i++) { + System.out.println(i + 1 + ". " + hotels.get(i).toString()); + } + } + } + public boolean idExists(int id) { for (Hotel aHotel : hotels) { if (aHotel.getHotelID() == id) { @@ -61,4 +72,8 @@ public boolean isContainSameHotel(Hotel newHotel) { return false; } + public void initHotel(Hotel newHotel) { + hotels.add(newHotel); + } + } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index bb357294a7..326adaa701 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -28,6 +28,11 @@ public class Parser { public static final Pattern ONE_ARGS_FORMAT = Pattern.compile("(?[\\d]+)"); + public static final Pattern HOTEL_ARGS_FORMAT = Pattern.compile( + "(?[\\d]+),(?.+),(?.+),(?.+),(?[\\d]+)"); + + public static final Pattern HOTELS_ARGS_FORMAT = Pattern.compile("(?[\\d]+)"); + public static DateTimeFormatter PARSE_FORMAT = DateTimeFormatter.ofPattern("dd/MM/uuuu") .withResolverStyle(ResolverStyle.STRICT); @@ -68,6 +73,12 @@ public static Command parse(String input) { case PrintReservationsCommand.COMMAND_WORD: return prepareReservations(arguments); + case AddHotelCommand.COMMAND_WORD: + return prepareAddHotel(arguments); + + case PrintHotelsCommand.COMMAND_WORD: + return prepareHotels(arguments); + default: return new ErrorCommand(input); } @@ -174,6 +185,36 @@ private static Command prepareReservations(String args) { } } + private static Command prepareAddHotel(String args) { + final Matcher matcher = HOTEL_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + return new WrongFormatCommand(args); + } + try { + int hotelID = Integer.parseInt(matcher.group("id")); + String hotelName = matcher.group("name"); + String country = matcher.group("country"); + double price = Double.parseDouble(matcher.group("price")); + int packageID = Integer.parseInt(matcher.group("packageid")); + return new AddHotelCommand(hotelID, hotelName, country, price, packageID); + } catch (Exception e) { + return new WrongFormatCommand(e.getMessage()); + } + } + + private static Command prepareHotels(String args) { + final Matcher matcher = HOTELS_ARGS_FORMAT.matcher(args.trim()); + if (!matcher.matches()) { + return new WrongFormatCommand(args); + } + try { + int id = Integer.parseInt(matcher.group("id")); + return new PrintHotelsCommand(id); + } catch (Exception e) { + return new WrongFormatCommand(e.getMessage()); + } + } + public static boolean dateStartEndValid(LocalDate startDate, LocalDate endDate) { return endDate.isAfter(startDate); } diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index 6dbcb3ad44..0403d5edc4 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -37,6 +37,7 @@ public class Storage { static final int hotelNameIndex = 1; static final int hotelCountryIndex = 2; static final int hotelPriceIndex = 3; + static final int hotelPackageIDIndex = 3; /** * String representation of the file path to the save file @@ -199,6 +200,38 @@ public TravelPackage parseTravelPackageFile(String str) throws InvalidInputExcep } } + public Hotel parseHotel(String str) throws InvalidInputException { + try{ + String[] arrayElements = str.split("\\|"); + String hotelName = arrayElements[hotelNameIndex].trim(); + String hID = arrayElements[hotelIDIndex].trim(); + int id = Integer.parseInt(hID); + String country = arrayElements[hotelCountryIndex].trim(); + double price = Double.parseDouble(arrayElements[hotelPriceIndex].trim()); + int packageID = Integer.parseInt(arrayElements[hotelPackageIDIndex].trim()); + if (price <= 0) { + throw new InvalidInputException("Price should not be less than or equal to 0!"); + } + return new Hotel(id, hotelName, country, price, packageID); + } catch (Exception e) { + throw new InvalidInputException(e.getMessage()); + } + } + + public Hotels parseHotelFile(String savedHotels) throws InvalidInputException { + Hotels hotelsList = new Hotels(); + String[] arrayElements = savedHotels.split("%"); + try { + for (String arrayElement : arrayElements) { + Hotel newHotel = parseHotel(arrayElement); + hotelsList.initHotel(newHotel); + } + return hotelsList; + } catch (Exception e) { + throw new InvalidInputException(e.getMessage()); + } + } + public boolean makeNewSaveFile() { System.out.println("Uh oh, it seems like your file has been corrupted!"); System.out.println("Would you like to restart with a new file? Your previous data will be wiped out. (Y/N)"); diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index fa1638b69e..892b98fb5d 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -28,6 +28,7 @@ public class TravelPackage { private final int maxParticipants; private int numParticipants; private Reservations reservationList; + private Hotels hotelsList; public TravelPackage(String name, int id, LocalDate startDate, LocalDate endDate, String hotel, double price, String country, int maxParticipants) { @@ -41,6 +42,7 @@ public TravelPackage(String name, int id, LocalDate startDate, LocalDate endDate this.maxParticipants = maxParticipants; this.numParticipants = 0; this.reservationList = new Reservations(); + this.hotelsList = new Hotels(); } public TravelPackage(String name, int id, LocalDate startDate, LocalDate endDate, @@ -55,6 +57,7 @@ public TravelPackage(String name, int id, LocalDate startDate, LocalDate endDate this.maxParticipants = maxParticipants; this.numParticipants = numParticipants; this.reservationList = new Reservations(); + this.hotelsList = new Hotels(); } public boolean isFull() { @@ -101,6 +104,10 @@ public Reservations getReservationList() { return this.reservationList; } + public Hotels getHotelsList() { + return this.hotelsList; + } + public void addParticipants(int addParticipants) { this.numParticipants = this.numParticipants + addParticipants; } @@ -113,6 +120,10 @@ public void setReservationList(Reservations r) { this.reservationList = r; } + public void setHotelsList(Hotels h) { + this.hotelsList = h; + } + public String toString() { return "Here are the details for " + this.name + ", Travel Package ID of " diff --git a/src/main/java/seedu/duke/command/AddHotelCommand.java b/src/main/java/seedu/duke/command/AddHotelCommand.java new file mode 100644 index 0000000000..614bd7039f --- /dev/null +++ b/src/main/java/seedu/duke/command/AddHotelCommand.java @@ -0,0 +1,32 @@ +package seedu.duke.command; + +import seedu.duke.Hotel; +import seedu.duke.Packages; + +public class AddHotelCommand extends Command{ + public static final String COMMAND_WORD = "addHotel"; + private final Hotel newHotel; + + public AddHotelCommand(int hotelID, String hotelName, String country, double price, int packageID) { + this.newHotel = new Hotel(hotelID, hotelName, country, price, packageID); + } + + public void execute(Packages packages) { + boolean isFoundID = false; + for (int i = 0; i < packages.getSize(); i++) { + if (packages.getPackage(i).getID() == newHotel.getPackageID()) { + isFoundID = true; + System.out.println("Hotel has been added!"); + break; + } + } + if (!isFoundID) { + System.out.println("Hotel ID not found. Please try again."); + } + + } + +} + + + diff --git a/src/main/java/seedu/duke/command/PrintHotelsCommand.java b/src/main/java/seedu/duke/command/PrintHotelsCommand.java new file mode 100644 index 0000000000..b61d973ddb --- /dev/null +++ b/src/main/java/seedu/duke/command/PrintHotelsCommand.java @@ -0,0 +1,31 @@ +package seedu.duke.command; + +import seedu.duke.Packages; +import seedu.duke.TravelPackage; + +public class PrintHotelsCommand extends Command{ + + public static final String COMMAND_WORD = "hotels"; + private final int packageID; + + public PrintHotelsCommand(int packageID) { + this.packageID = packageID; + } + + public void execute(Packages p) { + TravelPackage tp = p.getPackageByID(packageID); + if (tp != null) { + System.out.println("Hotels under this package: "); + tp.getHotelsList().printAllHotels(); + } else { + System.out.println("This package does not exist!"); + } + } + +} + + + + + + From 98f99e4a50bf9c9bc4a4dfb687cff0153c8d852b Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Sun, 10 Apr 2022 22:08:49 +0800 Subject: [PATCH 106/131] Update User Guide corrected command summary FAQ --- docs/UserGuide.md | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 9e60f64a7f..e403d29f4f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -2,7 +2,7 @@ ## Introduction -{Travel Agency Reservation Booking System (TARBS) is a desktop app for managing reservations for travel packages and tourist attractions, optimised for use via a Command Line Interface (CLI). If you can type fast, TARBS can help to improve efficiency of adding and editing reservations, amongst many other features.} +Travel Agency Reservation Booking System (TARBS) is a desktop app for managing reservations for travel packages and tourist attractions, optimised for use via a Command Line Interface (CLI). If you can type fast, TARBS can help to improve efficiency of adding and editing reservations, amongst many other features. ### Why do we need TARBS? @@ -16,7 +16,7 @@ Travel agencies often have to manage multiple customers and their respective boo ## Features ### Quick Help: `help` -Print detailed instructions on the available commands that users may input +Print detailed instructions on the available commands that users may input. Usage: `help` @@ -26,13 +26,6 @@ View a list of all available packages Usage: `packages` -### Get info on a specific package: `info` - -Displays the detailed information of a specific travel package - -Format: `info {num}` - -Usage: `info 2` ### Adding a package: `add` Adds a new Travel Package to the list of Packages. @@ -40,7 +33,9 @@ Adds a new Travel Package to the list of Packages. Format: `add {package_name},{package_id},{startDate},{endDate},{hotel},{price},{country},{vacancies}` * The `startDate` and `endDate` must be in the format DD/MM/YYYY. -* The `price` can only contain numbers or decimal points. +* The `price` can only contain numbers or decimal points. +* `package_id` should be unique. +* Example of usage: @@ -74,7 +69,7 @@ Example of usage: `reserve 3,John,91234567,3` ### Removing a reservation: `remove` -Remove a reservation from a Travel Package. +Remove a reservation from a Travel Package using packageID and contact number. Format: `remove {package_id},{contact_number}` @@ -95,7 +90,9 @@ Example of usage: **Q**: How do I transfer my data to another computer? -**A**: {your answer here} +**A**: When starting the application, data.txt will be created if there isn't one already. Simply place the data.txt with the executable JAR file on the new computer and you are good to go. + + ## Command Summary @@ -105,11 +102,11 @@ Example of usage: | help | help | | packages | packages | | info | info {package_number} | -| add | add {package_name} {country} {duration} {price} {vacancies} | -| delete | delete {package_number} | -| reserve | reserve {package_number} {contact_name} {contact_number} {number_pax} | -| remove | remove {reservation_id} | -| reservations | reservations {package_number} | +| add | add {package_name},{package_id},{startDate},{endDate},{hotel},{price},{country},{max_vacancies} | +| delete | delete {package_id} | +| reserve | reserve {package_id},{contact_name},{contact_number},{number_pax} | +| remove | remove {package_id},{conact_number} | +| reservations | reservations {package_id} | From 0445a59d6b650016dcbe08ff54494be62f821e3c Mon Sep 17 00:00:00 2001 From: timchang27 <64303732+timchang27@users.noreply.github.com> Date: Sun, 10 Apr 2022 22:09:36 +0800 Subject: [PATCH 107/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9094d095cf..7b8f9c018d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -77,6 +77,8 @@ |reserve|reserve {package_id},{contact_name},{contact_number},{number_pax}
e.g reserve 3,John,91234567,3| |remove|remove {package_id},{contact_number}
e.g remove 1,8888888
remove an existing reservation| |reservations|reservations {package_number}
eg. reservations 2
print all reservations for a given travelPackageID| +|addHotel|addHotel {hotel_id},{hotel_name},{country},{price},{package_id}
eg. addHotel 1,Hotel99,Singapore,100,1
Add a Hotel to the Itinerary| +|hotels|hotels {package_number}
eg. hotels 1
View all hotels offering this package| ### Test Case 1 From af9f2474b546f3303923e5ce07bd2a7fe05c3fc6 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Sun, 10 Apr 2022 22:15:47 +0800 Subject: [PATCH 108/131] Update README.md --- docs/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index bbcc99c1e7..baba37f0ce 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,9 @@ -# Duke +# Travel Agency Reservation Booking System - TARBS +TARBS is a CLI application made using Java 11 to help staff of a Travel Agency company keep track of its' travel packages, as well as customer's reservations. +Some features include creating and storing travel packages, viewing of said packages and the ability to record reservations made by customers using their mobile numbers. +It is also user-friendly as it includes the ability to delete any entries that were keyed in wrongly - be it packages or reservations. -{Give product intro here} +Do refer to the links below for more information on the application! Useful links: * [User Guide](UserGuide.md) From 67dabefd502937b38800e0fac6816b231b27474f Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Sun, 10 Apr 2022 22:16:47 +0800 Subject: [PATCH 109/131] Update README.md --- docs/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index baba37f0ce..6cf21edf55 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,9 @@ # Travel Agency Reservation Booking System - TARBS -TARBS is a CLI application made using Java 11 to help staff of a Travel Agency company keep track of its' travel packages, as well as customer's reservations. -Some features include creating and storing travel packages, viewing of said packages and the ability to record reservations made by customers using their mobile numbers. -It is also user-friendly as it includes the ability to delete any entries that were keyed in wrongly - be it packages or reservations. +-TARBS is a CLI application made using Java 11 to help staff of a Travel Agency company keep track of its' travel packages, as well as customer's reservations. +-Some features include creating and storing travel packages, viewing of said packages and the ability to record reservations made by customers using their mobile numbers. +-It is also user-friendly as it includes the ability to delete any entries that were keyed in wrongly - be it packages or reservations. -Do refer to the links below for more information on the application! +-Do refer to the links below for more information on the application! Useful links: * [User Guide](UserGuide.md) From effd44ef852108de762905c43c18f418be95c454 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Sun, 10 Apr 2022 22:17:05 +0800 Subject: [PATCH 110/131] Update README.md --- docs/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 6cf21edf55..8ee9f31acb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,9 @@ # Travel Agency Reservation Booking System - TARBS --TARBS is a CLI application made using Java 11 to help staff of a Travel Agency company keep track of its' travel packages, as well as customer's reservations. --Some features include creating and storing travel packages, viewing of said packages and the ability to record reservations made by customers using their mobile numbers. --It is also user-friendly as it includes the ability to delete any entries that were keyed in wrongly - be it packages or reservations. +- TARBS is a CLI application made using Java 11 to help staff of a Travel Agency company keep track of its' travel packages, as well as customer's reservations. +- Some features include creating and storing travel packages, viewing of said packages and the ability to record reservations made by customers using their mobile numbers. +- It is also user-friendly as it includes the ability to delete any entries that were keyed in wrongly - be it packages or reservations. --Do refer to the links below for more information on the application! +- Do refer to the links below for more information on the application! Useful links: * [User Guide](UserGuide.md) From b01ae46661d241fe11f0b18b0df38788edbca0c3 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Sun, 10 Apr 2022 22:17:26 +0800 Subject: [PATCH 111/131] Update Help Command with Hotel related commands --- src/main/java/seedu/duke/command/HelpCommand.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index e3793fd8f3..4a6e55e342 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -40,6 +40,16 @@ public class HelpCommand extends Command { "Format: remove {package_id},{contact_number}" + "\nUsage: remove 2,98765432\n"; + public static final String ADD_HOTEL_FORMAT = "ADD HOTEL TO ITINERARY\n" + + "Adds Hotel Information to the Itinerary\n" + + "Format: addHotel {hotel_id},{hotel_name},{country},{price},{package_id}" + + "\nUsage: addHotel 1,Hotel99,Singapore,100,1\n"; + + public static final String HOTELS_FORMAT = "VIEW HOTELS\n" + + "Show hotels for a specified travel package\n" + + "Format: hotels {package_number}" + + "\nUsage: hotels 1\n"; + @Override public void execute(Packages packages) { @@ -52,6 +62,8 @@ public void execute(Packages packages) { DELETE_FORMAT + SEPARATOR + RESERVATIONS_FORMAT + SEPARATOR + RESERVE_FORMAT + SEPARATOR + - REMOVE_FORMAT + SEPARATOR); + REMOVE_FORMAT + SEPARATOR + + ADD_HOTEL_FORMAT + SEPARATOR + + HOTELS_FORMAT + SEPARATOR); } } From c9678ea9f8552a1de695fc9b248809652b8aa5ed Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Sun, 10 Apr 2022 22:57:27 +0800 Subject: [PATCH 112/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b8ac8d05ff..d8f6d339bb 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -34,21 +34,13 @@ |v1.0|new user|Add reservation for a customer with basic information such as name, country etc. |Make a reservation| |v1.0|new user|Print a list of all current and available travel packages |View all current travel packages and tell customers about our travel packages with one look| |v1.0|new user|Remove an existing reservation|Remove information that we do not need anymore| -|v1.0|User ready to start using the app| Find out which travel packages are available for the specific location and duration|Make a recommendation of travel package to customers based on their desired location| |v1.0|new user|Search for a specific travel package|Make recommendations to a customer based on their desired travel package requirements| |v2.0|User ready to start using the app|Upload existing reservation data|Get started quickly| |v2.0|User ready to start using the app|Make reservations based on custom input and edit them where necessary|Get familiar with inputting| -|v2.0|User ready to start using the app|See the changes I made from the previous day|Continue working| -|v2.1|Expert user|Create and use shortcuts|Quickly enter the details needed for a reservation and query any details I might need for an existing reservation| -|v2.1|Expert user|Update ratings of travel packages based on customer feedback|Provide a better recommendations for future customers| |v2.1|Expert user|Ascertain the error in my input based on the error messages from the application|Quickly troubleshoot any mistakes that would slow down my work| |v2.1|Expert user|View all reservations currently under a specific travel package|Optimize that travel package according to user’s feedback| -|v2.1|Expert user|I can build a customized travel package based on what the customer wants|It appeals to customers who do not want our existing tour packages| -|v2.1|Expert user|Add in hotels to the list of available hotel options|Update the itinerary | -|v2.1|Expert user|Add in countries to the list of available countries|Update the itinerary| |v2.1|Expert user|Sort all reservations according to month|Analyze trends throughout the year| -|v2.1|Expert user|Mark a reservation as ‘completed’|Access both completed and ongoing reservations| -|v2.1|Expert user|Compute the price of custom travel packages|Get a rough estimate for what to charge the customer| + ## Non-Functional Requirements From c52e37a8e242670b3b2a8fbbfebb94b93a829143 Mon Sep 17 00:00:00 2001 From: chintaiann Date: Mon, 11 Apr 2022 02:28:04 +0800 Subject: [PATCH 113/131] implement sort and print package function --- .gitignore | 3 +- META-INF/MANIFEST.MF | 3 + data.txt | 9 +- src/main/java/META-INF/MANIFEST.MF | 6 +- src/main/java/seedu/duke/Parser.java | 5 +- src/main/java/seedu/duke/TravelPackage.java | 8 ++ .../seedu/duke/command/PrintAllCommand.java | 116 ++++++++++++++++++ 7 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 META-INF/MANIFEST.MF create mode 100644 src/main/java/seedu/duke/command/PrintAllCommand.java diff --git a/.gitignore b/.gitignore index 104a328ed9..b564905b82 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT -.vscode/ \ No newline at end of file +.vscode/ +data.txt diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..c076f925ef --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: seedu.duke.TARBS + diff --git a/data.txt b/data.txt index 2f684f7c66..30c161b79c 100644 --- a/data.txt +++ b/data.txt @@ -1,5 +1,4 @@ -Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ -Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% -Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% -ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ -Trip1 | 10 | 15/02/2022 | 19/02/2022 | Hotel1 | 100.0 | Sweden | 10 | 0$ +package1 | 0 | 23/12/2021 | 24/12/2021 | hotelname1 | 90.99 | singapore | 20 | 0$ +package2 | 1 | 05/12/2021 | 06/12/2021 | hotelname2 | 90.0 | korea | 30 | 0$ +package3 | 2 | 05/05/2020 | 06/06/2020 | hotelname3 | 20.0 | india | 40 | 0$ +package4 | 3 | 06/06/2021 | 06/07/2021 | hotelname4 | 19.9 | india | 20 | 0$ diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF index 182e949e6b..c076f925ef 100644 --- a/src/main/java/META-INF/MANIFEST.MF +++ b/src/main/java/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ -Manifest-Version: 1.0 -Main-Class: seedu.duke.TARBS - +Manifest-Version: 1.0 +Main-Class: seedu.duke.TARBS + diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index bb357294a7..67e0c2adc3 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -67,7 +67,8 @@ public static Command parse(String input) { case PrintReservationsCommand.COMMAND_WORD: return prepareReservations(arguments); - + case PrintAllCommand.COMMAND_WORD: + return new PrintAllCommand(); default: return new ErrorCommand(input); } @@ -174,6 +175,8 @@ private static Command prepareReservations(String args) { } } + + public static boolean dateStartEndValid(LocalDate startDate, LocalDate endDate) { return endDate.isAfter(startDate); } diff --git a/src/main/java/seedu/duke/TravelPackage.java b/src/main/java/seedu/duke/TravelPackage.java index fa1638b69e..cb3125596e 100644 --- a/src/main/java/seedu/duke/TravelPackage.java +++ b/src/main/java/seedu/duke/TravelPackage.java @@ -73,6 +73,14 @@ public String getStartDate() { return this.startDate.format(printFormat); } + public LocalDate getLocalStartDate() { + return this.startDate; + } + + public LocalDate getLocalEndDate() { + return this.endDate; + } + public String getEndDate() { return this.endDate.format(printFormat); } diff --git a/src/main/java/seedu/duke/command/PrintAllCommand.java b/src/main/java/seedu/duke/command/PrintAllCommand.java new file mode 100644 index 0000000000..52832dbf27 --- /dev/null +++ b/src/main/java/seedu/duke/command/PrintAllCommand.java @@ -0,0 +1,116 @@ +package seedu.duke.command; +import seedu.duke.Packages; +import seedu.duke.TravelPackage; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.InputMismatchException; +import java.util.Scanner; +import java.util.Collections; +public class PrintAllCommand extends Command { + public static final String COMMAND_WORD = "all"; + public ArrayList sortedPackages; + + public PrintAllCommand() { + this.sortedPackages = new ArrayList<>(); + } + + public void execute(Packages p) { + for (int i = 0; i < p.getSize(); i++) { + sortedPackages.add(p.getPackage(i)); + } + Scanner in = new Scanner(System.in); + System.out.println("Sort packages by:"); + System.out.println("1. Date (Earliest to Latest) "); + System.out.println("2. Number of vacancies left"); + System.out.println("3. Price"); + System.out.println("4. Return to main menu."); + while (true){ + try { + int input = in.nextInt(); + if (input != 1 && input != 2 && input != 3 && input !=4) { + throw new InputMismatchException(); + } + if (input == 4) { + break; + } + + if (input == 1) { + sortByDate(); + printSortedPackages(); + break; + } + + if (input == 2) { + sortByVacancies(); + printSortedPackages(); + break; + } + + if (input == 3) { + sortByPrice(); + printSortedPackages(); + break; + } + } + catch (java.util.InputMismatchException e) { + System.out.println("Please enter 1,2,3 or 4!"); + in.nextLine(); + } + } + } + + public void sortByDate() { + for (int i = 1; i < this.sortedPackages.size(); i++) { + int k = i; + for (int j = i-1; j>=0; j--) { + if (sortedPackages.get(k).getLocalStartDate().isBefore(sortedPackages.get(j).getLocalStartDate())){ + Collections.swap(sortedPackages,k,j); + k = k - 1; + } + else { + continue; + } + } + } + } + public void sortByPrice() { + for (int i = 1; i < this.sortedPackages.size(); i++) { + int k = i; + for (int j = i-1; j>=0; j--) { + if (sortedPackages.get(k).getPrice() < (sortedPackages.get(j).getPrice())){ + Collections.swap(sortedPackages,k,j); + k = k - 1; + } + else { + continue; + } + } + } + } + public void sortByVacancies() { + for (int i = 1; i < this.sortedPackages.size(); i++) { + int k = i; + for (int j = i-1; j>=0; j--) { + if ((sortedPackages.get(k).getMaxParticipants() - sortedPackages.get(k).getNumParticipants()) + > (sortedPackages.get(j).getMaxParticipants() - sortedPackages.get(j).getNumParticipants())){ + Collections.swap(sortedPackages,k,j); + k = k - 1; + } + else { + continue; + } + } + } + } + + public void printSortedPackages(){ + if (this.sortedPackages.size() == 0) { + System.out.println("No packages found!"); + } + for (int i = 0; i < this.sortedPackages.size(); i++) { + System.out.println( + i + 1 + ". PackageID-" + sortedPackages.get(i).getID() + " | " + sortedPackages.get(i).getCountry() + " - " + sortedPackages.get(i).getName()); + } + } + +} From 2c01e2c7135ddb081519a12a360f3810effb6d5a Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Mon, 11 Apr 2022 09:44:57 +0800 Subject: [PATCH 114/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ad554aedf4..ab198b00a4 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -35,7 +35,7 @@ |v2.0|User ready to start using the app|Make reservations based on custom input and edit them where necessary|Get familiar with inputting| |v2.1|Expert user|Ascertain the error in my input based on the error messages from the application|Quickly troubleshoot any mistakes that would slow down my work| |v2.1|Expert user|View all reservations currently under a specific travel package|Optimize that travel package according to user’s feedback| -|v2.1|Expert user|Sort all reservations according to month|Analyze trends throughout the year| +|v2.1|Expert user|Sort all packages according to date, price or vacancies|Give better recommendations to customers| ## Non-Functional Requirements From 5c5b2ac47e8fb7b3580a13ba47aba29198bfd655 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Mon, 11 Apr 2022 09:46:35 +0800 Subject: [PATCH 115/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ab198b00a4..8ed19c10d6 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -64,6 +64,7 @@ |help|help
(prints details of all commands)| |packages|packages
(prints details of all packages)| |info|info {num} (num < number of available packages)
e.g. info 2 | +|all| all |
Will prompt user to enter 1,2,3 to print out packages sorted by date, price or vacancies. 4 to return.| |add|add {package_name},{ID},{startDate},{endDate},{hotel},{price},{country},{vacancies}
e.g. add Skiing Trip,1,23/2/2022,24/2/2022,hotelName,90.99,Singapore,20
adds a TravelPackage| |delete|delete {num} (num < number of available packages)
e.g. delete 2
delete a TravelPackage| |reserve|reserve {package_id},{contact_name},{contact_number},{number_pax}
e.g reserve 3,John,91234567,3| From 54c85116c2c6bad217aa2adfe8bc2b8e2051c7b1 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Mon, 11 Apr 2022 09:48:02 +0800 Subject: [PATCH 116/131] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8ed19c10d6..1c7980f554 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -64,7 +64,7 @@ |help|help
(prints details of all commands)| |packages|packages
(prints details of all packages)| |info|info {num} (num < number of available packages)
e.g. info 2 | -|all| all |
Will prompt user to enter 1,2,3 to print out packages sorted by date, price or vacancies. 4 to return.| +|all| all
Will prompt user to enter 1,2,3 to print out packages sorted by date, price or vacancies. 4 to return.| |add|add {package_name},{ID},{startDate},{endDate},{hotel},{price},{country},{vacancies}
e.g. add Skiing Trip,1,23/2/2022,24/2/2022,hotelName,90.99,Singapore,20
adds a TravelPackage| |delete|delete {num} (num < number of available packages)
e.g. delete 2
delete a TravelPackage| |reserve|reserve {package_id},{contact_name},{contact_number},{number_pax}
e.g reserve 3,John,91234567,3| From 25ce741cd9ecfc72120d8c49edafcc0adee6f45b Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Mon, 11 Apr 2022 09:56:46 +0800 Subject: [PATCH 117/131] Update UserGuide.md --- docs/UserGuide.md | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index e403d29f4f..a2ace3ec5d 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -26,6 +26,33 @@ View a list of all available packages Usage: `packages` +### Viewing a package: `info` +View a specified Travel Package from the list of Packages based on the package ID. + +Format: `info {package_id}` + +Example of usage: + +`info 2` + +### Show packages sorted by starting date, price or vacancies : `all` +View list of packages sorted by ascending date or price and descending vacancies. + +Format: `all` + +Example of usage: +`all` + +Sort packages by: +1. Date (Earliest to Latest) +2. Number of vacancies left +3. Price +4. Return to main menu. + +`Enter 1-4` + + + ### Adding a package: `add` Adds a new Travel Package to the list of Packages. @@ -35,20 +62,12 @@ Format: `add {package_name},{package_id},{startDate},{endDate},{hotel},{price},{ * The `startDate` and `endDate` must be in the format DD/MM/YYYY. * The `price` can only contain numbers or decimal points. * `package_id` should be unique. -* + Example of usage: `add Skiing Trip,1,23/02/2022,24/02/2022,hotelName,90.99,Singapore,20` -### Viewing a package: `info` -View a specified Travel Package from the list of Packages based on the package ID. - -Format: `info {package_id}` - -Example of usage: - -`info 2` ### Deleting a package: `delete` Delete a Travel Package from the list of Packages based on the package ID. @@ -102,6 +121,7 @@ Example of usage: | help | help | | packages | packages | | info | info {package_number} | +| all | all | | add | add {package_name},{package_id},{startDate},{endDate},{hotel},{price},{country},{max_vacancies} | | delete | delete {package_id} | | reserve | reserve {package_id},{contact_name},{contact_number},{number_pax} | From 9174973214231103ce66f0e3232b43a17500525c Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Mon, 11 Apr 2022 10:01:08 +0800 Subject: [PATCH 118/131] Update data.txt --- data.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data.txt b/data.txt index 30c161b79c..de1993a576 100644 --- a/data.txt +++ b/data.txt @@ -1,4 +1,4 @@ -package1 | 0 | 23/12/2021 | 24/12/2021 | hotelname1 | 90.99 | singapore | 20 | 0$ -package2 | 1 | 05/12/2021 | 06/12/2021 | hotelname2 | 90.0 | korea | 30 | 0$ -package3 | 2 | 05/05/2020 | 06/06/2020 | hotelname3 | 20.0 | india | 40 | 0$ -package4 | 3 | 06/06/2021 | 06/07/2021 | hotelname4 | 19.9 | india | 20 | 0$ +Experience Seoul | 1 | 01/04/2022 | 08/04/2022 | Marriott Seoul | 100.11 | Korea | 20 | 19$ +Conquer Summits | 2 | 05/05/2022 | 11/05/2022 | Hotel Schweizerhof Luzern | 80.0 | Switzerland | 20 | 6$2,Tim,98765432,3%2,Brendan,12345,3% +Back To Our Roots | 3 | 01/04/2022 | 20/04/2022 | Hotel in Malaysia | 50.0 | Malaysia | 100 | 6$3,Tim,98765432,3%3,Brendan,12345,3% +ski | 6 | 29/02/2020 | 19/02/2022 | hotel | 80.0 | country | 30 | 0$ From 69994cc6a80db95194bc8f8e21d1c03261c89ea8 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Mon, 11 Apr 2022 10:19:13 +0800 Subject: [PATCH 119/131] Update chintaiann.md --- docs/team/chintaiann.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/team/chintaiann.md b/docs/team/chintaiann.md index 93aedb2be9..f59f986e50 100644 --- a/docs/team/chintaiann.md +++ b/docs/team/chintaiann.md @@ -2,17 +2,23 @@ ## Overview Our project, Travel Agency Reservation Booking System (TARBS) was developed to allow staff of a Travel Agency to easily record, update and check travel reservations made by customers. - +It also allows staff to check and print out packages offered, allowing them to make a useful recommendations to customers. ### Summary of Contributions +[RepoSense Link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=chintaiann&breakdown=true&sort=groupTitle&sortWithin=title&since=2022-02-18&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) + +#### Enhancements Implemented +* Implemented `TravelPackage` and `Packages` class +* Implemented `Reservations` and `Reservation` class +* Implemented `all` command to print packages sorted according to price, vacancies or date. +* Implemented adding/deletion of reservations via ReservationCommand and RemoveReservationCommand +* Implemented ErrorCommand + +#### Contributions to the UG +* Update UG after changes were made - such as decision to switch from whitespaces to commas for our `add` command +* Edited UG after feedback from PE-D -RepoSense Link -https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=chintaiann&breakdown=true&sort=groupTitle&sortWithin=title&since=2022-02-18&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other -Contributions -1. Started the project off by implementing a simple application using TravelPackage class - which we further improved by including OOP concepts. -2. Implementation of Reservation after v1.0 -3. Further improvement in user experience by tweaking input to be separated by commas -4. UG - Updated the UG after improvements were made in (3). -5. UG - Added comments to clearly explain each command in our /help function +#### Contributions to the DG +* Update DG after changes were made - similar to UG From c87982b89f952b31aae737f2fb534cebf8449b57 Mon Sep 17 00:00:00 2001 From: Tai Ann <66946844+chintaiann@users.noreply.github.com> Date: Mon, 11 Apr 2022 10:29:54 +0800 Subject: [PATCH 120/131] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 026f9d25b2..f71faf717f 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -6,4 +6,4 @@ | ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](docs/team/timothy.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](team/chintaiann.md) | From 4835e4c4cbe2dd261e348396c9af4e8f0a09daa5 Mon Sep 17 00:00:00 2001 From: timchang27 <64303732+timchang27@users.noreply.github.com> Date: Mon, 11 Apr 2022 12:42:57 +0800 Subject: [PATCH 121/131] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index f71faf717f..e5f5d8ee40 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -4,6 +4,6 @@ | --------------------------------------------------- |:---------------:|:-----------------------------------------:| :-------------------------------: | | ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/johndoe.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](docs/team/timothy.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](team/timchang27.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](team/chintaiann.md) | From 7cd5b49fff9768d8a2166154958ad0b849c6b010 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Mon, 11 Apr 2022 12:46:15 +0800 Subject: [PATCH 122/131] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index e5f5d8ee40..2fa5de7f0b 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,7 +3,7 @@ | Display | Name | Github Profile | Portfolio | | --------------------------------------------------- |:---------------:|:-----------------------------------------:| :-------------------------------: | | ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Justyn Phoa | [Github](https://github.com/mafpovbul) | [Portfolio](docs/team/mafpovbul.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](team/timchang27.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](team/chintaiann.md) | From a9613184bb0d0578cef063d5e73d05a8c364d0a2 Mon Sep 17 00:00:00 2001 From: mafpovbul <76990847+mafpovbul@users.noreply.github.com> Date: Mon, 11 Apr 2022 12:47:05 +0800 Subject: [PATCH 123/131] Update AboutUs.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 2fa5de7f0b..7c81e0146c 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,7 +3,7 @@ | Display | Name | Github Profile | Portfolio | | --------------------------------------------------- |:---------------:|:-----------------------------------------:| :-------------------------------: | | ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Justyn Phoa | [Github](https://github.com/mafpovbul) | [Portfolio](docs/team/mafpovbul.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Justyn Phoa | [Github](https://github.com/mafpovbul) | [Portfolio](team/mafpovbul.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](team/timchang27.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](team/chintaiann.md) | From dcb082f8d1e6412d745ebf76c4b57873001b8373 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Mon, 11 Apr 2022 12:59:19 +0800 Subject: [PATCH 124/131] Fixed AddHotelCommand --- src/main/java/seedu/duke/command/AddHotelCommand.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/duke/command/AddHotelCommand.java b/src/main/java/seedu/duke/command/AddHotelCommand.java index 614bd7039f..a775ba99f4 100644 --- a/src/main/java/seedu/duke/command/AddHotelCommand.java +++ b/src/main/java/seedu/duke/command/AddHotelCommand.java @@ -15,6 +15,7 @@ public void execute(Packages packages) { boolean isFoundID = false; for (int i = 0; i < packages.getSize(); i++) { if (packages.getPackage(i).getID() == newHotel.getPackageID()) { + packages.getPackage(i).getHotelsList().addHotel(this.newHotel); isFoundID = true; System.out.println("Hotel has been added!"); break; From 22ab575b5a6b150bc8afef03d83a044ff57438c5 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Mon, 11 Apr 2022 13:09:24 +0800 Subject: [PATCH 125/131] Fixed AddHotelCommand --- src/main/java/seedu/duke/Hotels.java | 7 ++++++- src/main/java/seedu/duke/command/AddHotelCommand.java | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/seedu/duke/Hotels.java b/src/main/java/seedu/duke/Hotels.java index c35189ee37..3979786597 100644 --- a/src/main/java/seedu/duke/Hotels.java +++ b/src/main/java/seedu/duke/Hotels.java @@ -32,7 +32,12 @@ public Hotel getHotelByID(int id) { } public void addHotel(Hotel newHotel) { - hotels.add(newHotel); + if (isContainSameHotel(newHotel)) { + System.out.println("This Hotel already exists! Please try again."); + } else { + hotels.add(newHotel); + System.out.println("HOTEL ADDED"); + } } public void removeHotel(int index) { diff --git a/src/main/java/seedu/duke/command/AddHotelCommand.java b/src/main/java/seedu/duke/command/AddHotelCommand.java index a775ba99f4..72a880a1b6 100644 --- a/src/main/java/seedu/duke/command/AddHotelCommand.java +++ b/src/main/java/seedu/duke/command/AddHotelCommand.java @@ -17,7 +17,6 @@ public void execute(Packages packages) { if (packages.getPackage(i).getID() == newHotel.getPackageID()) { packages.getPackage(i).getHotelsList().addHotel(this.newHotel); isFoundID = true; - System.out.println("Hotel has been added!"); break; } } From faeab7ec6d2adf80c20295cf4181f2fcdadbf8d3 Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Mon, 11 Apr 2022 17:45:43 +0800 Subject: [PATCH 126/131] Add portfolio to AboutUs.md --- docs/AboutUs.md | 14 +++++++------- docs/team/edemirkirkan.md | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 026f9d25b2..d97348d685 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -| Display | Name | Github Profile | Portfolio | -| --------------------------------------------------- |:---------------:|:-----------------------------------------:| :-------------------------------: | -| ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](docs/team/timothy.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) | +| Display | Name | Github Profile | Portfolio | +| --------------------------------------------------- |:---------------:|:-----------------------------------------:|:--------------------------------------:| +| ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/edemirkirkan.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](docs/team/timothy.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](docs/team/chintaiann.md) | diff --git a/docs/team/edemirkirkan.md b/docs/team/edemirkirkan.md index e9052705b5..290cfd817d 100644 --- a/docs/team/edemirkirkan.md +++ b/docs/team/edemirkirkan.md @@ -15,7 +15,7 @@ Our project, Travel Agency Reservation Booking System (TARBS) was developed to a - Implemented the `HelpCommand` class and feature in TARBS - Displays the all user documentation in the command line interface - +- Implement part of the parser and tests - Revised coding and style conventions continuously - Fix most of the PED bugs From fb358a7d37e00541d2731e8295571a529736aba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ege=20Demirk=C4=B1rkan?= Date: Mon, 11 Apr 2022 17:53:06 +0800 Subject: [PATCH 127/131] Update AboutUs.md --- docs/AboutUs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 7c81e0146c..8ed751602c 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,8 +2,8 @@ | Display | Name | Github Profile | Portfolio | | --------------------------------------------------- |:---------------:|:-----------------------------------------:| :-------------------------------: | -| ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/johndoe.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/edemirkirkan.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Justyn Phoa | [Github](https://github.com/mafpovbul) | [Portfolio](team/mafpovbul.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](team/timchang27.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/brendan.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/bbawj.md) | | ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](team/chintaiann.md) | From d0a073b7e9ede45f0f484eb49ec148df771917bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ege=20Demirk=C4=B1rkan?= Date: Mon, 11 Apr 2022 17:54:12 +0800 Subject: [PATCH 128/131] Update AboutUs.md --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8ed751602c..cddf240f41 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,8 +2,8 @@ | Display | Name | Github Profile | Portfolio | | --------------------------------------------------- |:---------------:|:-----------------------------------------:| :-------------------------------: | -| ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](docs/team/edemirkirkan.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Justyn Phoa | [Github](https://github.com/mafpovbul) | [Portfolio](team/mafpovbul.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](team/timchang27.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](docs/team/bbawj.md) | -| ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](team/chintaiann.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Ege Demirkirkan | [Github](https://github.com/edemirkirkan) | [Portfolio](team/edemirkirkan.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Justyn Phoa | [Github](https://github.com/mafpovbul) | [Portfolio](team/mafpovbul.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Timothy Chang | [Github](https://github.com/timchang27) | [Portfolio](team/timchang27.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Brendan Ang | [Github](https://github.com/bbawj) | [Portfolio](team/bbawj.md) | +| ![](https://via.placeholder.com/100.png?text=Photo) | Chin Tai Ann | [Github](https://github.com/chintaiann) | [Portfolio](team/chintaiann.md) | From 231098d5dd9f3f41a1e7e9f08bcfbcea9aa79216 Mon Sep 17 00:00:00 2001 From: timchang27 Date: Mon, 11 Apr 2022 19:14:46 +0800 Subject: [PATCH 129/131] Fixed AddHotelCommand --- src/main/java/seedu/duke/Parser.java | 13 +------------ src/main/java/seedu/duke/command/HelpCommand.java | 6 +++--- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index ee53ec4b98..864513ffdd 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -72,14 +72,7 @@ public static Command parse(String input) { case PrintReservationsCommand.COMMAND_WORD: return prepareReservations(arguments); - - case AddHotelCommand.COMMAND_WORD: - return prepareAddHotel(arguments); - - case PrintHotelsCommand.COMMAND_WORD: - return prepareHotels(arguments); - - + case PrintAllCommand.COMMAND_WORD: return new PrintAllCommand(); @@ -189,7 +182,6 @@ private static Command prepareReservations(String args) { } } - private static Command prepareAddHotel(String args) { final Matcher matcher = HOTEL_ARGS_FORMAT.matcher(args.trim()); if (!matcher.matches()) { @@ -220,9 +212,6 @@ private static Command prepareHotels(String args) { } } - - - public static boolean dateStartEndValid(LocalDate startDate, LocalDate endDate) { return endDate.isAfter(startDate); } diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index 4a6e55e342..a63649a4cf 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -5,9 +5,11 @@ public class HelpCommand extends Command { public static final String COMMAND_WORD = "help"; + public static final String PACKAGES_FORMAT = "SHOW ALL PACKAGES\n" + "View a list of all available packages\n" + "Usage: packages\n"; + public static final String INFO_FORMAT = "SHOW CHOSEN PACKAGE\n" + "Displays the detailed information of a specific travel package from\nthe " + "'packages' page Able to print out specific details of any package\n" + @@ -62,8 +64,6 @@ public void execute(Packages packages) { DELETE_FORMAT + SEPARATOR + RESERVATIONS_FORMAT + SEPARATOR + RESERVE_FORMAT + SEPARATOR + - REMOVE_FORMAT + SEPARATOR + - ADD_HOTEL_FORMAT + SEPARATOR + - HOTELS_FORMAT + SEPARATOR); + REMOVE_FORMAT + SEPARATOR); } } From db95f13d94db030951bd5ab3fa178eff6a435c7a Mon Sep 17 00:00:00 2001 From: timchang27 <64303732+timchang27@users.noreply.github.com> Date: Mon, 11 Apr 2022 21:13:49 +0800 Subject: [PATCH 130/131] Update timchang27.md --- docs/team/timchang27.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/team/timchang27.md b/docs/team/timchang27.md index e3b56cdf85..c03de53f10 100644 --- a/docs/team/timchang27.md +++ b/docs/team/timchang27.md @@ -9,10 +9,8 @@ #### Enhancements Implemented - Implementation of `Reservation` Class in and after v1.0 -- Implemented `Hotel` and `Country` Classes for v2.1 - Implemented `Help` Feature in TARBS - `Help` and `HelpCommand` Class - - Added Improvements in Formatting for Help messages - Improved Readability of Interface - Fixed bugs for PE Dry-Run From 8d029485fa43d5db7e7a73fc8a193560ca482a4e Mon Sep 17 00:00:00 2001 From: edemirkirkan Date: Tue, 19 Apr 2022 20:57:18 +0800 Subject: [PATCH 131/131] Review bug issues --- docs/DeveloperGuide.md | 43 +++++++++------- docs/HelpCommand.png | Bin 0 -> 316081 bytes docs/UserGuide.md | 48 ++++++++++-------- .../java/seedu/duke/command/HelpCommand.java | 8 ++- 4 files changed, 59 insertions(+), 40 deletions(-) create mode 100644 docs/HelpCommand.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1c7980f554..6746aa79b7 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,7 +1,15 @@ # Travel Agency Reservation Booking System (TARBS) # Developer Guide +## Setting Up +First, fork this repo, and clone the fork into your computer. + +You are recommended to use Intellij IDEA to edit the program. + +1. Configure the JDK: Ensure Intellij is configured to use JDK 8 or higher. +2. Import the project as a Gradle project: Choose the option to import the project as a Gradle project when prompted. +3. Verify the setup: Enter some commands to ensure TARBS functions as expected. ## Design & implementation ### Basic Class Diagram @@ -53,25 +61,22 @@ * Packages - Travel Package within the agency's database * Reservations - Reservation of travel package made by one customer through the app -## Instructions for manual testing - -{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} ### Summary of User Commands -| Command | Format Examples | -| ------- | --------------- | -|help|help
(prints details of all commands)| -|packages|packages
(prints details of all packages)| -|info|info {num} (num < number of available packages)
e.g. info 2 | -|all| all
Will prompt user to enter 1,2,3 to print out packages sorted by date, price or vacancies. 4 to return.| -|add|add {package_name},{ID},{startDate},{endDate},{hotel},{price},{country},{vacancies}
e.g. add Skiing Trip,1,23/2/2022,24/2/2022,hotelName,90.99,Singapore,20
adds a TravelPackage| -|delete|delete {num} (num < number of available packages)
e.g. delete 2
delete a TravelPackage| -|reserve|reserve {package_id},{contact_name},{contact_number},{number_pax}
e.g reserve 3,John,91234567,3| -|remove|remove {package_id},{contact_number}
e.g remove 1,8888888
remove an existing reservation| -|reservations|reservations {package_number}
eg. reservations 2
print all reservations for a given travelPackageID| -|addHotel|addHotel {hotel_id},{hotel_name},{country},{price},{package_id}
eg. addHotel 1,Hotel99,Singapore,100,1
Add a Hotel to the Itinerary| -|hotels|hotels {package_number}
eg. hotels 1
View all hotels offering this package| +| Command | Format Examples | +| ------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|help| help
(prints details of all commands) | +|packages| packages
(prints details of all packages) | +|info| info {num} (num <= number of available packages)
e.g. info 2 | +|all| all
Will prompt user to enter 1,2,3 to print out packages sorted by date, price or vacancies. 4 to return. | +|add| add {package_name},{ID},{startDate},{endDate},{hotel},{price},{country},{vacancies}
e.g. add Skiing Trip,1,23/2/2022,24/2/2022,hotelName,90.99,Singapore,20
adds a TravelPackage | +|delete| delete {num} (num <= number of available packages)
e.g. delete 2
delete a TravelPackage | +|reserve| reserve {package_number},{contact_name},{contact_number},{number_pax}
e.g reserve 3,John,91234567,3 | +|remove| remove {package_number},{contact_number}
e.g remove 1,8888888
remove an existing reservation | +|reservations| reservations {package_number}
eg. reservations 2
print all reservations for a given travelPackageID | +|addHotel| addHotel {hotel_id},{hotel_name},{country},{price},{package_number}
eg. addHotel 1,Hotel99,Singapore,100,1
Add a Hotel to the Itinerary | +|hotels| hotels {package_number}
eg. hotels 1
View all hotels offering this package | ### Test Case 1 @@ -81,7 +86,7 @@ Additionally, they can enter `info {package number}` to view more in-depth infor ![image](https://user-images.githubusercontent.com/64303732/161110520-8ed18ddc-b356-43d5-95ed-7df5ca2de91d.png) -Employees can also input new reservations using `reserve {package_id},{contact_name},{contact_number},{number_pax}` +Employees can also input new reservations using `reserve {package_number},{contact_name},{contact_number},{number_pax}` They can then view and verify reservations for that package using `reservation {package_number}` @@ -93,13 +98,13 @@ They can then view and verify reservations for that package using `reservation { ## Feature - Help Command Aim: Displays a list of all available commands that the user can refer to as a guide -![image](https://user-images.githubusercontent.com/64303732/161110894-f9226a6c-e9f2-4cf3-9158-72cc8df19604.png) +![image](HelpCommand.png) ## Feature - Storage #### Initialisation (Loading Data) -The sequence diagram that shows how `Storage` is created and the data is loaded from the saved files when the program is initialised is shown below:
+The sequence diagram that shows how `Storage` is created and the data is loaded from the saved files when the program is initialised is shown below: ![](LoadFileSeqDiag.png) 1. `TARBS` creates a Storage object with the relevant file name (`filePath`). diff --git a/docs/HelpCommand.png b/docs/HelpCommand.png new file mode 100644 index 0000000000000000000000000000000000000000..6e719057e018e4f8d4ddbd08c6d4d7a29f98f24d GIT binary patch literal 316081 zcmeFYby!qg_csnGA&6iADiQ`F;LsgINr`kxiwH;#0z)%^l#&7xBHba~LkuC(-7yRu zL&wkqzk}Y-_j$h0d*9df{`dRmg=^-V*=O&wYwZ=Ewbo~4MHy1!`@}dnIHYp2FH~`G z@N02!2#JUYfRe*G!mBtq*R9PZC6(nQCFzyzAg1P4CO9~y`-c-I(y`6j<*3nDJSzp3(Lh56H4UEE@0Ey|W@DiY=ncyZu)rFcwpdOdKM1hyJS-T zEAp&LPmNkyq;Q}493nbvsBu)L3I&;}&IK+Er2^Q#?BIy~5|3|>+1Y&vzJXI8${0?G zBc{Fr%DN+a$N9!jxawW{pNqut`9FDx<8yun5L!jt8Y4F(5DV#8d|8UyS4D^kmN4L5 z=s&t%92CoT>q@c!-doSaFP#CeZ=QZSJCh^UyH-q779)0j9=EG&i@)^ZSCYWb-bGU~ zBNKxwsg%znQjEwZub$!8;{Ly)I0h(LvFG;X79}}pwhA@u1fwj zSuaTKiOUCOw<(D)RGEFcV(Y9duhjEf)QD%6)OY8#BR*C=F^P9pxxx2H@g7^<*-Wz@?HE=OxEsj54*ALN^58HMlK)^XSSW+%Kg0B==(} zyd<(OIMX!@62wLttY#Ym^|tTKxszYpoq-%TFzE>wkDm|We7BDz$Hf-L zX99Aca_B`4_pW%@^=@(bw?rJVcNMQQOw3DHiEakTG+NR>DB!<+NZU34U1XLiC1LxM zZ9<=Tm52(r(uw5P{^TpW0l608#~vVC>b6yH!dciC8qWEXs++b=$P_wCS{xBKF_11r zWh!$pUDZW&qmz=PiHzgJv<0IDu@Yn$3(o^?VgJ{6%FpY;9k00p(A~6g$Ni$GHR!!r zkzE;itD6;cLO}@)J;njW(hUuvMhdT49A9_`IF3eoBY9RpM)Zk#ZI4d^5RHs^+38&w zJsF*grFI2k?B!w~w#Oo$45p`A8R7ciqi*04$aLA$HrhfzK=H+P3RKQL>O$z81L#lk zQ4V{agbiD-Jv}c{An;GdIO~{?trs(V2{gBHtf4qPGz;w+elKYXs>o*$zE6eC{TuGQ z#uJJSW7)o1PfzaaMMO>#A$C6&CylDfgB4$`;W|6j9Us-A2S4yE8>NfzhrIOP(7nGJ z(0I+3K<{cyBh;2^Gf{E-*1nfhGMPB}EeXk$PY>VvzkVG0iKXeqSvdIor#x( zrIESF;s>pzfA2B#h&R-j?!zO+)_YaAry6ISIeVHJ=S#O4j&y1XAPq{hS~~&GWam+0 zkMG`oa1DI*hSBwh-`V|?UuDx_L{#H&;6*nig%)czsA=trhNbV##v%oZSDVH)gy5Oni_bknn z3dxP^35s$v3y*i85}xsZ2l7jiS>Z9^l@Z_DW7-lHz=6Ci(Q`6#sSC*MY zo@Mm3`E~QvW=gU=I!BW+H=kJoZvs4@TRupFQBv?d&g+ub?Mb!n^4_23YYKS~JQtFA z*P30>dPqdiscOr1dOKqF)E~tm9YPa)J2;CP!ePU+$-}{OjVnC%2Zw<9fORh9{`)v% z9UIr7vd&j9TO2i_^`Xw5ohsIl39TiFZi4St-0i+fPd(q9a`I?CSDTWKE=|_D3ye?T8EV z9h!4KRz7yQ_S&@gbZH%#o9F({KGXL2@?KV9B&1;L25LFYT82a#LW3RaZ3f>h}4`1FNeh?xp^P(`gp30c!aj1DPesTO*RPo`w)%?>|nn1>1tu0zDq6&AT*dNbY zJreowb}sa%lbpC*XT;{yNruiyT~%(iUl~K0wMwLlAo-2ETy|Yu98`nB124=KR@3*t z?pv?c8B6{uxIZb-W30DRMLlobszl=n``GVWdrju4h2nzZRFZg`Z1-6B&Nu4L{G|g^ zJI+y)gYB`};o6upF_-{CeunYcZQ;({PUcS6#EqCb&Kmi<^gqZQgT_+JQ%4161*q+( zmwzqU^ltRZcTXl1Mkj@PD*t%gLy;8sPS6~k?)W(^{q+FHxY=%QyU2j-D(}5V)NGc_ zeSUP9d^@3IrQHC(b3Y9~y3F)f-eQY%f8(?-{il27dotTVcqLk!t#hhVS9Ly`1X{-=S=Ha@V6mv z&3C%}>Ph%mo2WihmV+F1YfX1XZ^7FARAUAL2YTh5Pk}LRSZ_cX@Kepz(y@+6HC zj~Wyb=T6l1I3wqvTcdlUhU4T_DX_HmUjrdYyq|fI6Avn?QzkOuZ%IDL&qinIs#PRn z{f^}~c+;#iChM)JAY0jT*#a7C8oD*j&aEYaWr_x)<@QrOoi!hwc!q_BA=CMY8V9nm z$EdxxkYCf(r;iTH*UdHyFNRM>p@b`hFYkZxHzySdY5EnKS(bU=bCXav&f`1T13PdT zw&-{^_pz%?G)=|>ecQ5&*ZsxQ^AYn%#u6oAn{Q)whYPWhqlzs_7D6;GCsW`0xEOm& zdT51~oi?{!lJ*GM*x9%Z_G`!b(EYA6d|{{?WiAywdb{u;hw)Q8`_q+!G%dV>_^SKv zm@b~4@}N=Uf=ZNZ{fD)ss_!(FN0o`Fo*L|l;%q{Fjs51$&8VqSxZzI2kvL}S0I{{X zz0SYOeq^+k_EW}*ZjTn>{>W{&+P+b3VldFmwAUi31}r*7F#$bp8KX*IV_-Xl2VL}? z8zWh2v=Ha_j?653V-tHu2S%}w=vp548Z6r(LdSL9m9DnabM&x&!DlugF03oeOf&=L zI>NWewQ9deb;{Ol_!u$0*1NS8W1BJMt%Q611~&_d7vCgqat5wgfCsh7j}oc}&UA}3*1&4Xm(hfRq_x0mHjVNZ|vQrDFboja{U z$}eVaz-li@>VAG%oMFUj0`^C=$!j@N1qB>t;GPHvANLl{72pmR_{YJ$kAwgF9tY z{Og{O2zZ7gt|lob2VB*R?MzH;?B7EioMbn}fP!nbvfB1IIFt;RA6z-rC)+qUct~^g z*AA~0UI`jQtXYlTLEf6MI$PTUwQ+ESodtngYZC_}dS`1Z8+$=#kw?F42m<$)#cYr0 ze^+s^6nXSoL783>VrN3n%gWBm{s>G=Pfssw_s&#M^@a3b&4FJckKQ{t*b1_-IXOA8 zI&rZ=?9A9W1Ox=w*g4raIYB@TkiCnIgOM}H#{Ti2m;CEJFHG!>?aXZ*%po@Pm+v)t z3xPU_JbHB5(f|DY8K;S}`M-OzvHxpYzy#SYpRjSTva|hNGY50ie`t33V>f3LXk@1FkG!+($SPeWyMXA`T}FU*0K_Q0ILoc#Rke>MB> zM}ON?``=AD_}Twg)Bkw%A5AYOA*gC%53zz?E~18wxdWI}nCVejaC5V9 z{MGC~%m2HL_CK`w&+`9nqhx0etfSH8@WB7-<3G#(sxQoTNdW&r5PzuccPT(_U}9mm z{~=v4anLVZa~vEo9Jv?b>dv_9NW$77^^=PopSR+TtbzE&ZwOoJ4>YLUoIsYkZd+J0 zry%`embZ;16&hA6I$ACD=!xRw)YMP->z_hIQKgAzN$pR#+7lM0tEYNh>NXQz+1c6c zDt`OM$jF%Bday3gA5JcYgM0OFzuqt7sg>=WsCoST+oIi zJ?(4%R0S7rdi@F!y%!GN-+e{;;oxqyzvU{q^>jn3Gn{N7SneO ze^p7=zM2{PmY8p&Y>-zTnoWpDv_L*{)a@;$`L6*c%i$9_^R4=)=={}X-}zNXBvk8g ze^9ArwmG2YyA8a(TX?T)1HzEafk&h6HDBptUdaJBa76&ezzQuG5cU z)mPQBJUiOi+^9q;CiGk`7QKSko_yT(`J3absi zPQYVRiB%3a-)*aoPbUF&aelaobV7wp^9dFWsmcpbuWPypp34s74Zh+ES?f=e!T6$n zy+=@UnFfDnHM9b}s$^4b!NU5(X*aMfhx7KE zL!h&vF4X#MAt+j1rRC@}@H5DHZ^E)rz(Yy3h%x;+RlCG==svvphEUaQMgEi}W|ozF zl1fM&Cb|Zln>RHdCThSXdRr)3tRHp358K-kb=7R#tl8Q;n0AAV=Id7e#M^h^i-EkDQRm-Yy5o}X?xoo?1Za!?QREIVRN?>w77rE7)MgYtU=gf^?1J;6h9YEE_Q zh>LSDN}P~pp&olMsWU#=QpS0JI4GK{=v1cdnxd_^3w;5ce8CE_Os`5f9Y8>kRF*?x zTE1J`n(_&pgQ)X^%G^0E9dib}X$|HLPv1J|)Q!pu9{clH`L)m&`ZveEMsL+@)t8Rn zWfe=VOE4TU^u*?t8vy%7W2fa0mXqFHeD(H}oz?6Vi1p-;ujn`prsTilS$_ zJ6=T|LwW6JGk87;3iryYxiu8`b*LDB-3cr-l}+3Vacopm6v$v6!=CN+o(gd~WCg+4 z3Tk&dSf}LDf;27COMnrZ8Ola3m7T`Z*bJa4H9^*+Uj|@qzN@v5ezVEG5xgjs();Bq zUtGscVlV=fdbZ**hm`u0O_S%@1;w&YANHl-D~e#$vk>X&to}p8Uk0MI3|1Av#|!CJ z!D};kT;1G}gDv&Ws^n+D=?@KC@*t#C9%UeY`YW=BONQ1ZolM8q+#*M&LFoOqj&H;1 z7Gi7Y?ZDG=9Iehx8mFm#r!9()F9kjGi<*cx$IX(;$L~qwcx&G2E3O7kkhJ^|vH?y` zv32m0?AnNr+i+p!0B7g(`TccY&x=#kxyZ#tj2Efh!{Xk%Oo2)~At zKT{I}T^shS)d{C{T}hz`ve-YSr10Azz`bfmvcEc*^)~SenQ#&FSpM}w#5sHtI;zh? zt5f~!zNLCs=l6rhZ+xaI%AHQNuUG_LN};~+t9IqvH`wL8BfdlG1<<0}WKRVEc_HEG z$@2XKd!wD8x4CLNm+}f63Esaah}|DNC8QMD`FXpZ?bT_TP}g8wA@Q9Yig?-mv&myyFLgt)a^YVtFlMW3-+M$6}fLlWOkPeZj+s$NZT1sSzB!>4F3$sii z)r-+K!x~x`B*n_Z6f%+hFIyx!P|dt&BHjjM`D#h2%m@REiVc9H=^lX>BIfS>FCd&@Uaht31XUi*mU(tph-M9!X75x8MOqeA|H`jBn1Iz}yC;~j!Bf)xc{SlfFY~RYY6RFfpY5%E;oSj7hNX5rB5uIJmtR9rW4yS{8=1Z6<|X z^uto@(+DA zp60SyY={E#&$R5Pz;b-)=8oR}aoNglYLwjFKIF~Q^-`t%=lGZnq4#~sx$(q5(WQK# zoWcp*D+K8Z1$PaX&h>un=&Bq?pr%}w6Y4W6bsSmDJ8aTu6*c~ksHckY zD_7L#Tf@SZM!o9S*8%wfPBx|cq!MmEK#iSIr-LKTPb}S4yAO$(Cvgf%8%E=IDnAp) zt?=4l{U$9Um)rn4m@;tNSOfziBE7wz9~%n>h&-WQEQ7%#Tp4HUXg*BIT`W>ZWCK_X zn4^fS5^M*~bT^&85|3>soiJ<__nlnM`bKzJ*Yo+!xwUC6)~V~maynByO4BomW2orW(w087CBi-(};91dWkHws@?fTK_**v z587p!bSX90SKhxqodW22(RF`iwsmzb9B<29j*LsqFub&jGpIM!<8i*>XvyI+uxaLN zV{OjXx66A-mrbA~$zD)?vmv3UO(iCbTKEJK+q|zx3Uxx^veldLwWjPq61Dy|6hYtw z?F5Roc3Z+QcSL4cNJK1eG`-=a>HvO>ai~D1%|(Y){FX^ZuTS5tlW-Z@&+C!sr?>I1 zF2x$(5Y?`9yEyLkRP4|hy0{wTlvhD+u~ z^>X6om~j}U^a<4b7Ta3Ye5k$KdT{_m0i%JC}+l>o^m+TcP4S4Dm8Rc(e{2g38w!AN~8+)smpXvjJ4HxV48u9v^Zk)-|h%;Z}f>vpFEorm!B}z^ZE~ z7>UlL|C;zI@#~$RC6nz-<_8-_YZEKB_a@W&1*3R8^XcYJ8dJ_2hC7}psfuZcuPg8& zxp~I&cO9&f90ufINs7#dP&IndbQE^eNrhb~xU>*XMD-DQzi^%v1Wm^Z+|3T_B45|E zm2C_rq;;l$b+EkZ%#!y$^`7#VRe*6Sk~*^Fow!suVPeN`6LyZ#PIzL*$zh)uK(8Ck z@H3X;EDL~>Q}w9lQ1tvL4H5bDPA<*|B3QtO1C8D`qDGsL!gA5cV;#%at-7+VpUP=X z6MhqhzJY4O20y-x1EUwIM9ifzqZW9T?pmJtcM9|4npVB3H@ zYdx1o`!cWQ;l7y6kGlg z)jxd1R)6#eE?5Yw1vEqxQMalV?yngQd3f~1MbE}rm91uk7YskNP_TS_bHb6Yn{~05 zbaA9Btr3mK`micPGY}9EnQB4RBeJevA~x=e(QOm|$R394TxV`5)J=j0)}~ z-x`oQ-$ojILsJe{m3pDSg$ZiN>AL?OLAR>t{bBysaqR($chYLUtk?Gryi0}UCDbq3 zSjOcJx$;19iie7*?VQ{^^f?m~0**Xt6+OS%yM(e7C6mLvbi+~Q+UiX?H>pLB?0gw| zBr_>d`GDmpKRGeNJrZtCw6}V;z5JTRI3cDyVW=gf#|8c@%l=LDOmzpy((QRk+oO~T zaNm#3_+OzkYx~;eDA?(7fy-BM(JnHfb@mIY?l%O1!YG#aG(AcudU{SsC|3WD>4*Mg zWKwyE0~q3;F2r=cpCu}#-g>O=EIq3j+?g2{=GY@I-@#LNrpq8#8HhB1NwL2RasjI!HZRi zFLC7AscL=*+Bv6>hG|D=fZ6BdzEclgeLA6EGI`GfbM=C)0=x*y^E*4pGU$l zEAe#`Z*VKgzE`Bu)G62;&W5~dvB;Ts(%BM2Kij3}v z*LTt(^J&0j8zGczhFf?JwZs=0u09HeXSnRNP)SCwU;wb-;M6!f2%aKG>}+|VvCW=d zvk7M@o}^PC>m0V_N;Fh2OpRoXUd5A^MT_dlEt4e}Hu2_BZEFUBkmk1{Sm8N55u}c} zdC&CuRo*<7XSR3CHbBehIraIb_g+If=HWP3y}yr;rQSuCx9!z|867&^S0v<5OW~w} zjQH1^c>B4B5t<|;M`u#CqhMpv?+&{4tX;VfWw+6QkGIfq&zLAYz#w>Sx?sSE6b6eb zoa`NoRgc|v#(?La3uoQFB)nE9PwvN72hWcdm|5Of3+1n|9ysY_JvmDyAbPmEr-~YF z(hqb^&OCQm4hAnfG`^q`-5>wz7$6;vVL92W4em8`GqBu06$gysGW{T7SSQ$!#}!O; z`az}eL?Ii+>`0wg9CE&p+pCAYq0Sd$j?lN#?>MS`zIy~RzF^sPCx0FU2&j&-!h^kT z0)#cK|8Hs{e^2S%r5~5wbYgc~mFVqSfa{S&3fmQnZ<+6|5L*~gMSvvd?|d!CvL||; zAAbg2*-z$BAdy36uZ%R7M8ax)=_{f$=*vhQ0~T4fbHPIrs&AwWVe@kNq!LBigF}Rg zz>_mb?T++NW$v$4T%$&Th2lbs>U$rRPu`mQe2$~E@z4<2;8jKi^75P>6hT36tA1># zyg*K*UPl%uQ;uuhLaK;(mkBDZ@BH-<%6{_Sq9m2+fK6^?5)y zfH=DA*rudy^ft=of0fKr!_xPY^?s4q*4=_CUZc9%>~Lyv+Ns6<0z}>H@^oR)QNu}H zo0dTP;6T}HfS^W_W_V!I(Jv!F+h6F01Z^FqN4?fJN7Spekr$H>r$TNg$!zJe`a%Ht`&?eBdg?a`|Q(En)2SJciWBq#!U%*B)8^ z+?vWGYyg~N_R2RsXi| z21oW*Tg~$~4I|K5bca5KWCxyd`5D|{^>-%iB-wd$glU!^CR4(BJ};Mo0*9Iu$rN6_ zq_OtAK~O>Rl;(oi-FF`_4r{i3q^M9Qhg)<{HEKJ+dSgRZ6T+I@Def`WsRXsAM|bYH zn?S;Jmd$D)7Dy{EfuYisy}FKa(V1Z#gM9RSJ6KsupUAH!ZSHvDq>lByzT>z_KT>k% z>6I6%EBC(Ro2|i%}F$P<%A#!EbiECsN-RYg3krASnz5x|K88a_su0egi=`ASGuTe ztlr>Y{q4-|PUk-Wt&Z-@1u8GmsGavU&Bw6{2B#H!UC{@_cCSH|6nYw#f(#zAzkC{Y za3poM8FE~Sak7vjabFP(^G&W62IUbIhKX~F=B}!165o3d%nEF1Ef`!@9gqB|493hz zLgn_dTOt)IC{**!9cfAVP7gkfR`ws7Scgfk4O8x|@ycSfCS?c6s4<>-#%kCXYf8&_ zbv*zQ{4H>Vh79d!yiq=Sa7=N%_WWcm&1D|>ZH!JvD8REP z_Rqm2MI4wxuiTDcJ(@Tlf%fxFh2P#S8_7#dxEY}{nu|f4n2sh;8W}1#7+_E)G5Wc9 zZc<4~L9A>)zIzN`d1;;evX@2RY`fVyn)jZK!=*I=qJCR3Zkkt3q+d1YQx(~x6;~X* z*I8uLe1<<+bg|~bjIIY%8?CgSj1$^8hHW)z>_CIgiHpI)GNjf<%3btR%=oLVPT@3Ttipvg=CCXFL>INM!1!)tcu1vPpPrVZPbTW|IUm3+z%J z4`@wr+&+O6W|olT{zt_u%M>f{sw8#xjrL4YlJZzt4MNl(`KFtnNZi(0dUn?+i^cHh z=FO#k(4My1d+kIXPx;+(R#AsZi`sLS&LNQ1!;t$t%-1vPnU#o~8OxbpCKUVKj`MIU zvn^LOvpm=c*V(!Cbmi^Wx-|OUNBc#c0Q5S2SbRV9P!Vs4-Xhk?LAD<+vt5blaJNH8t2u&+}V6(6@zDVKH@xFTsQ+!9XL;= zw_VB7rz*emV6>FMiut#SR#9LyMo`0}xEv>XHcNI1jFM?jER_G2rj-ixT@o1gPh|lb z%)0lMsXPKSDoI@(y-!v&2V5kmU`@#Tf==j^cKB&Z`Pwqe*X_da-n~??r(}8HIgGr+ zx?+^`H(S+dewp+TeS^*6bCy3DJh^^YQ&$RMtWJjSiun=3)x-a|SVszGK)bDMahjAY@2|zKHZqsr^1#e8nIl$GjWx5dCFp z27DVUDw+zR+vV})WK|e0hi%W1mv<~a=Mip=BWxR02ZtZ&;nushPxC~4t(@LZcZqY+ z3tv7>kqnTgikw5njcvXfQXMjQZ9_??zb=B#PK$>(Uz4LsU-ye-2iH>m=6K4z>00{E zmAyo=9fQ-qhK0au3T$p3!zF6o?5A0qvsS7zKR^+zxw%pnI-}Yr;M#H1@5h8kG=Tra zTBRk|q+)+h51-=rSohbVPi~ZT)6IOBdW)vvLyZBB{2(#cPkFRf)`Lms`;4a*Z>v^% zI}e=CG`+aTsdb$B#tBjcf0H^7J^(Um$`R}I@{H=$D5Uo+Y*lBDVv7qs(TqL6B-7pq&M@HcQtKvh#44+A8MvfV7_lPp_2UFO z)2Mt{a}V`lIJ+6FE7j^tJCsF0zf+K21~wT{TAUmL)CP7>l_Z3ThbR%oYUz@`yKAQb zcC?&}hqAz-s2^ONN^&s!wgi|aC7 zyr*y>nE8CM%7IJU#t_4HwU*}x0BTL2^uIriDEIJUNs91j`)os~o`ezw`02${-bPOm zvFA^QdmZ!1e=WO^B01mF;*+2mzGsEgv16idX99aegn5oGAFq^AS^Jg|zm3l;KmA39 zs(e3A~ zX$`s9OdF;l?B@tPez<}mSu!yb*f8IW=zSvjSK>X!I^NTRXD99u(mP!@a3R%egov&t zDPtN>r>PGC2^p*Y^QXRW)8d?!J@fv>ak&31;LvJFfR1RN&-v)&2h@x>%*uiS*Yt^q z7r7@b-E}EGoK+kMGSjDvX|J4!=?AU@P)+}-vxm<7S*p#FP1P*HMb_fl-I3*KN?og) z8Z!EYPw;DX(_ksLK*z#ld+72{y(mru-58v=)7CP+FwR6D%9jK$Cea7oc)(w@#KopawDYe9O%3brl3I}(9uyxilymH|rZIOVySkR8CXrn%f87;vWvu&j0 z!;dm3{aqq@9vgY8ciP~SSUWwn;Gl+!$g%Ks6|QzW!{qXu zH7tjZl4#EU4=L3p6n^tR-CtExNpM1WRL*(yFAt`6=4G!#AWd92cl1Q|`y{c*XAel!ayQwfO46tTudu(lQGGibMBkdv`d@8>e)8;WdhZ6IRHbBFW32kJhcpRK(fIzxN90uDn*_?m<#;OsU>redg>o|K;y z41dZh2ea)xK%{KS6@tbuCI$i9KH*-#Z{NL`8+jYewjwbcaEd)Tc~}^wiGUwyf=TflyzZ?$;DOrjRwZ%;o3FT)+$NJWmZc*$Hl?tj*52j{E0K5n z!u%@p^B$g-@pZB}l!ddKvQeUJ`ZoSV zglhjXmHrct)r=VTP7M(Uk?E|ed>`6SD%A;G=P_RioV}JHSD*^_o!!v zpSyGn9ve2!eQ|g-f-X^X!kd`aq>|sDF-eKv*7>DL;`&P<~Z&q`$C z5)3n}r6qD*9@JR?M>Bg)))l0$HOB6k_;LoiYhcxrz6=o}yZKOh{jR!|5rJsSmC1^%8NZud0jj2+JzA zemuEW7&9?>t_Sh3P}rKRgh*KqrR$*l-FT0Z4r?ORq5rtpCE z<4fY#LZ7cFQMo(JDmC-wK=T0QgK1+nT56Q-dEt*yX;IJ4b6DTXAtDtyG3TzaFSx+e z3rozw4GUF6`eligDx7Qr!6u^``%V{KT)kt@KQ~vLMY|hNdYt`Y8DBXco$evjx$vXZ zY18+_VqijR-v}lOv`_NFCU^d2?%rw}y=YF?SolzgrJL%vj6h&&=0JMgKtY;=H|Dv9^$*wR+5j+~Tm7dPVj}F@fyxNC`#F!S_ zt-8Yl5S;^uc%wV!n)#I(xR)(}4lz<_byPj7lwqRa_UkY_4LqUO9MH!Z)w2&lDPh=o ztc^EF;3AyDU%I+B*{Xm;U4*fAcrE@hh!y^90%4V>hl!~JVoNlh&$Un){7RuhIu#Un?T=4H%Pq^DUNLBe2;1I7XZ3=iF}IbZJnJd+4QlJnx55AirRM`* za7Q^}%{dTd66FXk!mi{MP6ELNH5Mx7D85`yUiQ@B`ATnenX{$`+0gRIWr#$lvX{x} zM&%*Z%$y&k2dsKE^LuL03VbGQWC_hGog|;+aqvy;G3lwk*0O;cqs+HUxJ(#;K>kfy zVW8fg5aZQW#wvfO?*7L@8s^uDnyZWH1hQ>a3TwN)YMc2-42p|ys<*BKMDRt}|X z!cy0w)e~vs(>$6E$g;7muy)PPv$CP}$;bKApnHWQqZJHsAW5=!A%`kSLxDX#T(C1| z&qis(3CTX)LL>eK4O^Mk9w2PsfwT#1xOQjqsdZOsaen1woerH;{_T5?7-0e{;(nhG73$GPx9ln64m=(k#7IvA=sT}!lJrvDZU+mJ)@^;Z4D|J2%3g`?>Zl*z_dqaW zCDpqE3xvSjDPPyT5|A#`?%=KOw0>E=;w441)JWk^)u}DGULuK94hhSHDr|1JNjz zg=6}moUYOI4b!cKXZGV?L;eU8`K!!Zon5a#ZoGWAztXR$R2Q1%oCgt75-yz1gV;|X<>};n+EB?mOU)YJFb!A($u#2P^Ot5G!J@d6HXZvwNaC3lej+*1b7+d? zOoKPL!3}+iHk3IRl$D`&#G%ir0SJ5ok13E3*%X3Tb8Fxt30&NNT7q3 z{mX8;6}46a%b(#57D4Z@5z&S7+GLb&KtNrBPKR|JX5<`CwsvdtsP+=7dET3Nr5q-g zM5RNQ;IvN_@o{8_@~TvV zp?Wm9mEii_nXTPHd> z@Hittr1oeX#Aa7+lq8Z#&;+>-Z;3+p(t;%5%CXVvp88@#G+q|f2|PR}F515UJ~7>P zPSwFQ=dNsN*e=+;L;?*$Sh%g+DEzWtKYi%^B}VHHN;e^qJeaOobbIn`BPKd$#Mh!Y zkMb@t(F(C$K4JV2OX13@t5=N9k6fwvk795PmlA#dh)iWf9@JN7ZKW~DH8#lOZeaJM zW;39L{Rpb~{2Y@z;(U^tPsgjR<~ByFJ(^Lzmm^gbN{SzT=UGrC!8MSq^_$xAwd}?6 zENnH%-2$Z62!)O(?-kpul9?YOot!K-($h&C(I-rnfZhlYwSg1;cyg=_t|$;YQmR^B z8T@+a8t`*P77y)eoDrqDoA(2@ElEZ8;R?2mn)BT!UDwqN>=TUB z)Bs`Bug=7&={(CHm$(qD+~J`jXnJ7NB5rCV0b{O@8;Tmin3@yOEC0YrifM6Gz5gdl zltv+0%EQ@-`^gB^Wj~+rTs6g=pMHdsDd%CGJqInyvtX8zMY@V;oloja$pO@PqWk3Q zBSSzeUf3HahTB`jcV>=2t2Z+AST2*@rT%| zPV!0h`?H^jypzMV#!O~U#%Sq7HL}hfBnLnRu16+ZP;m+Y`bmA&j>z_Gso@a|9#L5}FbnJYYuUd!4h~*qRKr&Qn3|W19KK)7`CBge z5oMD(Vj6P-FgYmc4D+mn5kTYV1OZl_4d6yQ#4ZN-g;4YLTn0?k8&0wpq#-T?7HuZ2 zEA!v-1JNZ3aM;6#%F#d&s&>iOARIgsqHPy#e`b@v;H?k%nJZO!J#mjOqZ)>8E2E|? zJ_|dnC|`Iz63GT74#nw`8LE2@vDNLXy4wYK76z2%nw-UQ7*C~zfzg0W<{(*nuUjBO}F1Pe1 z{Y-*PQ0+esQ-MXSp~jq#ltS`rP+dLVNyBZT!G}4ShP_96Wez$p3>&=rGg$4pm12AG^E&MY}U$N zYqiX04@H#X}5ktCveTPH>EZPy8VCM|Np%B z8ZYh*XHfDz9mQTtlL>RYjE|O-znBYROFd>{OKlVOqB}KQN-$BC2B;dKYX{s=ve2;o zx-?hfOS;DxgoFKo6T#rIm7UlG(7S4#R(hBba1!KDLb+L&XGDFAV%7Na^b8z^qL~~$ za}p;Gj0JN9Tqd=A?*F$`{Wn+dixn$iRk*Kv$NsnC^0yV069I<5YsGZ$A0;dWAYm&X z@dio!lU#bH1PB$Eim$={Bz5`%0V%F~^SjhPO2@B^fbbL6eJTA3)Hd{HvuU3!=>3esrBjq+yb$H+bct*X1$+XMqPo_r9JVGvSaY+ zIu~GppfVH+?q2||T&<9xus+T|`d>Fw(b(IdYESH%p~|A>Ya@I<)2`UxnO^_i%|CZy zmP89Svvogj$yWh^*;zJ7=`h+2e=@pF0@C{niOzGM;m7S>Vx>e5ThmA_lP2G5n|X!x z7SR?eWLM*K#6UIHfr!e%yMMFJ9k&3~KJjg!6%uy1(%-xa$uA$VlMJ{41>#+kPmh?Y+%1VNvqk(YH5-Pdlzh7wOF93w( z=9;QCaGc*hBIBp%808OKR$zRJaDUFpUx z1>W(Wmstgy?TksmyPW^M#Q!E^F%`V=6UO%9vddhBIv|>3v#9xoeE=QIxh0I)xWM8fV z9!3!$NQB)400f-Uq(gSe1|INQ#a`wC+JP#y3Jq+0NO^5t6M#KOhKZi9bgHo&K9uxd zfVHK(x->8hr!Nx`P6a&oy7{nIMCm;CRStpJ&ZS(#{GqG}U-x0(9X6-N>i`>1F%%u<))mW#Mn)*HqE*+9sx0ALv5 zLI7Hh#m`PZ?z}r%;{+K+czRX>X?drj*3`$HYry_H0rPP#XvrnRkQ3?KHsX7X$^v;H z^{D#)$%yIHwJslyKe(0wq~VN(erWizVbNP-)T%{5Bo?_A%7W1uvyv*-UK4R zZ$OX$!w2&4HfvTqCcHlC@y@*Si7?+A+er|F+SRO=1d$y9Jf%f3_bx5>`!8yAbC+os zEk{Sx_#H|>idN;$FY1~yLZ?tV(dh&r9dk1`uOP730At|YaOs#89V)e$gFL>>xOBR7 znE*I=8)3}AuDN^vny#fb=$ocGcENMjkLrYZ<*naG)TNVGEt!o8NJr7yj5QA3AyZU{ zg8@+di3g{-PW}g-3izI!yj1>HLCq#wQF!O)&z5+=_Y3}#M%{$d^ za`O)1Mi3u1$mqL;WB~D5TgG@R^F9p6G%as3kCM_(qh#xxpbdQ^$2aP zx2`o-2?9AUnOGU|&BvkqsTMGrPAWt958U-YCeBC3|Bt%2j>>Xfzl9Y+NisDeNv7POPF1tYDam`|m^PDsoFYMr&&-9l zV6zG>2c1p|*S)j_(`sBMW|07ivQlppP5vpK<>8Q^K8rfW0ZOi1p8|Da?u3)F8A+5v zY>q;XYBLHH<0DgH8tVC%@S5n}RRXx41lsx6p;n!uH<9tREL}Uiw`sx&%w*k94DHec zqM9DEl1_#+N$k+Yc zX3$Z`w@(4*g{C4W}na5|XjqD6pGbeAEbvmv- zFK$wL;XxWd!~c^h2$`7skJWpnBNyw*Vy95ST+;PKTw>a8lU4FHj({M+3>3#%!J)4@=Rh@ zk=1K-0-1?5qnX91xpHpY^?pUHgMyZTPj=H6ZJ<;xg%mm9kO^->@?_z;Mr1y61inMy zARy)FvuK97!i-%eP`68y_F#FGC12pS&WHrD?Fh`J&2$%fesBw&lT~+FP4vO#wcmIr z!q}0t^x)wW{I||9#(Y(*$0%?_E#!GjrpD&E0X z)`rVfQ)?yWlks-Vmyog61J-j*ip@r9@1!bw>eOvKeo6YjWbOd5lt=-ysOU&eKR!vB zep2~m5#I~rEccjT=StS0lEhUn}J&_5?4$BXO+=+9dBo9jm>{UZz`$ z57?|m)*xoR9bix=&A}I~<*_P{U6KkW5$YU;G08ExEET_}5Q9yDhD0-IeR14mzoj_o zt)!u94a&XVr+Zxx?B-Q5J^UmlLC1mGMaE-?F^nM`KzUhbxCR|f(QNlhpYZx zC(W=v3Q{jdXw>RbQfoM_3e&aO{D?nn?s0m%tE||0%G`=vM5d26;t<`Zv3I3(lblkK zD@kzPWM>w`3nODrUC`;!)6~b3^#=WznzkKaxCK>L+3g)u#G+oFNfj@w;D>R>=*{MU zZqH)o=lYJQ#HF0>(L*Q|q*&+Q5b`Ole&YP+hY(P3?F6Np%_%(h*-&%<$uUy`u1s~})^b1~As`S7=XdjL;6iC0{LiK-`$9i&Pj>}qNe?uiO%qU0y} z4mM<|w`Ic^cg66(h2>VonF?2gs`2v%%RDHtl@T)=lJ}!3Ay*k|SSQ=5T0r~t$up%` zc|K6ZDz{>##mtrG#ELV?;qF!>C+fzwevB8-P(t~%Z0{;&B>N&vg=OOWB|(3?tb4se zQB2F>D!ngZHlT=>mQnO{rYs@`D*6%`_H!?iucn$U!qf)xj*Oisc=;^HnQvh2^iWrU zh}~dr?Z)yc>n{~$N^#{UVbWUFg+M-MNSzID$Mz4{U>*+Jye>Us++27OCnUots!cj0H*+@YM>r3h5VXKjLu^Qt|X3ea2cO70MrZMtAOG zsL1=v7bRrEPTHsF{rYq@;U*bw8 zo4VRl)|ePN#6ka@N`^;(-*J28Ha)tqaSa%@{wIBdRLbxDfoi8?Sb}W%%0TVsFSiGo zI>H_|&ZKx0FX43vHwcrfbr<(4raKV*6J-QvhPUNxr66p+!=!kCPBRYJ>&k{qv(gWH8H!?3j9@b}G;-j~iC;gM+SW=Jz4y$W5(Bb&e!QWq8PEmD)^v=sKt!Y2G?`iXs_CWeXa zoFudA18X|2)k4(flc?{$-8;<9_uE_QuKe>MrD!@{)|97x?Z>fdjl(`Q7xywV@Zq`p zx5NnFv_y0daxu-0zXo|%h0F8j32Is?g?r~8T^>h9(?=f_ho;7s?h^FId?-uXhH0-w z=JJI*M^_&5-x=3Xo{!8)A@gI%cQ(W_ED!WjT!H_IuRp_qQ}{eZc7@90A+omB+00dx z^-i3Y+Jjz^4`uGS2Hh#rFK(md?H(4xRIq4bTfa83H&3;@JR>|3x!0Upj<3dZJoFgp zKMM78`VvU@U`UyIB1;0#H--9{6~#+rvKjl^!0e)l5@AR=l&*}sWTuvsZ_iwuP&JRS zn-0&?sCJgGZ-r4!)BIKr3s6d>E~hIw{rqq)2g7h=SUmODm_z88T_!$NtF~-9vrd$T zAyf9}F5~p=#5;2mPa{0d{}5+>V4TIS;2hLX_*!M_lcnFgR`+El*ah4}kWt8Hu5`kV zhP(6Q_J&@RDqIXTNzc&;)le?mA-F`c(HEnVn~Xk1#iF>}BmCNJaJ}WO|MK25!Ua{R z5gcvkuU79~=l>ZXIE;vN_tpp|zZm_Pr)XjVUE;iAxBc5!Di%(Wal)BrUs*4scyE)e zrDr;DDpbE(M$1FtI6RNqpVmed{@h@iDHri@{xUHU!< zY)mw3%73B#$doz+^82!5dwjhOTG1wN58s<`l5?SSBTYEApf`mA1$&`l^{^wTDbFrq z978~c(#X%qZ(S^NsxLCB+@|i7ZKhSHBRc73EAh8fqbL}dZ?Tz@%g$c8P57^&#=qB0 z0v~EfM6VC6mmn@Gpr3h^-eY;4euFUM4vDXr!!J}ue%l-3y0+Cz2Dn{9-JFL`VA9z$IIwdGv6#oN-;8vqezH$hS$}p%1$$Q%=Em~M5 zU6&KtK<%=J{V+{9?(oBIXHlkp4<74ctu3CEo@iP#Oa}f$IV|%Y6~l;mBFvPF9D%tE z@j7W`l^4FjbM5>-mMTN7hWCCV^!?FWZlVsVqY!oO#iHeH_^wjgj=83i<06(h$qF^Q zvYdSOw~crz;p_jPv)amCuG$k>o;=k+oTcKqr_v4?xKj;^ zK4w()%NRbVVR=QhDUz=WVkpE8hhP70#A@-$A-6)YFy^Hwi#Bsaa+YT`-`g4uRi$YI zrH${mo=Z~H?Jzy~^yLA)KtBZS6#tdm*;ERpn}bH4#Y@#k2WD)>*xu^DtD;u*>TRyM zhwc)CD5H$rx0Lc0C6$?Gts&oUOV6iIGA6=G9UXzjnl!W6YWSC12TawI=IxMGZq~_t zd^zg0b$_TyRc-HAe2<*01Zmzq^pF$C=1SnE*)Q2ZqgsZ{+uDz+pN70dQi(?B?()` zK7^hUy%)PFZ}r_AHFQ}B}Fxj{J1_$}mM z8r%-nL4&vY$N+Ij8Cgx?K4X_AZ1XW`wyY#kp;A=zq$QSoJO7cRi{tEtAuuo+L0Z=3 zI;mKBr{SR!B`V%Aj%(jV>)8)V?zFK8XKk#v^Dh@qfqH1cC!~CH?+YRSu-PLM>cs>m z3DKEnA)gPfI9Hj?-uX!QkL1D?Djy} zctfG%5z{jbyQz@G`27-ik5*UDitBIg)+;W8HN)1P`)(A0=-$)zPrP4LlS5k!QX9eC z2easNwOSI@xr@u3rGaA!Ox*1`ZXk!7i+%7W-g$u(C)%uPXFrB%zE8u&YR+58wYwnE zhnou~VEd{?lnd17WUhbO2mthjw;&E%=UcOJ>lWlS@2qO(d;62rM=RtL4+jieO;j!C zYikAxkZ!;6!>oKeV}}~)>f~&kCsh+0fA}8~M~T1^vjj;$4%0G8MdzN#2bHzL0^fpO z*R*!Pm6kXLw24PCo*kUI`5E3pTdKx*!h0?TgI8>lg#L2m*YR?Uq6I&^p$g`FIVNE9 z_535bf^&*j7?}*Jz|mt{A=l9EQ#a|GXCxOiz{AH;Y_lM*ZW~@#u<}nMX>|TjMQH9^ zR_NDPa-HcYJyESrXeyWe)!Stg zg}qfDtRhUk9mu2qC5!+278ei$pAf@Bu3VbCMa6dAiWw>kbD@q{ zKf7&AWvJ`Wy<$uf-4tX)7O2bIHfD0J292%M9n*~*cz1Qd27Msf^ALtIoJc7aCbszX%IfeIG9bVU;uom&;~Ew_i|^V98k6*0V5$Fa!i%X1S{W zDb#=U5A_g}D*^FJmPZZSF+zY7uA3|YyVrT+#<0GG-PKom^%h z{ZnrK{oR86k%&keBd;g%&v5y#97B5(K6Ox6ueRDTm$(w#l6o9QJICSx^neXgnnWT* z0#q4OD7zWTEnpu?A-?|h_Y3y|YW+7KQT!|3XSW)h+fXn}*@PHdnfB+rSON>N@6Qy@ zUzCplkoY?}yKc(`o1Lk!@^IaV@8F(NZNZq41l1E8eJnTYBWLP%bX$FNNDTK?=kkL2Y8FgG2{!)0F zqyPCSo9{GX+qWRGdubd2iBbaNL3hoI5cCWNch#5Ri6x`j9v}MwUtwOF>l9)t#U{A? z@zR1q2;y331IYMp=xCwBc(?3RtDB!}HCvw-PeVyJ;>0+wq7%Yy5~{3g-lt}xW(eT3 z{QNRJ$spp{q$B_4)vk@JZ@<`bjs!VEBb6 zb}SV6&P39>ddwk25W=3sr5wAb!(I0=@HdVSd%{5DWLabrb={2ki;T5Xo; zf;fVy0{e0>0Z&3TTHh2bD>-{=jC;8ve;%}GF-c@|H=`{-41sBrO1j}K?0=Lue=WUV zD;Q_7Dn2J?32y?w=glnkP@|WSXGMTyLm}*%!K^#6$+bY!keH5HgwQ{cm_pYrW!3-h6lT}Q#! zJEX#B(>mc>s-9mU=#djM;~is7q~f*T29txWaVx;4t;BBS3fa!L!G`sIZu2n~Tf|W1 zvD4nBpNgEPdFE=Gr_8rEBPv-K8-O=B3X>v?ruSCGgFnU{colR{W5-`_!QhOn(H20e zB3ixAU8?md~sA&q=IMGsI2^GA8c+>9Kckl2^ju!AFNuja5!-z=)n^Whh2MI4u zAG3W=Vm6WLr-%gsbYB8)lPraAp?xv0XTz$TG=P1Pa-j$M67Q`-6kY5-kbb>QGQZfY z^zLYWeHWo)X#Z=-@%{bjl<+XGV-mp$jCx!)k`*dW)2QVy+?iZ>@A||L&r#vfE=lgp z38zfXyDhf`GrxO0r2vS2Z`_mGFqGS{J4L_Dq?F1}`?z-^5KH1ZN89)LmhKvz9O18w zux`Aln#U; z24Gw(_(p*>;t2?r{nipCljO;jAW5$8h&uMiJu5vRZ2g6n|JTp8x6(WJKds?QSRQXQ zhJXX>Itz}TTQixxqj=UspdCJ{xb9nsbbn3jt&14SWqKqs>%`qkz;^=JQkP2X=MylPtF|?hoxjOzM0Tq@BTVIi zryhZcpL3bTtzT{*Q}MkPu*3Lm)SO!}p{l+HUb73+Q5KS;@{PZKB#Z!qq_O(4IW#QF ztnDmEe~lUt_s+Cf3-Z|kWGebse|y88*aMG3;<iyMGx8{$c0Bnx!ve6IH1POsRP` zJG|@N`Rh@Ke`qfLmAOrR7u`kKci4~J1_H4vP|OzMY8@Nh2IHWlwl4XRa$L3hTA)y% zYja#pt*7W>f~O82tWf81aAUO^l5_iftd_N#^e+vLl||smW6~8AjkIvkO%Uy29D+Zz(J^rKM`CA6-_z5jRq~j@R-ecFD zFciCrNjUb3)=_gszIan3Xc_AcKQPy<)~*It*~mRbG>xe!#?A&r)0ntS*&~Z+ z8q>DCH&_vQ@2tZkGzlV*oU6R%bOw<|?xLi5>z7!1WQUy3s6`YUaKxTIcF|zrSk4XP z&wS080$@HNzFxm~$G8fKVouNrIFn2%hZ}#{J~-mW%=40;t|P2&;*Hj(6~s#aj?M&j2^fmUE;!6 z*rdS~ijlX$nEB5;IF=Hb$?&A`I~In4_jzt5i{r(aV`CXN0>cn+UXuTVBJZzXO(6rx zs7c+0V{YPvt2Mwy<&>suX~!WsSEQKWia~eQW54?%g5+=y>&qQ4u>C)g9{+Dy7+jnx zGoS(bfnFTyW6G()$U>xzP4vl@&<4Fl)Q-c@w$367p9r5{s7mCFg;~c>pb#uEJp>2Y zQl#mfp@vRn4;mfAP<|+wOTZxID^uyu52hf%v_gvE>>&jCL68kj^NFutcM6%GfY>g5 zZ|n`>{>x7;(cCuH2qhXLd|IWrR~*i0u#^>Ft)9OK9c$$t91&o_QubDeusN zfF_8yd(n2<3ssx@jS1>`>jm0J_)|vIQ6O_VDEmEv2C%?tGc~V$fy2+hM|VKN@(4Ln zBCb(9n~S9aWWrYK9QKFltEY$mP{c*_MJX$$9HhC!1pE5V^79f;vIz z@e`raZJ^ixd^!}-!Tl}+2M}Koa0%_BAtm+Wo{6#;4plXs9UTSo!+Gb&*Zvw1Do+BO zAjOI9mTgGdU(UqvK=74vxEsc#EzpM{fQ)k##!q~fikBm?&xKD0p%6nA)5d_S&IOlA zV!MruZeXz?)HvN(=IaBnVGXtWQ6}(QLIFkqx1fL2{lxz%_t)CQ6z7`ygYMrt=JR+t z1k`-PXD_ieB1n_f`p_9aQ-7&mAa$moOLrt^{^q_qF8^Q<1jd5^JQ*y(;QyI~bakk| z?KnZ2wzK*_M>nLcxu1u_9D??mH4ceTWyzoHn@j+J`mvYj8sDq9m+{^vBrMp{n4u9t z^UKd)7rCLcI$6+qxZ=s5DETz<_vsEGW@a*fB|TI9weF(V9|B#6rYo5hI97KdLQC$6 zch_aWu<-{1r~&TbLVaUlu+T`8MvzfkLT-M=o?h$_LC4grdgKwUD7Xb1-8V$r0cysL zHMp49qr!2+PZ58tLX-(5c!}HEI326Ju;s7A6)F{tRI#k{X^rCSGVFTq7*~Obk`5iB^h-g3g70_ypX*)#5Gta zwL45NbWHkFwe*u*U%F-w@S@d`H~sagJ-^O!4v(qor(L!_X+r67X%0=|`1OOCJVwe}0J4K7|5`MgcWI(F8kpUa_?r zcyM_?EulhzU(SMRH9(G&lkS-}R)Uvy8I&HJ6`6a3zcxWb&$M4pp(cPQIuejFf5mEk z73gdEZrMzK0PB90W8m(rSEX@(fwQf z=iAknr?hkxt2MV``9SkM3l+2U?E=5Eqo#SQ^PyM<+x35@Hdlgc0hQr%W>*ZEjLX@i zjP$LHkSm@`At|fpaHohny4ZJSiyuBIep%UW zy@su(T}Y#S2nNlHmW&19nZBE)@X+Ql0tOI%XpU6?60Ce*?PlRxcSP^POtp%Y-oM6> z|DG#5&SSnRUReS-#iJSgew4u7`z?SoBa84~lM==~)AD0ym}Z)6g&v)hG+kkO?v2uj zRDWV`+FaTLr=z!QFtuF{AS-7DnsE4x*(HGJGcsZ}nC= z_P_8fg#x)kQx~gt{x(_NWI^tkoadTIe z@1Ipk#{x#_DHNx* z3ojmn4BG0#22;hC$V7ovQ0gv}e~_{vnqwTMEyO4~a4y!Z8M3}<-pbxr0xOm-?b1ku z5DC*IsgAAH25SH59yNTlOu~>BK&bD@;+Q$W72sT@KVb?58ShWl8|Vj__>^{?h|@^7 zj@V5SPGcOo(b?DSVD{chRDhPS(5Wi!D_e}CLrbCE`wA4!oe@5==|3L4IW25Qa$7d+%oC2s zlxE|Z%+ebHJelQ(-O=t6h#R!5;)N%MIw%z<+w_oK_!?yL!nIF^NPW(Vh=gBgqZ2%?@FSZP@h9TcK7u4^p&UFnXCHk;imr*Lr8y9L5iZTsZVS6t6^NWkwn^-zo znf}Nn?gZ(LT2CG~`22r)dlvrK^Y0{u%?JxZuNt#QHgn;T-zE7D zB5rlo-}3b*^Vhr<#fBt}Egi%WMJ||i`gqHoC{w=#2Z{g}l7dfI(yd0O{6WQS{vLr- zun}*Mjt|vDI6He;6`u9{HI>K6q|ya(rykZU&+fNuh`>>)$>?s((G%qtcz=*_4u%UX zk)eQPFc$WCS~#Y_iB}XeUUVnt|`gRgqX4-mtXBg=|jF}%TfNl(y5?q;a4v}Q94uO-I!^;vTU zD-fy~-;o|8=w%n7?N$J211Ji zhr+?$UHbY{DDZQWV?@jbs^?-BFVS35u6sR~O;&W(BTF1Oj}`6>zl_(#i{EH|&J{n!K6cB=Q*P--lJC4v5)+Y- zx{%mNU@Bvs^1i5e{+yhUupB0q#l!I##$tOT`-#dfC%tLZ7Ek*yfxMa;TEVJ4I{RtN z8V3o>h`-(vO}+KedV4Jw=9LpCaRg3aoO^xZ-+vU?!3n;f=p~tO8^aqPQDJ?|uG(do z3a6=Rns)#$dK!wBT-F>}-CGmU&i9CJY8D&ywRNY;HuS1cjjU;h(Iaj|S~Q%3+JREQ`u4H0;Skp(5Cx1}%RN4xLYQ1)JS6=4CC7Uy*lo zo;*As;V!FQp0z}D6GpIV-Fb}ng#`%pUgbix54XH3@}!b~V@1Tw{0xZl$Vrmo2j^)g zTIA?GqQ7esrCW{Y-rc&ws8)4v$z`^!-uWNj0(msoVccNV73*ZFj~++^;9T%Di0_FM zLKhI%@zb3yqU|b&QgApeR?5@%a>{?vnJ8*-SEPqJT_N+yJx_e)pq#sIXL+^D;Fz6-Q@3t1 z#6YK_ySp*F8MH`ZUes4jg&w2b4|t%tcbdXDAk+In8Oj=oU~Y?!it!akQ>x_eJ^%eB z|F$4+)0)+CpD`b=^U&R18Q1;U7&r|j2#5Fig#}=1TIg)c9jDZgbNg!JQh8e62$=~J zt36?}pp|YN00zd4ZD&e^!bBTu0t^p&e)*o8K|8I1YWM(8!s zrHGwS8TZ(S*spowJnmi46}lH#%9Em)DbmR@l%(;BIF2*Zq*{Cvd8#( zGfmA@HdZj(?r^W{lg&2t`yZu5@}(o9_X|C0lG5R;8cW!9>)kgP;j&O<%es)aeM#$ajUj4s$sy&bZtV54}li zqm<|yXGo*0ovmKEAb1x2d2a!TIF7HLbf!+mf_jGcHQZ-DAxh={uN*8fDE>3l-&jfx-GxZo&e7C1@b*Q=Y>YoBi?z!z4 zBMSm{nUwb+tL+Aj`j=@cR!w*5{`cZZIXI6ln+pX9$FWb~eICcx#gmW6#fHvyXKXlC zfy8Bqv--?pm}jcH=>SOQ48wLOG0id=X;)x+((DpU6P^)L&oH`xbg(1f-?n{HpK!6@SB*Kyg$3wfUfAY zu;`if%Dgx3J&Z)_Km$&=pJPm=Z4oC8)jr(c(cM{_dSHH6x8*SoZyaXstGH`!zN{HA z%FRnBPrUY-xI9EO$at5v3D<}y*2kD;?$CC7-1AKty$~XF*6j3H?La57E{YR=B-tv< z*o5ZuqjZ7@mM1;m0o0hLG7=FNtsENsD9ED}7cbs>`8NKo!(siE8TRe|_ zpMUOOb~(=$cG>Sz|AgLLIg5tB=K0}`taHZ#=lVxD?@ zt%x||+H171hKU&F#uw)Tf={!is$%?6UPYu2 zZ!ENCVxJz9@i>)dwwH=odh+Dc6?B2aZr_zIiFkHv zZtc~5J>j2T3H+ac-k)?}YEDp5-vzyZSjlvE80csTHCxgvK~hpcsNU4IiHMw9BG?)4 zS$0WqvMXvhS>l(zs>isH@!uuG@1Vu-Bv$;Y#Mj3USK&0Ui#P*BZ=o?}o>xv?!Dm#+$T6tu z$ebied%iMOtK!%5^9RG#3{bVy+DYD@B1!O{IF;_~twvb{7Uq}gxd|dGxY+GtgK`&77eIoY4^nm-CGo5^~?4haNk!!_i|Vkki&qqR*=$ z`KCk!$uky2D@UnCG_GS_pg5^SY=DAM`3F6u_K&C~E|eJ$-04ab4NAmjwctYy0|4QR-9cSMm|(o(ctOtQ&#bEN7}5RhZ>Ld6$l_`B}5nk z%Rx;-d&|06P^C|`?7NtSNio%PgAXdBS%8m??Y>X1#50OFy0d>GO){EmvsQLH6Vro0 z#(^gEkwNM=4f^4ucx?gY|0oszm9JyFae|ds6i$&dsc3`suP)5`hWfHv&?t?-q@yk< zzu52UwTXZKMqYSFLUM+nji$On9j1hzB#1K74DMW&e0IMHREx_W!TO-)t&aJgER$31 z9^lvoi-a@y4o-Uw?&~7COyelR@_<&cq3CrGCW+%PO*(uo=h2Mv4i|e`EZ*lL9Tv8< zKQ+K|va3-3sz!ktl}|pu9JQTgvxEAC4c7}rv)jIx?|0e@dNw4C(pJap&wp>9>?N%e zG!wrURFhRqGhv$jkOt{yBni@u*h5k&;n-YOqyh-1x~*fRm6pd&+v(>)x9pPI*2?$i zLT!y$Nvn`^Gi{CfurJWtXQ<4|D51Y)tx68(oShnsZ6tH}KCYUYaj4)CBsD9Mh~(%s zl6!$i;(R^&<;UfndsGZVr(n`sK~&dzbZ`CYV*tbbq1Z zOQs??1-3}*d;554m+tM97Gy%)DlKs3`QxX_JNHg#CF|C0ee6FK%>OF0f|*@kd9cxs zOv_mO@yY&L(J2|2=PDSD+B=z#zewKqgqscN{L2XZKkb6wku^4tNMI!^gIBElPl5Jd z$%PdI2PL2J#en(PyLN4Qa-z08Z}Zlo+rO6KKQpmZJH-RX+iDGy{y>xiCLkc9H-xzvIfqOIQDl$%m-N=F zfNV-qEjGRAA9+{r{SH7(r_9yDEq2aF=SmSVGP!C}vjD%Ax8Sn3$hkgZGb%smyh6dD z-FVKT@v7%`xtrC9pe27Q3})u|lj4vtx@uNe|NLU&$KH!Wu+{e_Iz!-!&=nrZx}mrQ z;oY>rk?|-3ErSB8GXoEI1YBvcM(yn za;~O_9T>T{eDxyk($RAXB)$NJeJXsThfJI>va${~HcT%x>^QycDi**s97Kw&MFwJ_ zw^+Fsas=%nmG3lA0^%;Jxdn}g5fp{^*MC&QLF@`Ehd^0ANs@3DPC(YtOkW6kANS{{ zisudg;|1X0l4^LM+A|n=gp+{zUoZOHy9j|cw_?ftWtSuFa}_|6-M#)}4b*jQO3A>W z(c|chH8tASxDZ3y*WRdo5>o?;*~sp9uoQ%8ZPQmYDOsHLsa$w*AJYu}C^YJeWye!{ z1?u1kqyzuvaF*zaEzR8OWh*-x-y;3=PwfYv)6iz}MrJ<1OcY>vR$flGi*YQoV~52*+IBS)YkS zrX^E?Sah+u1sU<2CXAbc={Y!xhjejI;>ht~K=ZHOL07-f@L!wfe@ZqfY0M^)PN9$w z#k$bA8y~H4*h0X#Xq^VmGpNr)tyGpzD zXs)L19sDtzK(HNL~gQeDrQC40I*6LImQ0QW&=XB>0_ zqJwjH+ZrrfJ_18Hq~>jqw%tnlf=RWg0NtAhyJ;HQ_2Nb3Fy(wOe&amMZ>R}pCdi;G>l2&7afEkSnZ~N zb@sJhQrTzYI+iAM;(@e2K$$#kb;H7M0aJ_?=zBtQFG0PW-xn5R03Jg)9PH*gksKy& zCN7`PnPlPhdA8r1Lp$!!SNJ(xSpxq|CSRb*2vZ{L`z_+TrvDBcCHc{#qIX zuP+`60VmG^XS*jLrpk*)9QNgl;2^|~FxBDP!XwqYqY^=H0a71ywq!~}m67uUc`16- z@binr5ydAcDr$dDUJ?Y`q$VZp;6-`Wsh7x+*!|AiU=6W&^l(?btK#-9AK#?!U0>Rf zeP{(+0oaPlHGSf1zdyBiB+`o)bn@?sPyS=grSv0L7TJuG2e!z7GKMzM%Eoo(5QB;D zFiO^+i1;c1Hhtm zMfZBw?n*lXS&?-12dmwhb{FKu0-Z#$jyGYjLOzSVcdY*U4$8~n$FWcKi1ui1tHYqD z^;*B&4$_NQ0Kc02q^T_X+R)`KbYQ!!Bo@QmnoM-Ut-biMWQR4xQ!IkbK=Wy)r~4yH zE4e|#Uxzy&<_!mYX^5w+2nzdx;GKk&7{+_=_k0+KnAR6ZQwGyL%Yb*u@A(i=2?s3n zFX#Jl3^vNMzn~vi81^lVKd zl(ZgxFVgFKFA>|nECj9_duBxu<-BKN0li>2G(ETbqi07(XpyFtd4tGdT!`D^UMg3L~IKU3}@@!-usA+0GuHHzjx59((5 z@7psoID1brv&iVJxmjrz4b89sqcr2bVM(ZvkQU>zq^a(oUYRv)sagE7kx^lkeaNiZ z$>UlRyz^@e>AAN~vPbu4a{Y4ggayiSoxhJz+Bs$vx|hwxc=)xsWal2M(8VL#DG5Cy ziw56|L07Ej!PZ#QrhBpS=LfNj{D<&_Xk;e81tuZ7*smJ61W#tC9aINm22uV!qNiNJ z&>=90x2I?G;^EdoPC@wLpF+y0&~LJp41fjh!yL>aOWN$8&~VeZp#y5)|7c2w3Z3ikuw@wOGY(9%uS3(n zXgn6`w$rv(>mPux{QRdfWir6NFE-H@HUzu@AMcsRqw8d8@SA063AKQe8%VuU51xCr=JZvUz}=hcNLjQ9xyrbr=q(@sIb^)v{*%+ z{%|BQ51G>LSyI}Z&BWH|Rw=VgMXMxzb!<)GZ(^OFk-4yiFjxl>CzD8;o>2(jk zZ;(ZyFuE>;op1(@2J32D-l|WTiwzj#?eV`hDn<=U|04CULWUJukkThxl-ybJQ`;`} z3phn(DIhA$FcS0NJtg<)hGEbOZ8DWTf22>-w8`N69g<_r%hLy=$$M=uUtwC^j;@Xy zgp=ASZvGT2K9An^Sv&Hxw9@7Ok3J@6&?}$koFhPlJZs$!5O9dSKRlkUh$rP{jaG_# zBV#8p|47+x5hl3t33?d6?!H)RxE6}TWUi_i?QS=K;CWl6r_h2LI~!UWN%y`=t`Im_ zrbiRu4I81HTQo;yheIgQo#b!3QHU<~u*70Udh~INnb<64-=Yl8cr<(x^T~5&xI4G!lddP%oH8`uCq`&T zV><6VBMyEZV{;&oz^Nkaaj`%5k?C|feKfJE@vfa->+^eE&s0M#(GvOCo)jreebm?P@JcaBm?sx6%k>PRE zyHj_NulWfj{wm3{V6AOau$MkKVvshDm)ysGUwG$8gc*I4@bBL+jluPfC);_tdifrq zM{SPFO2zGjde=_2;=W_%&H7xCOR6_K0Oe5V73=bYwCc_%(XZA);$=?2E;*QR=YE^& z>Kwf({X<#!U6Xfh8nw>uWiX|{)htf;{EByU)s6Z?{Zwk2*w%BA#Xf)QqlR3qYb?6B z^?0rc{_evvY<6L#FS*mIC(QPMd<)X-*dwlQ68mu!x3m^g_hJ5ewYqmiOa)UkeUZhR z(`ScubAmt4Ek7l16T%i!tBxfSE+f)&pgFy(Su7a4-25`bxw4X|Sa`>Y%0^AT>YIVm zLa#IL%f4qgRXcS#)%;C|Jztb>YR+FKLLF=mEmhdxcIc5;ER~>m(s;yA`}lGGwPov8 z&ucT-dfwxUK8vOPj?bM)oy{7-PJbCI7tI@=IP^Y>SY z_h8H=>$VQh9t0JW_fYpZ1Y??w;)|%~5Z#LUe!U`IoWFCQn&ic@Y&F%IVHq?^Zff=+ zio|kUK}w4c6Sm!o*H?NOn^m%*X?nO##-Gg+QT{4HefnBe6SoYiMDiDbXMk6k2(Sni=~j5^+Y)w?)sMFgW#HK|WHKn^f>=lIcY2mEvAG)pfg zl3r*Hoy(S=-~`=F!Z%uTIofi;4cVyVL%$VH+SBhwi={k1Z~Aor1%wj6iI3G$*JY|D z*F1dJz|Ge>`e;7p<9CGOL zA=%#cT9ai1ePXnbk%y#t5+}y1v!dkk4puDYFB;?som>nELgZ+%eSs+d+IXEOsGjvO zt@DT?y#K@ByAIb9gfR?#w}`o%BoR3XMh9TLmYMCm-FR1oHqHvl1MA9bhwd(8;P=5a z(=~^!ue4%~&3#@q$hx%OpXdzwi`1eO6^dvt`dsXV_O&}{kAng-x5Ev6>RNxvrYkU& z%Z=n}W7xlpGoPc~kf|`NT*^4Wla6=pEqS~(dB61Q#K@#(OWIpJi=gj6ag%TJnJ&z8 zu~<#+HfCcdj3sm8ZS=N-{f7=?LJn=!7$t$;hwtUw!x40IaZfwB>Kpf?EIQtLTvds=ko8#9^#| zBl!FNOWHCQK48q18L6!f@;>F%T%6Ef&eLiBfHK78?26Ivb!zum7b>Nk+Oi8qKamgJ zHmLd_K0Ru2chx7&1NU3q<@+-*7 z-%u@k@1?ab|M`eh#$1p3@0*nYUX`Y8`l~f-w3buZJ=E^`8TT_&>5VUGxio^4`u!uG zOC((gAZCCfAejXfdLuw-T?#*&Mjhu=uy%7Ygo4#TYHUFi#FUFycK z1QioKI;fcNF=fx%e5*y7Y-lUYTO(n$q&Z4XT3xcsc{!d@^3yA}6|EILF2!eyt-aI( zop*cgj~1kDABj}80N(ny%1nnw%9PM7`f+wORL*gmQABPO?1tKc2Hn{jqf1?cc=fwk zkJnuS7$p;YYNN#{Ni^;nuT6vo+zR@*IAOz>l~Lgw9ah{KGCi1O!Y?so{;>^_8DkNj ze-hj6Pw#O?>K>ki2pX`Qp?07UGH%*mMyH(7nIqNr8pKo12f5%SiIo(ufqkWP`y6v9 zTnChj4o}6%7+3QvboGo@)&??H_HS7@{p=GoUk%z$+6ye_XUy=L!1w$TzD@ir$x!qe zTFfd-v!7hg;Y$!lvZ2{FQ;M8j{4hBh)`1m%*yoiO1GiK^rR?>QTcMAXpIL*IV?Bj6N zOQ{olOwz7x-pkTuhaW-MXu3gqJfOEPa^WJn3s2oY=Xk>F~0yU~Jo2w3&PhRCKffc5q zDB?p$vP1Jjdtu+|rv0P0?H{cE9%ba%Twi&zNejCi9oVdc&*^C^g<%nXXB#_O0X#g$ znWj1q{5RKW>YBwksn><)+oHKCwyrmk*Qrt2*^1=^&Uz+k>V7kE#v%0zpZ(Z8`Go4J z(g3c0JcpeXBUR;HPS(_+Hl0*#f}Zplv@d;Fmv+mfr)NJ{Kl{<*is>y56%&4aG$k#* zCvz7`XSXDs?XS!&^{p)|4df@E<)1XnSPnIgH;h7Cpy`ryh8KGxnP$Za6-G{JO#N_T zHMN)&obj62<5}8eICSI+!mey*>A{SX-pWR;tx2r=CEoQyMNx%$WYR9V zR$!Xdu4!2=!(eVNg~A?svf*i0m3Iy_oWqiAvu#!&7{dyBT;^m-zp6rPGS?&H1j;~) zFp^tSRXLya<^oikjd#;WM_5oNiSnRx^;9qCIGm*>9Hzb3x z3fePD?Jis77(9et?_P8Q1GzV{jbAEYzPq-lI=;B@)eiG}`~CWZqqn0Xy?<9>NcG_U zWU_6hc%1#oQ=%^7h|A<2ZoS0u-%PLv{scfwTQR$_%Me<@&4x-Iv#HFb zBc-+VxAjJaig7ak4|{(Z)n)p=aii*>gh7i+i8M$fB_)c0w3J8*l2Q`VAteG*(k)0y zcZYy_5Ya!~P+K&~!YGuE9mY^LLsGo< zkZT7Z13(!x%lxwLNTQ^skVTTPNG1hUPuK1_vI5>1Y3}LZXK^Iq$rA*xPQBw!PR)`7 z==^y%MAx3FA8tFlk-UwwTlmBnWeXr_Tq0CgcOpe37wzQW#)t+;8m<4kvdWWFC!TRY zwzL5#+~9txzRKjG>qW*Unp*m}d?=?3otl=|<-7l_+48RWZj~$5n_%W~`x$hjvd$Zt zb2tN#LXA^o)6`qMg6_Z_HnWKb#n*37pQZW6V-zVk4<%6!6ITY?{R$W%t(bTMn2wCT z<;Kb%>j&{u_CotQk1AH6FqUHo)!Tez8|G7 z9+paLnh?sMlDyqVzslWeu3C0-S^7iLlga~@IhC{%NhNjuNu8k*GZ(Z>EK+h2zk(n~ zI;lgDk@%8C78nn5q()K=1yp4y(p*IsyMSzH|$tXM% zA|fzm3X_p7fXLCm9?xP9HHfiQUwsbVyq!K(;0(xp>dq>h||Z5^XRTA0qe8UBFpWa7xVPOtTE8p|{umx}YI zXXWSKJ3tt#&anMlqfBbEj;+M;>7x(O5UI-uOS{N&i-kv_31>QNj1ikT#-o05t;qel z*O*Bj)$v@9m2fx-muSv+e^zQc!}%X-#1tg-Z>*EAePlEZ7C##l5_4 zkir~N$(IY6;4x zhdvaCBQur@9cBHiOHN0d25z$c(G)>MYahI^MBfd{bUbX0GN|{)ulcq))6TXr)LKt* zB?ZIleQWMKZ{Dj6Eem?84BpT9o-85l;VgADCP{}bk#zn$VngzLF-aIo6RUFic*gtTWDedD;%eRSew$Sbn%xYEnHunlhNR(>o6N5{>5F>T34 z>Ba~B)mc|yum=Z7o;k`^Q!wtNte!b0rEWa$!P~4|rZ{|R&%@ZW8{yacD$}2hkK)lC z1Ksb-J-gOGpIrJyO~4^+A--(E#rK5swofYQ^q$WlR05*@RtbRjb zWpYdv+Yj@oaatmD6=FJUwhKiD-3=!>hag3iurU`Vh~f!pQtp2;)lK3-ge7v!)#IQiab_bl#sq-g}tP9HS+>*j9K z?;K2v2<*>s4W^3)3`bFyQSVLIm`l=GN#{Dmfd;Sp5}-Xe)G-+xv$Z_l$hPTwWnkDV zk~o=dXIBkQEoZLYa;$E?SL4-(KN#et=ku}hMk9t;;^{74LR&vfCfDBD36a3G!C#3X*jxcQDKQ)TJ3r$xcrwO;8DbDt)O!5`|Q*nBjy*s zqTXaOZ?7BwVp7P-%OpX{4sO}6f7~EizJGoh z5(sh{oh5|2H1rYU8cAkq=t_DF@fg_l22f^d^MW)0USaZpx&gAVm`@=~yCpXK1G~U%Yx7tw`DBANS$U3p+suqFsBWxecj% zSY~re2z@(Ml+pV_MPeRHX7FpGZ9wUaRxh5H>n%Q7FxFYVp>>9e<&@kjfBuVqT=oYd zA0${RdQ~@_`;WIJdIFV7OvjA{eE*gd{-29ui+&_s!)S_5g!*s)7WosJb8tt6JJIF; z*1Y}4ZP}oHJr*NSmvB2Cgntj$yFf*$61@HK@jrg;FGrm~C6g>h|B>G|4VjprV)6Mb zYB&Uok#J`s0HIWe*s^t3hDvn@3Ji32mij+k5iggXMq2)%y#)qxh@d`7*ym~lSn`^9 zp-MFa9WHTuBd&Nvx(ZcD4i%$Z52VrE4m8jgtvA5Uj;Kc@D($x0z#Fg0E;bGso{@wkuwKe-95AmwSfFQvu|0^uAqo=eC}QiOZ{``w`N_&v4yCp`{d(=s{rPkuvoDTb z#MU`oNL-i%t9`_eOqIc}K%dr=|JC#bGh%QNCj)mcgUUlQE>IEp`WRN*tZT6W3hbSy zaR12TYhPtYF6 zPWrhr!HXTe`1 z8VX2w_L4oZ5i(*w#HMb;H+ngtEtRvJ{os$w=n$Im*Y*B?vOanBbHdnN56(sNzGw3q zUN~o4i|{8^!AgAH{y{?aZ=K}KzRYtJ?CBXWZs*o>+b~sguTsz+bbAl;JgGf_<}6$2 zB=w_rh!0>XEN)1I&c5uMl4R)cC_sAosORRtnDj`#ss>zl8>}^P zMQMtsX-eE z3-FfIOJ2s8Lb*_4w8}9vY!iT?z7_Q`VsjF+rI|UH$e4lF7h%9JPR9R?PxauHg{BBX z0d;qn=aA>r&^`spUK_Znb%EKSS!T8TqOvNCLFFnDBgaI54{h)xIyw7%+xiq9#ui7d z4E_*M9mvfj_%O2KXi#$axPVou*4Q&lb|<@K1X^3S?X5{Xz6B~Bd=nux9>tO&b%yte zvA@Ye<9RY~a*NIBjXLV*OHfF-;I@|jAQY_# zw;WDvWXS80rzDgV^K>1KuEMf zQWGKLfeI9ezDt8K7D807ttxvYY z*n$_Zjy}&P0iR;g*I~2L+c7CSV9v(U4oleu*64Mkl&4;Kl}XI8AFD_cwOal~cHAQN zfrhu@ScVYiydz7$rUuxvwo4S=VmeZwrLft~K9c`IJ*@2uD9YC{SluD<&G>Q=?l1K~ z#}j{91t%+x*A+kZK@g#CJ`BNXl(L)O0H2F7v?2$y^MYqGfLE6cyN3zek|WFBjakh+F|==rnTpDf$DuUH;PLD0(iUX=*NW*MFUuL17IEYp zky!(;bEr1uDvavuLW?s^Ke>wv3}@=$)TzaSh$0;12en-BDz$ojcx)A5y{a*h6rJ}J zLdQ|ehDmH-OJLdf(5{Um=6G+_i#k>`N=>~UNp}OXWNtuWbET*|v#Cx+y(O)hYDr$j zryj40Jf=Cyex$-S*?6#s!)Gz-pgwg13l_rH-=ow%Rk>3%&}=OY7QYA&r8UNVwTA*!Y6rfi2wBv z^mchdraZaaa$%xPiWS;kDUr8j;+_`1=+}Y0l9l+y{g@IS+K;>yY!S7I+W9%32QpQP zjXY82U)*POExs#Q(Nfn&OuGH}mKn#xN7k;zLhai54hKp)rg_a&HMH^q8b+6KPRbLu zK(Oj*tv9Ur&U}>c2=)^WU=B9fsis}pFHqtY*W_)q6%eftcKnyu)l*OwZ3Lr|1(@T6 zgeoj$IygzY{d%N_-*#Zqf?h1(N!T3rUT%UJ$w2AhAT0OBZ!dY&2k05vN{oD~YK8`; zj(Bfw)mW;rZQksQ4JRg@?g!CG_pX8J_R|6y(OtfAx0q8kuLNg>;D!h`k9My*!Vv<{ z7`?enIM6Hxn3e0+3mL6611fZr+Y(<#X|FP8N7-Un^7_-1R<`1kNsFey0@%D{PV|o193@Jz8tSbxfR*TGWf;O>7BMm zLBL#CJKm28@bBf3P7i~-p$%9@I#+ntK96;RLWMW!*ACDH>*UFQZ9Laz$IcKpV*`Ko=zrTUo=h4B{=0R_!~1BJu2>>LZPi+*NRkyHF)~&qni@V4VFYn-N3c=1!D(mFVu7P%ne6=0FwAo7N zBZgU}$;YBEgL5*BM-kl7$Cp?gU6LmA_Dgi`4WO(wIx6YJxrVs2K+n@ylEBIc13gdN zx8T)^Kt>I|sgkLMVL$qeK(l$5kfiY%MWVV5VAx&AY#J&efv2$@Fh`jKXBppa8m=T~ z)sy+K`E2na@N8}$t68b#c2ZJZ9iW(Koh*fv>Yf5cS8Mk^@Q2WM=3N>9N`+-q9+G;f zbWC>Af%kYC+3~7&iy8t+0-}FyWo&=gB~?X1=gxRXe3v8M7?B<$!0r}uD5wkUSk`J0 zBHPttAsydG_MP9WLnx9J;y;MEy1@j4|6OOB->MLNy|az9+Web~1KY({Wo zDXoBu6fzIN7dw(u1PBa!PrMZXc8^#yT`>fMVuzC>-(aJ6MrK!DF@Blw zR7Ah>wDOkp2B4oA$cEg%JolP`EL-@d6@679Dee$corY43AI}2KCbX;f%9qQSti+cv z?W?JY*G7qP#xUw}H@#Q0>ZcT23dM@^>C4Q+yYOIKvvvm>)o-j7_KHa4 z^*0{sZ6t(>*nvXqmyjIlyt`BjCkmxFg_O?@ai6^4U3BpvSpxS>LmgbzXvHO~?Y1IS z2u6WVC+=#r;H>t`_)9u?EAbjEf_L4{Fw_4$s!(thEJZQ(h>{V-^0){ApLCb&`!%}U zJ!s|?ka2hE1iy6zlfwY3hTS|RNDxOUbVBrU+?gebXmfdj#F_ws0Iw3~y$8Lv6sqD5 zq+s?HTGB=LnU~o9HWdZop6@o^?q)L^B6(nkO->`?flU3(4;BoS1g@@666&?ygbb^j zdEtKF5<@m(PasfO`VxW+sZ;iT%aF~xzx`Qgc~{c$qZl1PEmR3_iEK;hL0;GamIR}2 znDPsv>~NIv!Jd0Uxm0JCf#Y}Cc48;xY0EFFraVoS(G8+>NLcZ$F@pC{?pIf`k0Y;$ zqrgjtzg0~ClJq*Ao5nD}Y3Pc-j|z?>Lb+^pKKfgRuEOcXpj!16~Qq!czqk2H56dhyPCDwr63jE;0e%L%zAOA?= zjUj}6vodDdAfvB++829SD!G&FMI5fi@QJtT0h#2~c%~K4Ae3y3FIjH;Qn7DS`&-)P zF-*>B#K=8Q77L;ZjcbS_S;Bk&aS}_!9zsTuR{}4I{_SL>&ILjx61QC=^F6gqid4)} z188F6IIfhs>qs_0z9iH|Oh3;IXwc;S69QUP z-)M1zo@J-V3lJn>dr;O1?bNm%rjzgl>-Zj|@6=P8znrTVe7&xEsZx;mFEy{fd^vIJ zwWsyfJSc)m z9H5f34B^iYP#=n>v!CT~6|Vr`?>lrM3|FRG!=eE3-_aJ$&1N`~7I3zve9taoUDd%+ z$oDUY^Or9Z$Ye61GNtrDPJWs}2Qm^UXUDPtGLZSsi|@?o5!XH5tV!ZZ_yKq^8i?PB zPT%Qqh`I*Uf+XRoSx)pvG=LGjw&o!-vX^}IcnR(^$)NuHfVt4d#?`K*f$fO{WFwqN zT?a96YpuMe6mOBm@f7^9hH~wz$LcRH{#W+>%c0)Hx(p>?eXhqCKixxqE5G7}e~vuQ zFOc$c#=gS1M@!)IuJ{6%@2j#M-S5ZF`YpM8FPHW_AL=x|feu0j_7f(jglyK?F{u^D&A8uwax zL@O@6BWUp9B+AQTRlmlhjOrEUvR-Sm{^tG#2ACl3w3=(HwIgdI_Q4bG{JoPs3;Ikf*@zw!80gSggLf<{F! zM^2=&7XBsY|G!^S;NDCWW5wP1uh$M8x@n9xQXgCX;~fu>fORPX-TtqO-rrwL!4D|# z`i4DAk=6O>8vEP(E(&W`Oq=_kP2Zm!my9bcIpR6psjUBT-6?Pd*Q9i7N&e%bpxA&m zLfK~^|L<+NGbr!jn5o$`|K@Y}$2kTg?LC|&_O$=%S~kNm2Sw!k6dUvVIX()2ZQR7?Nb`2)rl4h3u@t}zco zex51*dKGR)z%lzUpy@`GDw3Q3UO{i(yTM$eCmkw|MYl; z!HxQBKR*_+gBhNH+c)aM17|utqU(ygq0x+l?0y2QVK+%52HbFOpi!v zb&bVycSLxs_WcAx(plk8!dCETcMXReK;tQ9z+Vkr$AKegCWzS{5ktloYA{gnX*i_S zX2+jl)$aE$a^TKdl6Y8ToYMiVu^l7&4L8HA{oc(21X*xfIgcW&?(s~s9&fr}wKQ0d zwV}!BA3SSz_qfc*%|@H;G~8hz-Kif&p)3`agAo^z91U&)E+K3N&`VA8{5aD#9Y0LE ze)gCN=3)asL?-Czdi&#Uq!=F!(fSO)t=Vwm<@&wx>Dyq4NqYd<{Voi|3HYWT;55tQ zFkmv*78sp!`1niZAi!?Fhf1tnOf4O2^p%w2jiM9`J?{oFZa%m^Js+P81b?+hW_2sIl3O`S1h3mlVQ4%SL3 zx~kw`=>o>**WL>C;Ih_|zdXM0i=$6VNRV%Bygo-+zu5w6vY&R)@n{huN?`96B3Zit)6Nu^6z!)g z?Lech{LKiMf#P1DZC&VON5=baharXYs_Q@;{G-$8UttH6APp!A4rfC-3)q&!M2wUr zNme_cm43CnkHPE|T4s{;R_TlzB+Emk`PZQh-Vbv$Rkv|MOV_qBn<$;Dj>qGq7iHlw zo-MvNSo$<=^2ib1J~o7!&@gdiHk+--OXL5b+9|^OThv(uBaYAxk%%}fK$kxAAp32~78{vlp^kDI|s)e+4BO9#hyp040=v8KT7V!!l%aB1S ztr*|p=*TP!gwe~28Jl0%q00LtyE}qSFA~1hF3p+}ZSKttg&8+T41t8B4m_<788a70 z0HAnJ8Iwuw1W3T0-iLOd$0Rff@t!`^#6lb|?k54(TQHNyXbvSzphKtX7&}X4Xi|D9 z&v7dA6x!kL>7fM-WclIk9-}f%fzSh`(u^*#TZLlw3{c+9qLjlxoFv);_@qOMW%1&V zSd+@*p3q3Rigt)`pJMe0zJFWoj@$8mk<#opz9vkzO}MQ$Jk%mNjGsOx-Z~>TQ6dyJ zrPbe%*JVNcwKUrQ=fIr+n4>s&WXdp|IbS`&WUB9R2WWvOL7jd8#8o-l?9nUp7Q`rh zb-aKAMc+>t=`%=)X@j@xDjq%AEFzTzo?ePjwCGzzKQYW`G2uo1H2bCPs}_pKrhuTc zazxt1F#NA@vGip9ylFkFe=CJKy^)V8Li&n-dc@T>VGh*e3&0Ad3u$r&+`^vc!zvO5 z=MwLFz7r~m@MoisUe2~!e_G?hc?bB5U{l##qS16ECc@Sc{47th8|7srcsxyBIZzvk zbNsLkD&3L{+Ay5w)3n4KUbVpBm9w$#vLb8P1csL3sE}-hksg7XWncu$b5O{aw-s07 zWKOrQ3<5##Ijs7@SPwrzILz_g`{Jp5iWD*Z`^Cr(ZCU?WiP>8}?TO+2f{?OI3wspN zx1so(AN0jU#|DyDq~ncC6_4;&aQ%FrPeOUnUM8cW4L?Xp^SVROZn6*o&DE@YXpu$0 z0I@pb0d&q`IPVcNj1efT7a07=h)7SvU;YXs1`@?k@#Xe`FCrB_C3j0#ncDD@RPf{@ z`QvdZrKQQQJ>42~1%9iJt10+{WxPJGmZ6cguM2TKdQT8qZ2K06NZJ~8=F>t}yO+W3 z7%Z`rU+5dEz)5-vjX(3K>tXN!X%(-2a)gl%H!5pxW*d$Ir@;WJ2U8457y1In=O?ce z1rAOASmku6$_2_Mw5+yV=Ja*pT-~&_yw1Z*B@ND9}vqdI6!WLX2R< za~mer66R-AvPvZHp?iLL$3tmKAwya?oGDZcA^a5Q$8r#*DCvl@?+7m-od(bp-VJZc zLptq1zPZoQO!D9#r=lw$q<8g07>;Dv&6#yb4NW14)PE>raAkAB_d=t9Mtu zT-gvQ+!{=0tuq$0CJ|7yE#sA4+FcAYbuKx;L!M?!amhIz=s8;;9y&Duxw@8uWX)Gd zDcE~|eH=k1eRPu0gV^NKd$5P;vTJ4tk%%3s1M1Kya%5|5G!5;_lgbHyf@Ob0Uhx7Y zV%3=MSr7u0wjJZVvOivX#82R?hDrDa#s{uy{k#YInOsJASTOO$MoE>?HKH}DHLvgB{wqI=qfZWeeSHu?6hwZT zy3S;}Z$yQ;3iH8R*k62a^2>Gk1@*!?o1*6zW3oE=s#5PdpBxon23j6BP4-7z)Jd>^ z{l%0ZohN9Fc-Ka881LZ}(m*-6V+V2K)E38E!>G`tu94Kn{I9Qns$7(LhthJ}CLJ4R z882bn)cH_FC<<@kKB;X19sB30=AcZGblzl(Tqs^%cWg22SX6C1U8}?7Ciqy!Q!~g^ zM^F(Xm~6?(G6S2fNl~BH#YNf$K>o2*PvTY7T@HRpnuM?7TvAkj=S04Ws(y?5g5~Tb zCVY(n|5G9<>%ki;c84_{tgv$VgHg=BZK*$BEi^&((X}e*IYA?hK$vA%VvanC zHcGWt-zT}_Uvm8UjQ^Q{V!al`#-Z6v40++Ep01=iLZ4MqOJj7OPL5aI*3q9-UF-Eh|V^T$@p+zb#Wy$&2C=`1ejL*wa5=W4u!}4O$l8YD7fj04=YgQoCoj zz7;-^cwRWYz=^XZOG6^bV+$arD2Uq|)F-oIF~r}~Dpm`SB~45m3N0ZHAK{lFNn+}o zwyDz#aw9r)XO&rUhYO<&OYy&{^AUC4eg5bz30du!DhcI5yD4ErO+DuVL9Jb zFKQ#Zhbj4pfFnt458Q3VzO#gI#ed~yk8#K`!gX5w9K^2k#(Zh3vh29dF?YbLuZnsX zaJ2^P+{qPuhCOLIm6dnAqNzRx(K2+1ksX&cs52bXcgGKBPHnL>dCED z=?7s9@zP_hq6fSJQl(u}=!+G?u*gojTiQQ!cLrs1h)iU~!p8!wMSpo?A9HwHZOP*x z!TTf?(#uaUSOu`{A|hK``l464Q9}N6l75iWCS|4#Oxa5C{~d&tk@B0=PMoo7@axkw}|c-&+Tbs1_MTXk;dCa}6$5E8IG<;~I-1d4b=3XQlV&8f=+MFm1T*ZkTuL;M3aO`Qh*lP@-QkEsIVLt89IR>Q{OWOl9-;-Tl%1w_aoZbunlIbp#A2$ zK@Wb}1m}!)qIJ^3-d*pIu^1oPlLL^P=?j$dUu#MldKt@gK%p^-^I{?W1vQk!L zS~j2j>~7Da;N{DshUTSCF(P(pWx1F?i#7#6ho6>m%nII*=YjDgkL5l-yc}i!Ry3SV)%Eif9(3PO9Qr3H=ue7Fovsfs`HQ0uvyPJYqK^z@ zhkpf_Ql$Zqa)fR_A61dtPvG!c_Rb$JF?+63KvfFnC5eXaxqF`#l+^I20>jECavC-H zTWJnH_BCoSUc&DZQU6l*h9W1{yoI)uNU^|{edQR7@P_z&)+%J9Hwe0fdy^+d=ouGg6RPmYDhSWIC`n^FeIMZQk)Dtv7l&75F5d{qJP#xSwayD6rCs z0f>rG>NZeHhB;clPLdKTMQwksVfm5x0i%1&69+v`3D@Uf2gGjsQGr<^!=&~6C+052 zfSx2w89^T|wb`C|Y!bf#VtF>MZJ0ap{J#61DKUyyy3*9WmD+I8wXl*5ET$@jEgN+J zCvii1*p66p@3*Hif~PXx7D^)Ru)iIr^>5P*(o2C+A;Rod(Ml#ng=`TIj5ya*(w{{4 zX5U2>|5+Va<`K%t<1CAebwqfNP^@njqx{OwgTz2mI|U$Juiu>43A3dGBBNYUy9*P{k^9De6$H&YruCfN=f zaYECe7Q60agkB`WXBlZ;O;QpZ}Pp7kn%$G5NJVj|r0r zJ)^2gIhGZ}@g3Eu{iB(ET^)Fmi0bS;%bN@o zqI&ufKsL5R9wzsro4}S;^2f}tjPA%k7~NX`-!ZxyavA(h>Ip)hgiE0Xc^(4YGILkI zq$*3QbnTUGVH>6M_hanoy^F;)rYgy=d}+N_H7$5SVy#dXr$I)0w0J9QeU(%r_Ek@_ z8fNKtmSOI#u_nyL344Q-yAKZm{@Li>`S3&q`@~GvS1)AV;??nFT&sps6Hz7Egaqch zEi2KXWd;3IAUyUrzkF4h$XfUuXdTIhy;)Sjp z?f!z(L~)XW+fA3(A-gM*>tF4yt#bXV!qO!7iy1py;oZmeDm36tau<@F42Q%!k;Y&zi*DW zfOSoL{Sn5$Q?<{y2q8^U3dfGWI#2)Eqzl9bjl(6%^FMnMfB#)UGDPF>o`3egnt)A! z@D_RV-t}jqGo&$n$%VP8X1^S|?XU@H= z#(3REdsF5XiubXT%+fY}ph`wlxr% z8X@+}Wa&6{BLxN}N2sCd3>H8N6e&+yXy2cwGffxeh9Uj|s#Cf?3`IG|Wj~%8Mu4!j zDhHn~FCVGZCId+OVecMrB78Ee>SbdbR-HrUPaa>Iq#Qk=`JS2v@5k}UcWY|JGL%QJ zjzSpMH+rHMGaZJw(u`2(7Mx^8)>UP<=?U+cD=D4}nLizF=@LP-N0O23EMQDy1z_~2 z+wE!JmuXgys~+EvHw*Cwu|-ib4De8VEA2l`3dvM0?E)hilkV@}@XXYOm$7fr zf?M`{QcEf2F7>K3TPh@_>8tL#r8ZcoZl}w~h(5nXE~9)h>U&AlH#0%kZc!-&vyNCY3(V5m`oj{;xg6EfB z6|-#-g)~W`T{oIW3!-iMnG@dwCyh4aBonNrhc}O$?QHH2t|vB1-)uQ_JSv>Ng!T3f zQuEbtms0S6RzNs3`3AoNR8)n^jz0s6BbIw~`0(8|%@Qm&cX3O~-)#E(Q{drKScRY^p<#=szwo6@+sSmki=B(|>1~pNeDJ^v4IvqK z@60r-PYk)mzK*_k-ZIc+CegKwS`TnX*pFDO@a@KO@ABOkVH>k(%X>HislsWO6;JBnE)*J;g-lwAP#Q7$ve(|D)N4T1HroOWtcNB4Hg#y;@M z4qmBUK`QnYz#Xvqc7;tGtwQo?4zWmtx_hf672}pV`%6fa(a!1lo6oH9wIx$fln%>77!aIDo;E)i5LX z4ZeCc1mx?DpLUCf%zegt@#i_K_a!~GGNB8OV`D9tv`)O4LJJnc87@7StpAxuJLe%b+$BpT5@wZOYtL}bRZgD&8kmZ_Qch5 z@mO=A)Cpi9?Q?+fyM@&{p~?+LkeJSVaJ$0le9#?7m$2NM9mhQr{+#Z}k{reTH5S%6 zAwe{-@AvD3`QEyQv@wr&1}T^PumbO+xeE&(Gu)2#&a}Xmv0qU=3MoT={ev>v+fmMo z21#-pDCX!D$F?TSr`G=FMBy#nAwrHt*)+9TRl+ob#IwerPtVVeib{E|x~+I+e!#O&?R@zZsyKm-qfmzz>RS`; zlJ~=kV!IZe^&^j}uPP%6hbnU$Gsf^fgRI0FW$G^gZUni!UMwfJd1@)Kl+L7r@+$ltEu{m)C;i%SGI~(BPLV zeofBH4|0tqdS-2uFb91mFxWCideeJ)EJI7=&iQ(LCPxdmfSOamU5}jg9I;(AerW*7 z=R*ZA%4GOG{%-E79eA`Okh#^g81!$$d2RDxm9|~l^undSafL*Z{DN!s(KM4T%(KnA z2k#gOn|4#cm$CQ-a+VFESSb5Pfhpd3nC0e^5pbUIREQkD^kH+qms95{`Seh@(*nxv zy#-2`KkS!sJ@L`nSsICmyIzqezS?P&~2(b?RZ(v9bkdiM&(n0VO_ z9?BdSqn+U79hcU6rj2$k_fIoz-I2HTSul-nB~0V<>n1gk-pGo-3y74>mfiC)e-TY2a03$bw)+XonN;+L)nV zK+T7x@opHaU>q{(aGq_78R)!uq_@pIZ!;PDTQv*C$gTL`9K=n+#b<*-_G$aatIni+ zX;eY9WqcwLsomJ{+}39cwe@-*si)#vooAvw*Zlt5>j+=xm&uNE7bLo}nqojEui!D9 z=&5^+wB@6Se@8IyFWi@yCHo{PEQgR$gbsk6`iiIbR&ey-M{x$0eJew;1in?!71zft zWzc=3qVnP3x_HBn`TnH)Xvf!Th*{DCa|oRa27}(#e0X~x`Y2t($zkqhsu-?SkkT3- zkRdW>tP3mh!(9Z^B6Fg4JuegLT9e89&~LE~;0m3vYjV!V4+rab3{7XYO<(RARaI6Q zzmdo9tlB3T;~)+e+@j-q~Yq02~@W4V)`>h*pGuex2VtwH!Jlqh&#?Fxp{$ zaW*(kc;n&B8Hu4F6cLBuXF?2Kd#MpHe)%r%i{cZ)JSRuy!FayIX@>OjrRCDpeT}AH z*CngkThz1HDc5gT6R*d7t|_w(Sa=o zag`-t$|_iw7tG$;Q^4Nr4j8?tK(CIeg5g3UJj-E%<7T{MCS>?_xrM*x<+De=SV5vi zXb)5t4!LKAH%@0f%9wrvw@V!E zZEAxv)DNS(Eugc`so%XYX0{oqE0=Go5%%vk4jU#RYvO5-LY@f>f~qmywgwBSCR zw-KZ$V@A`F5Q;AyUYZL()U4y_ls#<7T2&q#zgaRJyBc}A{|dX7_}7PltYxlI zR^D+h`Qei%Ux*qs`7SvnFh{ zmUBOJpOoq<89Qo3P#t{`4TS(r0-t9a=`^OV22Qf?fyd0Q@VhXw{j;N91qyGuFU;Tp zvONwh?v$^ItHW=U0%LgeeHYC~4H_r>Jg1sZu>19+VYtv|7Ce?0rn#3x&+RJ|8n!f^ZO3q5Mzc!K6fNI-GA@MH zQe+vIqi}`1@hTol-GdzU)|m)Wk&h*DP&qSmK2!I87o))-OE&*z=8~|`1;UQ)tC1OFW2VjqE)cm8$(&9khuGK zg>Po3T;;3zSfINrR@j-*aEG1XpZm?)T1-yueWeT zw&WUc_gojnZ&y%a3oUX<3q7w#Z}nOPweKUlJKy{<&*(jmK7;0Yok=;|!rcq|s?GJu z97D8a=)7AgVP8z+|F$|V;&;uNm|ISN>pE4b!No+z3g_clfl~vIm9a*fhoqJRgI^lS z`roxX10-Qtq?B#3UQ1VXj5zP~YK?|aQFZ6`VlVni#WFXE#>inOP-I6pLYd}|1D3gI zPb!>*J5Gh#8t?m=K07a9^(EQ{@}ac83F%XWN|qT=&v3(RM=0|1-QOQ84eY(rGBmTx z?W;c5nC@@5LFoL=FV19XW{_NLtlg%Svw(c&=6b1%{nfJSQX5!?T{S#1G?*{8XLl{s z7`%9%(vKZEQrI@}=JqOx4(Y6@6AE0cI5w||&?tQN!7k8?XDy!XJmP1s#^BSi*v8+m zuc`lJxCoDv81Bv5ox+b4F2(j&7rdE&U`zba)9oN-;O5_AIa|Y&{t_$RMzv2e8trDT z@j}qoKF8Be6Qg%^mix;fsKc){3A=iu_~e#Qq49Lpm_U05Iw^}(xgYzHwQA(bQ*Fl* z_7*!Gh?RyJUcPN ziM5X$`5Q@z*zY_yLvwVPm~1Z%kG{>%z$@byDh|t=2n}W0b75Mt8t>fN**|+XKKe(| zMY%8d%i`2TR8C87hj3gou>X+8NWLb$%js}0^rF&Y%LFIt;1BX8Dk&@PQnP4G1LxdO zJqJ;t+fU4&gpwNxG<=FVF#WbYxU$SWQp7V^1shS*zQza=aa^9hPW>gBAxCs>F#px^ zFZ>?uvLd%FH`Yg2D30h<1j#3L^qpSsq?6-WM8Egjob)yiTaDY{yH-}cZ>xXaTHQ(b z`u!iK`3Hmp%h608%0wdi7Y}Q#W=X5x+|E8duF<-3_jI@dW}`%-Y{vIo@we6-tmL~( zG*qbWr11TSeQMX0J}N8IUr-KZ1g(~cThi28qIp_$ zgvF&zRy3N3JurlJfk*+DuAG@H3vCew$?7?a4O~rh33%PZFLKG!U`kpsXRw8%h--i5 zY2W*faVi6OZO6nU<*UvMl)et}mxWR&2G<-=_DSEFElUZQ6ufaTe|k`*p7A@+Ds>4%BAj>_2R1?L2zDiji`A zx-C+Erb~WlM+fze=Lx0k+(~Hg!-(UJ4f>X=c}`K^MrEcFh@bP+V<+$CMP^)9P#?%* zdoIo&{`Cajd^6>=5-seT2730wA52XKD)}1MQ^Pdyw~w(m?8($04i__?^N3-xs~`}t61!JL!ZIS%C~Q@ka$ zhmUt;rujlAzpUV<(_}r&B_2rLTs47lEV?|52zBT1C8j25BIFb-v=M!WPCgbFXe4GV zKE1~9(-oPGgNhXGuSS>C8G1=)HAi*1DtyFW}Q!@_p6+fjH~}zjQHZ*X!7>Ywdgc8$^!`} z(-%8>1?OD~T&smb@5%Pohu{4;Hd?5e!hu(eKj2!4DvEx&8GrFKvL^3nj&Z$eX4?LR z>u;+Do=RlKswcxLSOUR*qc^hWZUzk~C-oGT%|p9^>0LIo$=JJ;-Ql*I-gL!F_+=(k zR>fYSG22a0E`Ha*Dez=f+0F0ky}=7=5SWRb^UMXztMBfu6wI0I3lg;MUrmIfcTmcc zS(NK?NX@S8G)htqY@OP5~wb5RJFfb)(MzVuBb34id_ z`*t*u_QGWQD)y|EdLqEr3NU7Sw1TFKwk}F++RqO@eo~7^4#n<8^0NNzh>n7+>B;L1v+H@fFjV4lqyeQOJp zl^*Tg{}Ij^ABHaJIcY2MwZq!}tow3z=UklfgQj!J#nb0oh+hqIW41L_$c!lyrrntD z;^h1n_z&m^#Q_oii94|~BjTPYRX08+jq`WV{FQKP;uyxyD&fCmnw-~ zHP3^2!9<}Sm+fyV%Syv)x+D?V$!{2K###kUy|397M88;M&yWaIe?^OJaS*OG(DO3# zw=io)gQ`l2r9{Cft%dk@LXLyp*HV~iF7Afq3iaj=&$F7txs3Iy>yGQlblvW0yv^@{ zC-9ivbl%ma!W-2mWi{g!64+BT4e}j5jK@uo#9Wg33+#ZTmW9B5>Jr{KRK6??F|4g9 zI0ycAy7%0FF~$~E$E3yU9?WK2aGG=AWqo2uub}qL)x04TL+9F7qssIRV@1$vAT^Gn{GX591y9R~O~lD-p~n%2epIV zRR+uTze>s%P5DEj_dUo$<3ArspH^sJ9F(wEdtl1D=WPP^Dqpw~h+p*Zj2DtJ?;o$? zD}orSiO0bwrrT#HQBybcL#*8H72k9>$?9#wdYlrK0jF%+{?B7JbAuRbW~~*c(M7pW zX=-tU2h;iI2vCEWrdjN_5p1^codvf;eKZ(fS5NW*2jMG{;Yb9h1@e%(Ba7H$rQ_q( zZLv8z53RRVELeW{wMPJ~foaCc@FyakH#QRZZY05a37c&OFXK?_gR#%VdtX49nV!{1 zg}O)0aSX6c+3hx(`X?M!jI@L#d$c6X=MU39vG?7lXSq8r11n1|uz9NPKlwhn>`B;- zeJY!8=_&WDC!QTVcWUN5_V#?iH|;4DQ4phWP@KXXVMpuzSQopgnS=!LH z%huw)b_$!(>wf>79ob~9lyzP6G@CAK7T2cE)Z~_zWzE5y$ry+=Rc(_t)n?VK2GalD z=H~LLQ2cZIGIiG9X-6HXFWT?}yfj9a7m{J{FFX&0eDe~HWu;WFlW z;V4kQ5iDJbxm#b(?ed$6v!CdkgXq~-{~ZD%M_)u;S>6^}N3Ei{ck& z{ACvc&2VX-ahn5R9B*ynN-!g!>*lfw9pdNCw+!ov$0_m!kPlt_g)7fEtJg9JA}i}E zc|45gkL31zptQ98fSj-9x&K~Yd@<9vn8;Yy)N8aE4Ha4nT|Gt8q~RHFS1w`dhY zDUF>HYu-_bzjGLE8IXyIo!P1%oK8lr?%iyF6!q+i2#z*qQ$#Pl$X2N78~^RA&~%0A zSzu$L*Yzh$VCsUY`+n~h7+4G03V9oG2*D_N?gy%8z~$E2;)NNNNG|`gnm0-JlMou? z10IKEc-EH8dvZ|?x$T#4nY+j|!nq7+S3o!NgI)`B^~iBMZ-{VI#yV5C4m}P|h>-Ne z%p{hH)hy)Ka9?Q^K*UufZJjOl#fBKr57SEgZAAx3?$u?t31Q@tf%s90;ka)qBT4LL z)!gjSV+V5G+1dl`*Pcq)pQFTO#ue5Mhr4#l-Sz;x^ZM1b%3G(Rr5QLE_7M9m)(@&W%Z;7e{0Fd5m=f1!TnJj_Q48E;Q>gAZ$I0<6pD^&oUFmujDtd<(tlBx`cgZ9#+=U zXGfq)T%$&eeDxegWLeQ$PMGBs;)|4w)!BZxOlPmtrk*mqIZ#B4b=@ItQCuU?T!O9EJTtzMN{?r08_TlvB^ z)f&K#lQC^Sd#JIG=Gt}>+dr0f>m8srSlmglEPPOZD1dUf^$e8!>BxJb0EaaA#*mMI zeL1Cv@zRkT>I%FI*DFobIpX^zr2J^cAf`a=ov~|5EZnbfu7AxI5<4OhpMm13ak^H1Zxj3UXfn zf=+|9v&W!^kpNY8==pRIlg63jLJ=+Fufu5X2|u#tmDI+Z)_qw z59Z{e)n>n4BGEQ;<2e5GY8Dc7v+x%Zo#hbGXM0}&f^2A<$1lx8?BJWGnAA&gn*qEL zR!wU~a!tB}Pj{6jpiU;#R40>Z=6(2mqqN6L6Ovn6_pR&}c;$3SA;uZyyU-X8kz3zn z&>GRq;S(tNGb)3sJkMByD>X&t%V-%moy#(@C1t1eXr{Xle!_LwjJc27{HTmvj3DTr zY}uNl)1IHllEE|4e(&%#>Ey~|-%Y6%6q_IOYtdBfvRe zTQ;4{$f478*3?Fv5ZD0}e`^Z94UYpMo}c$>i|+bh2EeF;nlA(k@p|gKs-2jBvUW~2 zAP-*SY7AIOXO|wtoXrYnwRk|z++SJHC$44ipcr+8Rp2q-OO(nhtjO>Itms{?L}XYn*mn)kr| zV(IC!TBF%LXckwC&J8@>{BZ6sy$qCx4Zy&x9{ycv6XnnCPB;AT|B;7iNQ~9C5l+0n z8Bl)G6p);uCVoIwDn1@%W9oaOuV~7;e(bhm7N03&gwnh?Z^CQx>%QUU*!||%ExVGz zBh4q3CAt)zqQ0mlyqBV&`V2KcDa;YPP0GVRdfxzzDJyzz*xO>4Q0sDjDm=+T>_s0E2{fs+?3K~DNIDhd) zNgvI9u0<|z$(1)m93;M)Ej_7t>5@2<0(KTqkt9Odb(6hwlYv#Y5Qu7QK6J7nzz+h+ z#5c@|vj>=jy7uxp2R6%dVl+K#vOFfZ6aENI$*C^By|QqW-qB;SbEW?764v&+dK{U< zs{GBOloK0qN4Uxa(cjCvHvtvE!KfuQKEqsDr&Z;YMP9I9)ZmKW+!ipTK0KSPB7Dm1 zW+2#Y=w=&E@gT#5G{9*h?R}nuRNLfTrmE*M>a`}=e_A&Yy_;cBzl9y+%Off z-1#v^F{=PU{#=h>u2mKvi=CpHY0vj|JS6^%m+xLn@u+kdxB@>T{^X-D=^Y;(oFAU= zlEXqheT#T1?Q7uI#LtIa%Xfp^KDax*&>-{G5lz?q+}2f7E{J$poO!v%K#>o)D*Na@ zs-lm&l?9VL6`xAn|Nf2s0}WCB&uy@+`zO;v*2J1=KR-!^26Nb^oZf9vG{!-XE@-S+B%(wFvc0PkLIrU84LIL&ac?sG<;66IGYLQ zEo>qG)nP81qD!ZOzjSuya)hxvGY$&qIqfAxE)q_9>L#7@6MEv#oa@v}j~0cS);`tI z+L|(RMQkI#`?J};phdqubH3we?GJ}e@!P>k7c0r(HKl&kbAgatra+R5jOgonY8GdX z8rc%B4_#4wY{7KLzgEl#%Z4QVlIcAJ8K4(ySlS zDkx7JN?6H>x2zO0Fiq+bR3=DIClOF{y?xdKX;RR5dJlHbP?cW3o(_n_ur zTxQZTZWQ}&i%>Er>Q1^mC4t%eSqRqkDVAi17g{^Y=b>W?S)EsKuz1x3z7Lz|XDOG9 zM41JcrDZNO;*eJMqgyyd*=?7z=LAh02DcFS_YcY|%H7B{XT=V*Wj&Qz(v;8Be`n?# zzF^MR;^d06TGSzMrp3hh{k((HDNrl?j26heSY6;!bm?Coe|mtgw)tw-q#Rkh8Gb~S ze8F!iL2Kb=uknCIVVX*>@dzi2;kPD*!*2O{Mf46kNrNq^2T^rH^q16IeMP~!bESt> zjNLuo)#Esp&u&Lmg@Ng9lZm>^={qt%axi~u0eG3`=KoNgwjbL=;*LK>Rfq}wnmHvl zqw;dX45E)hEv~3#+Eq@uQg3iO@8~C5W7kc7{L!{QC-HZ)vh_m>k|J!t33o9SPBE_cv&aR$^L(?C!N*{0|5H$bzp6j z5VIKZn4p^)0PUn^Mj`cJu*9UGVyraFLRXlZ9I#~?PI-BNkl_q|k3Gw&WhZCi3T83a z={K0gpQ@(t7(f1~$ZqqGpBmzJ32?=v-F2n+utyULzv@#{8 z@P)D7zby!7kW@{7hjwY{Cv%3uRahWAy6Ccg;u-V;LsOQT27aW_kob+Pr*4avdH|3J zM$+3ggaa>>p--`l_eU4{oBv0bd?tcj?YM4Y0-%!N6{XuZ z0h}d(WxU;BJOH=$CC!M3<<#+!Sbw?u*Bx>pif9xieD_ZM-){a@Ms6@ifCBkkA{gfB z*Kt1>%>s|;)vT->zxPD2AgReS+es98>HS;k9@szh_Kb2U{<=$PF0kI=D%-iD#8{n< zPxS`{wxEQd*)DN>Hg{nID5IpBtGgnbrirNn11$&%G@wRCugaF~sjFv+u`ym3jfGu4F~MeZKV? zRSA%rgqIDWdp@hnPrv?ItQ20b{=qV73U<#;Lrz#EPlAMjF{|}Fz#@jNzzaF4w_%tL zC^U(YGE)`pT!8S-fqaTZH{W+5xW#w9a@r<@Q3nh%_p%q&-kj+fI)QjL51R591ofKE z{8k_Rh;&p^CB$DI3Qp)>v4?6>#X!@>rQA8;*UBd;Xymv%Dt;D3MaR8V-+iULV32L? zakEWiMgz2|-IK(UJD3A1#C_Lq^R&`S={PU=^+EJTlhk})#s--5g_t%qlC+FHb>4-@ zs~R@nS9$?!MZJRO28L*7*7U+I7$d6c%sf<;mGIgKgS(OqNwKdb}#FGhVV!`9L|r45KoRk)4S&4v10Er5h2TV&(N&*t}*PuvESm?j%%9I*n@G% z>50MavnE0hdMhfa#)~+|gs>a3nd-h$tVGXT@5}L*%Q6GlEc4OC6aOJST_DgRYOS<; zm0U+3GH%1$h|w^_EdyD&+OcCBRVZ>LZxpOm#|MfB&5$n@h^SkjOpP=lFgf0+BGzpU zzrpReqIo*~Y#Tfh(+?*wKx`%+nrcpS@Qr_jJqwkUn4P7OTrV^5J_Sm#@A%Yieo02E z2Sulh@bXD^#?#c@hu+qEcd@=-ojq66p406fW_$V9Zu5){o7<8!8wfFd8^NA!IO(%p zoO}Ri>37<&TFir=PEMC(X`jf=gSx{5bho?*)$WXOkEteV$!N8vCjq{a_W)b^aIVP* zMJib7%lqv^?@!I~*>&Y85Mg(-d(++esM5v? zeW*2M>~l-L3SRrPaZZUAaL2L-} zCZdW2!Inp~W&sPNbEu$Hb%DMl7C2Z#q*U$jE<-1r)Dvt0pd37ssn8KBPu+Sjv+Yr} zdWQG+{+^~w6bJC&j0~t&^R|Zp{Jy0L+4ggB7o#;UAA5gH9 z?<=lR*-?hqO*oAJjTzoQ#HHWKAL26i)55(}(V%3KHfSw<#+Ji9_L*9~_9<~ze5z15 z1N3MDCYFM{du6YJ*AW{)<)n-bhc zB+mD5Yg8H%G9o*hV4l5d>kgo?X;Ce7=Y!{Jx{j*s&$73n zePk6>rt(5AMw6XG$wAgf*){5>v+vv=PaEfBuwi`Jr-dAdp7NuBYz@WnJQ&J-&Ku5f z#dj5_*K&TF`RA3vgS`jLps zG<*ns={)-Atf2F77`8e(3yQkAZ8VFTv%5Jk526embGv10&-3F%r}Ji~Lm(W!KQfLwU2%Q}-@t;wEim;K_}dcEEs6x3aJKveo@5_pLPIHYNIWQpp41q)04z=8l!|514& zKhWHW%aWuo0M;k?$_n~X37zx*0zzAlo;sk2oqyKA6CW2epz>^!ZUk zIPDp};zuOtu1@nxhXYD=`n@hCLy|O%(8i7WhfHWC^4)Of%}UZ!1@`h-4vldte+giA z8o_A>I#d<-vY^;jQ>Q}3yU}uiIXUR@(uIWPzJqC+Uhp3M#tHe!fi8g^f~u{YhbA@5 zns`tocT8QE;)1gJ;?xdl7eG6ps~49<>%KqaPk72Fea{)#+9g0@9<=RoWcNQe%;`yg zh=nFtR+PJ!ShJH1{a8JZTj=uj@3USH83lumxz4TLQvBXr*?r-Q+YdZaK}IJ)T%{zxHW=)QQ~mtrvd}Ww3SO$#Re*8%3}X5W zZYQMrC#CvtH2h7g>XfWkXN9H$D3s?G1ci38&&ff`YriJTObyGacTV!)m~Ic(@0U0d zc;)Xr&pA}TB?&tbe<|x4WR&3KK^hEiLy`WL_~HBtTN0)!FPZXebAZkh)ek==Q?Pk2 zeVq@O-!9ejqiaP4-O*g0Cn1_<>3;d+ke(EzyFyF;meZp4x+-1aAj3)BvhYf*O7%P2 z1Iw?<3G}cPY@`L9J$D}1V#J5Bl=Ck6R=B-UCqbaLfQwbWnuC^D!SWms>1LODLV|cn zc5N1<@#Vh*sIcz&PH5YFH_k0i{MLv7CdiQE#&RXw?ojBVC%=Ip@y^2_vUdgV@?t2W z==erKC1;cE$plSxEzn*1eA33{@sVwVc^d>?rNY1~ERQsEQM2=~SIPsZG^+ug)EW2{ zZ3YWD{v^%G$7F77e#xnZgGi0hKu{|Wmacivj!(bwk`ECp`*)8d<_%_Aglgk-E^c9I zmb%Kf2uxLqgD4Y+^i_%FJlvWt@+gz`FhJr+4&^@?av^LY%;m)1^Kt|l0NHpoA@|{8 z9(yeW#eg(jh=-SSY8DW-Epbk}=an~^0HkTM>>9@%rczU8Axq|QXI$@rI%-_LD-5qWTyb}|lG#`Q_D zPY;0-`NHb7pF4_KOYIeB0 z5UP2bubar~c|+Wf_k$^S`hf!cY+dBZ<4K~mqVnO#L!vO6$fwtwE(6$*Q({+De~RX~ z*e{u9SYVxa)z4-Cc4meO(`b`FJ_iTK6uO|Ko$}ffEEb9r2xYC&*a7KkwYt`xR{Qx7 z9(WMCCavzX!zjm%>nYEWHEkou(_&IKmim&+FQG1i8v-V}Y=4Hi}Y?Os9#WA&WRC3C2 ztbIG|6kpZmhVKC-^l8GcpiEAQpl-!2VD7CxSzhI+hu7K6?O$FJX6`=+J7D777>(u) zU|fMf-m)`H@HruE5CS?fi{{I9T=r*{SJA;>glWyTJaiDvw~yv~eeor={fQ7`oTI%h zBAk0bC8ON7Fye%1X7KoK^q1$7h1(J^#Y+KPOjpm|N*>_bfF^NBmmiuoGYI$p=Kf_;E~KGI3;0 z`)y$G`KH{Gl}aWC={sxX^_ZzLOSst=$6I$!?cVe_vqxF7Uy~6KKPrEC@~x$46gQNY zjAo*8gT&+o5w?*MrSyETKIEma@1t2Yu-0S?W=V>hwa9mXMnFX~egJP?THJR?t4B8? zn4K~|j9auAghi@xcODMD1G;=#>BUq(il1l{HBJ}27V)}bp7F~aatc`{DPrgm1@3Wp z)^ff=W3{$*VEDEqpjq6QfH(C`gNuE+3^uG7m@e6ubrv6Qr zRz|O9Oj0Yo&bM{0O%5(czXo%CMtw2VyOOcl z&&CHag0JcWSwQfF6;^ip3EE1=uc7$OX5gvu!vl}oZwo)?9y zu=7%(`~lFwQ?MN)WNvQ}DtSchy+)TrAtym#_8bNxp7XS zQuK=XNhdYdWB9}-PcIIyR#Vs@j|xw?7vg3>q!1VZEMxPX=}+~EcV0CE75NW*X~}Tj zqKO%K_K$Sl?ee(kuK~=d14EZY|Bm9KIK-6T_J0neLpTm8hmkZhT`(oJkVV1_zLFTC zs2KumJ*Vqhn!7+@!P3c+<*PDT>CL=!Gw-(=*-YizZmS#UrSXWBgUxAZz)#J73gAWp z-wbTBrxx_@hs%|lUb9!Y&bEu*yKY}-|X6b3%TK;FL$r4fpEIqW^-w}MwE?q(n6rBSN%qdjrB2Jh06=s!E z>Oor2kIV6Krej?f`47+i*pPTEkeug06!X;4otoe2X6TD)7^F)vpS0G2S`AY5a!pr4!a_11Gr7 za$7DuMp0#7TB;-NfsuEs|4A61bRyM5pOLr9Bri;fZ8Cy7EXqP!aElhrJ2p#r^}i5n zw@m(iiYY1W`r4@(=tmeQBF(2@=3rRKjPJ+Bh2;$H7dzR(EMo-nQSudm(R}9C!|B3GAjjv&S<%ANZt{0A^qCb zNauOd1DDTwLZQTMKB9~Vtxc>QYhSrk#ZmA(HEZ+%|H+!G+fFp=wkEfE#bN9hIAPkeCbKajLWVEB3Kz^Wk1y>SzE6q!Few;x@r-TfT(bWtE$x~k!a?^`k0fp`=X z{uB2KXkF<4wJt=AWtmqNsc$1bp5hEIZ6~_6Ve8ff{3KC;b&Kjn21FbTUH9N}>G#xr z8owOHF!lEK;=SlbDle+lTf_IxcULSUzdJ3`+%!;BTlA?Z!=BYdX>d|U32cn0GNp)m zRW*3W9};+5Z5a66KscV*Epn+>(TH#AqDu&W2cl1+NRZowVk*ND_5&k@)M@i79FXF) zeJ4Y}=c`4(0p&RVYgwuk{>I5Sd4cIIGoPnds1}5phqPod^?Tjysy-!wtB6a+3!bV>Jv+sL z=ZOrHPw^M~Bj~SG98-zvPUv-e84zi;^?hbM_Dc2S!^?9oJ~l{P@JAw(;rvXgF2iPD z4r8;EfxARMuK70xx5(2MHLLSBNa(FuwSCl6oL zYwCO*rHz_p?+*97Gk0B6EV*1JdugHDZSL`AQN9ovza(sE4je5ey(&Fg0}Okr2sB!l zEFodEGnMMIAO6hw@Nm~U-J&bAEp5Vq$8$8B?D@2#7+VI$FR4KXSUrDiOf2ga8caD( z|0Yb*jJW1U!KGU-GpfJ~9TJ6OY()k4Q}a2VAbk9R3Cb42G86RZ0NAVcDKAcFlt+qxoJ zT<89}fkY5-bSE$VZ1SX}#Y)i_>gGdTes+MLVr_wew?lnRf>=k%IX)uF1rGhu436X1 zU+1)bt+@zbmvY#sku;hpec62`S4CbvE|(l2H8~AOGQ1RBVO+(LJF1%cl1rNrj~e+c zY~Gh`+)<=9f+)oW_iOKyA)Mg>t40RhVS#o$H}8uO z3%>`t}Q#JWI8(VoG8qhcqjBS}E{dmiVZVN%xna2oIgWdj)<2M}aTAprm2UzMG~RbE4t@hFnWQ6C0JjPG?IVc`Id+$!=h#MVTa8S zsJpTA=z2$-<>nQZA_D-a4a8(+=3lB%SF}qng3CI%^M%YQrHqt(DX(@bH3~}D9$CSj z1unKWzKqjBphEUN!9*g1TkbL1ppSHf&)eLoL2FoJX zx9keHCsql43!)n6-toN?+C#!l}Hri$%NDI$QaRzQm4*?Xy~O8(TqE8cF4{ ztF0i`dJ&%lR~Nm~6rI;Q&Nxjso$}!0yyyOj#_QVyn4N+}f`5B`wZEiLb(v1?w*0(` zuw?MeS7fs+Kmv3Qb9aR)9NxJdFLtul>m;+AM`V2Otr*_NhC#dX7iThYo4(U-rfF_X z6kGj=2ImOi(&X!Z&)$sz@ZEo%NKaRpGu}Hg68-p$i}kEBz=7G0-iwLv?awCc{-Qj1 zi9)oznG^v9H~qUL2e27rKc>I7UM_QIC{5nyJ6Ril5~$-R|4=6yGZLJ_5a}5+@C`DQ za{)0FMxWb1wt4h5sN~+zPl)jY@vwI`5rvl6P%CEkxXU#KipHT3&B!C+>WJEnmtey@d|_>K>3p>Qi4Nv? zmlWeZ34>}jOWi+zkBgz%Y$s*H6O*mdv-U8;%^W827i>Xev z*LCUo=0V>7WBTze33jM;Kr!ZoJ+fwX83iOkHPf#;gGp=cK6tFcMewyPNDkMUuY|?| z42vGpRee5-kRf{V8qpA;YdbGkSwJ6YOcGC9cay@GqN zys_7xOAN6+Ud_V*wA76<^#g+;OHxG*2I|9roVA z0R2VoqWaTZ%ni^KA5in7+N4l84`@JHwpmV|Dojo*t%;n2k~y^;$Bdon|K^u*}R9^R}L16vLHiY=I3d)&)|!?_81G(iKoE-^P6GLSef z5F|6TabjLkIT$?99hO@3qiivlU2Q{ae^;Kn9L#E-=>=^KZgQnO((@oXb!ARzD4l_Z z_hSV2oj(am$~Ay9kj~QP zq4T}jAT{lS{NU@=U(Pt}fS$RW`CE}qP*Sj1Jj@*0uK_Z;`EPuq_o24IadY-PZ!&xO zR#U%T$zNpY{0aS_Cg}8v5<3oP&wtoTZnQYdT0;-(i19;g5f9-HU_A?(Z9z zl<{;x$$D)6J&K72dkt(@;V2&90{^V7S#F=+=L#>b$K+t`6sY`@%w5;jYuNlaFGsHX z8WQrb?Dli5R05>CfvVq*ul=oR@yx5?jfn-5XpQ$$+}o)pDpR0#_oYefLuPpk=L|~i zdrX1nr@A`de02#ScV5W~t7apSOX=U3$ij!o=5;7e$)hxe-};&eGKV98?l{tze8i2G zSRA$ioAJD2S|sD((t*MyVWxoR;f_4w5E%eD;Bzf28VqO#nF5K3g3fRenWcuwPqB1- zq7BAMT(+*bx+#O3;hVd?H)w#mQm_7O4>1-wfuG^ir7F9l+OZ0&V^VR+&S@x0>5oet zvmhzhuiZE{h#k)cQmd0`%T0oGvKMllj^LcjVp}}k4zTg``1uXI%7b&fyXff6dNU|J zO7F<5Jz+h?fJ6&ansu?e0N8pvp7-J8Iuxw!=a*5tbU-`aZM5EAQXy07M!v`LaPmsx zmEZLU!B9OOm3Mvy8M4MpxL1$P%RFj2Bz8(mqqBiJQKm_D{s+y6`-GmyG8cA! zR8izms=+8(nRY@mB`(!y2TJQy7eqJre8g?78W}eZH(#Mf56ZL?hxgtsK$Nqs?ac2MML?ME;aa$!&JcFl;6j<0~&kXv|Tya=9gZ3X(^u4^)4 z5?dwiitfi#(aNth>dpY~ny*%M@qtiTf^BF=nbGQ!N{X29JKwK9-#{8h4g2wkD&u^z z@YXmZcv7%Cph}`9=r(7dg>hEil2{{=@DYMbH)c{!r094}KBSg6)wTns*#Z=3#9J7L zK*OI(9Lcu|EbPZ19N;57PpEtLPxU0%(%E<9_{)l`8hr`ZO`Uh8vlvX;cMeOGLKBJxojc2lH?_FC#-{fyFNRdb5-r`e$5E$6Yzifod zEg=rngH_2zN2chEXi;yoIKnGV1 zeIP+Na~=l790>y8BPJzCe3QcZc-s?`2`x~*8@PHQkHkqoqjJIRQ<3RckvW2QQ?abp zZ&6<-y9Fu7I!F9C13m7W4L?30of}X1>_#q`Iq}e$>NN^V-Q49&aG-s$c1W%wN+@{) zBTiCX_qi?B)Ppn<-nP!z>b|ynFC|+HO;4*1=5{xWZi5Pp#Uj$S_>w=uv5a*e+I)G6}y(t86QW53rLQ)%42GtJ(I|33sH8cv8SKRwMVACUL znc_}DW~D(kqvk~ttT44(h%@8HP$JwX@(ONlC92_y{wii8ZTw0z_Sht#@N4TQOuQov zs|K1}3e7eWh3-@XTbR%6($?4$=UzC0if&Sd6+-%Om#!W(}Mu-`C6;NV~EaQ=Rue4Bdj7k&-#@AUNeJNjLb zM?8M4Mi*v&hc|Nx+!GIBV-~nIicZ6y6(L2i=VZC@{11hYiM-ynL)%NuHUt?EN}VC( zj#GOxojxSve1IH5LhG?6*|E8uySsFK#uM``lTkDmPMb>q#Ry9nOrB z4w3hl$!D8?c8?0Wy8$`G8>C;rUi2sAx+KIWc|%x|)AfRr(UW1 z--;o1QCnr;D;r*17EVyj&(E+6m`T55Xnd^`D>goM=WCytF> z-|%P92r*D>->ndwRY0|kdpx}NexBiJdQZ=o8{$5-(@#6n=`+RHTE;h-)?-XR2q#m% zDj-z#V^$#p2)?^g7lw>M5yNwbq#cE$TRjt!-LrbqKOP`2r``C~IX;Z=P*g|c9M`-< zw^1~o8C|ncHb(zeZzy%|2_^MKozR)Mp-sh{WNTEGSnexNjSeV@DR-Vzg^TXHr|kY* zxhgRbmH??J8(y~?AbtY}>@Q-raVxbyqZZvr7gG8ueN5;!NItAf)uulA?K2eqG)*Vk zysIQ~;EOwXPW0vhmjSi%BGtwRL)tEaYXNrbOX`10KK9o1V3qkLZ_Ie=x?u7wjgC(+ z(}Yp0_t`wtca(aZXgyE20bXr}tljlfT_vY}S_P7^N!^^S8gCE1&ksXhj7&1L6V!6nPw!X%tw4|^YEeqC~8+4ZmrthMgTKv8`%3U!8oL7l7J>Tk50QrlK2rh~u zQkH=r`;T&DCDz#XtiT*6G)^z(C<CG^`jqe#Vv+?f zj9bF@_(UYl)Swz%kBDU7bR{T7XzpfS9G)vwyjX@|jb32@&Mmk#vgO5{o zQEF;VndscxE4ae6{7em?q~v$l5%v`R6`uj6$dddid*Vie_P(>`EB8;)a{%^sPZj)G zD~f58#-2^q%N6LB;=eX2&;2PY$E+TNy}tz{CkmVnUoPE#eY0mF;}5aw8>2YpBei7r zOM=F$^oXz`cE5Urgn@|Cs}$6AR#e@j(|C!Wd9Ew(M_2xZFuszR2Tg1q9~{EUhtGPU z(ax6zSg%4@T6sfb8J=Ay52zn#G0^mnd-sWfq}zvRjSZ&HH9>RTzfY@tap|y8!?AVa z18BS=lrINO5nir{J z`7T#{sX8{61(#e}uF&6v(EmV|7jl>6c>59Sz%u9Roj8vbEB22>Z(wU@KN*Jj3xTFy z=(|^}kG&f~1+6#dd1fzAma|pyV$lYCUifW3vj|LE*$JR-retJmyv0wPCmrBa;LA-> zu=@UQ-Ck2FkYlr1BWk&c|~3v)urmM2}s~j79yb$4O9Y27+v7f^@HyWl(bUjL+`7 z>(z^x^C^gwmp)(KPa*0Ilp078e*#j=&8{85@^gcCiXY^!1ILx#6;$9hZmKP@75(>@ zlVcn#&=&L=)V_oLTMn$%0i#;V&Q0go?E9ZcAiC;*N&WrLZU2iY`|~%QUQ$)m+rL%+ zZ~u-6>&rtatnJ}femso-=PMFn{S$5aZ@==7?%d%wEO#o|NY(n`?{a50kBNzC298~y?+6+wL@#}&;_M%uv_6GQjCQEef2-T>Wgfe z0;~NOWn3>2VhRz5oJl~b^kLz1=%1gCH)tIJ{87V{15Xbd3wruA0flKjv%j_rk3oUL zY&;a?%iYNq@{@Xl-Q5a@lwlzEKW+KbLBOS0&U&0#Ls%=j^LNtpfBFhuYO?w<_3mdL zGr_mjQ~ch`K+vlofO?AK!6a64tT5!f2NG$Dnb;wKp*x`t#^H%jQvG4FCpmlD4Jo<` zGG@L+t5U^)Z-{AYL0eab;I15DQ6u#oHH6vQYCch zmK-y)$SoMS-^@4S0Scl)v-9hL)<|j*7|JmLA&?2sVXCAYfDp63D_FMWypUBQ5w;WQ z>87ox8!IASLGID;1dc!-n- zL3ok$%hIyT6JYU0VKtJcYfLCG_A)7li>(f;g@ebnzu%&GA45ZLR_xORP)J%154k(o z34T(O$2|aRu{{=k2T+hcVPuk#Es)K7$_u!!Nx!>CI_m%Uwru)K$zW{@Ju-_*H_#4| z06vpi5BJ4buw%zjvM?^!A-7ZmY&lK*vhD4 zQE8blHQBUY^a@C-a^8Qc?|6#$KboQ7js1J)@7I?PO7HS1c^`t8T>7iNy#^l01!Cp zkCZ162{i$No5ca5fb>aR1(U73&}-=K2}%@ykX1(rK)iOAGr_0___pgf@sP3RYGKV* zX~12Z@*#PFdcc@yp>6=IvaHY6P+n{RbWY=ehHvYel}n{iIY}RD5j;$lyW_)QD~&we z^MQM!kYTGZkcaqb-3C;fzY3h=4SY%jJIq`X*d0uOxML+l=QQ{o7L9qlW?m;TT!vdFP8Za|77>5`eO6p9yY~@EW)uNPfxFq3~Wvz5<4LGstrco zx@M3_B7p{{kO0Iu-atS`vXGT!>!u+Shg_#S@Bl>wZh=NJ50IezH6M=SoeWw+P0;W{ zmUh)^IoAzwl8(EvI*}AO{}Sf>jVi~1MFJYPti0o+Bo5m-s25d8cXXntIzVyR(r>mN zUiOpY{VS%8E-qkaH|i}r&^SkPe2w`B5{xkF6WwAa#wUVC0&?qizz%IuOYD&7k!7NA=8Fn?W$f(ebgAUK7hnwO7o=`n{6-01P-L}MJ z4g|^RLg+tzgeS3lsEcw%u^3`FOL0=m=Jc(`NsVku;cD$lDr>__e zt+W1O9xMo&-XRzuVq|Ka1#iboznNNJdNV*lR`${`nn&V<+=gi{`BrjD=M~D96Y>S0 zeSy`mt^*@YBYt&Y{W+9HD*pPyOf74uwO;{1(<+iY)wkY$n!M!9%l=ARt957RxriYCMQrWZENz>N@1y$KuSjL0##d}XE zF2Gs&onEylj`UP9C)dHSSvU2H!F*f%Gw-?Q_|t2V z)AI1v0dGZEcQT-3fq1ONp8&_h?eAI=n zZ}@d@G{?G8YSFXp`McpAnw;F?-*>G{0y$E%Of5FCQ$u{f-U(u~pMHSNRvl3E&WvK{ zO>A>6y>d>%5x2&EYT`BoskOC(tMlt?-ly15UjLOlVf`)p$vuvJ{Z?eWooD>}UQWf` zQ1(M5fzv;`#W&mrGKr9JyI!wxTUMl2OEe{q2fzL{Lueg*lJ8Yaz#p_FoDLHaZPqeB ze+<9z`Wyb%_@t-!9b>SDe=}=s<5@q0_+e0_t0e z%Ugc6Qa^$#f*GchD&O;Z_LBm+9$91eH6V(Q9&iFrbh~7I`B7a0HI}o8BhLeXY%4BZ zsthf^UG}JZ^IXqRH~Ob*ce2aR0W#|n%i-hESU+(Sn7ql*o+pmasaODs&pK=CPa8sK zu`eLDF=z-C5SwasV|o;u-1|6_gU#EOvUh4KJ*V*lfwi#n$Vdb|DJoh9nvia3{xsfi zyAQ#pG4u3VFfy2MpwqE3mlR*ZPxaB0yEcGgSgR0Gj3Ij9|M^nqUr7+0d8*%;L}6gq zH{eLyOz$tE9cw${*=|7aVIMloJdL@hB!8;8cU02fxPZ|UqNDCCmj$mtoFyRT7O#8Z zmm>0{?I-qk<`GibB;sEpoM^-&Uyw&V$OM+Ry!9cS-F z%Xgics+TML#Pb)>1l}}K0!0ajjhE*24|RDE3Fy+rk0+>kIpFZ+q}djIZ~(ATY4>G1`3p@e%vDI zKdgD4Uzh@4x1pOn_Oib#>?Oh^Ae$G)CwiVCvFVr7QZK3}@_~?MJquEy%FcPC;nAk% zk7H#=Dd9y_K6`_)&8?!g*%20PcbaW+}T-e4*tNaker>qD-Zn z5|go&0qNhd0y1R8-cb6f`)2kM z_5|WXzKL#sQouse0jT2jTkx3X)$ZSS#{ar%G(I3Id)22lHF@=n`UM;I52blCNu3s9 z<<_4&D^fdGjS4e9Z}hf2xn*Pu{$m>U{7Uy#1^?&Pg->(&65Lh{!P6U>lyl17E8*KU zN!L|awa{_k$P1(@B5V3DpkCZppc~kR=QLfVmhZ1o5eXPw!p4xc?l?pB-{Y!lSM? zPj%fD*_T;>a`cxaT=zFBM9_SL{L-ApQ&6eBInIV;B-68E+Z*p3ohLWu8-&ZZI`}iN zoDAr@xE>PwCxtACZ;ug=o~7KV&P?V4mfo6DkQQ&rirnxxcs=}C>;Dz6;?roGGjj0P zz?w`7t*RUHfNoe~Y+7(3Jvx0EDpLycl2zP?;&8a|V#V5$D z1W?>@A<1D84Ebn4Y=B51WfnoVm5>t}bQ}=Y^;c6Erw4l72f(!f)Z&Sg$k??pYrp1w zc8(e?NXOJsRNy(g2%Yw+u)L;^qsJvL+C%YcUEuER07?4W$e)5bc0Hye_@5EpN0{$- zWcow+)Z&XWSTZf_d|gPnC%dW9G91>$FC28g)5w&C#UWBlKbkinlx+JKGW_44dg?Te zkjBq_$XjH_^%VC0PH9nLHKN#6n=nvJr7E>+zW&Dp4DaljKlTMByJJ-1r4C?9-VeMC zOIIWC7YS03>B1&7C^#T=Ujc%T+&sPbZco#dUIzEpDi%xU7qA3bahk_yP460li`vNy z4JS~csk$u*#5U!=zgs#C@Kh7^$Up@PZSY4&3|ikNYnu z7y#EPOP5WMB>QAldU>96y#yBK#`j6)tPlV69via(tW8ho3%h;7<+EBhNP^D*lSj?6 zkOnOkZ}o4=OI`wHIRGu^7YPqRtNL(QrRmJ8a45YCzOjNLR_#OlhZ~RVczh&OrfBSL ztzKG_8npvV((kGc;Yr0ws9}XyzD3tUVx0715@ezT%vyjiaM-_=3jyizTkY!O`;jNo z!04X|ulnpMt>%lOH9s$iJ2^=AIIShoM1V|=d%2-`oQmH}U0MjLv%nqzA~IOWsM&Ix zB@rM8EXp?NkBN&nA`s9Bd4ap%gjoJNG)eM)eBK=X(7r(ZT-nTrv@6**pp=XP5pW;Z z@-g;J1iC>QKJW3F&J$klADh-X)l#eQ+ptwdx_+Hd^=Kk@+mS7 zC2e|o&h{xdUcSj#z};tg0h2$|15&?Efs+$Zwc>n(1qd!^f;6{NX#onAj0hZ@H{oi} z{up_n;Qfs|*u#GHT)YC_Jy)9fW3(uBZYN}tOwjD$=MrR2Fudh2m+>WYmBI8a39UOR zAt@_|&$xijU>(;2j3$GH%4FjSF*$8c(>V{A?$dbnVBsX$Q^I{yBp!h`~uE4t9;-Ab}FN7(y2%GTY;Ly}h^sh=~?1z3VX(EPrD6*vDOb z^YMi+390^B^FyNNU)1}Rj5HtLKnZp15#Z1@%TA5D3aQ8RefEAvdT~(c&d6Sly1&p2 zGb>5en~(HoJ!bm~vP$wKzfHaMI?hdK;JfR7oM;blxeqJK&;1E5YF8;+N~cq*p#X4#sU#vgikHaaj^9*bHI@zg0p;&%S*`8 zuJ#b{Xp?Qvr!>(xkX1-3TMvUz0$rU#ML<`5-4uVC(k-jDFW9g%}CT~fZ{tM%mP!qy{b8Y}(z5ZJ(w;LA>T!nKC$ z(Flj(dQzJ+e{7jI>$KNPiUje<1%J_v@QwvP_q547*G&kY1Yymqxf)Zdd*1oXjq9t` zt4=>QIz70#Z}j+9ADyEI>n6I!zw0(9qo+>_G6kH}-b$Fr#w4PKx5&K#DX` zjJ3r5X}2YU?-bBk27DpLZ%u^WkfVvjx^XN*vHb`cyH|2)Ix3EieZ?LqxZ&*i-H99t zV(YcSbA?|rZHN?OMS8xx=zk@P3U78w*v8+!@ug{jj`ZmWe%{i3p7qUMW6p1d6IC3& z78K53lg~KfT08)&r99rn(P#0QssV&YwN~`DWo9>Lv$0+ldBLnL)xJ)Hue9CrTq<|+ z9r%N2cz%ST^~hNTDs+zLdpOQ?&X*e#l|AZrj;&OrG$^x>4tRB}^ORXm>0-sBE3N|3 zcdE8$d)0B&Qk*~jte{gSLim|_z~`Z&e%!PLo-a8EY;{{|mA{-8$bAFOuafz)QIm8G zO?@+X(I!rScRNNXk7PgDV?|r#BC%vRjUD)GCJIsVnW*Lxym>@+j}z@_uP2K~(aCn{ zk$36cs7Z9&oX<1Nxts?+#%3-#nuCpWw|f(+!gsVE%U%9$E)qk?>;~kC6PKnSEQE~= zYOGKXTkzgHw~lusNP^C<@RBHtI=i^*m@jUfab?=%I&Jfn{o@VlIAI0_8-P3|2KeUE z+e&Jd-MQ~PDpAQr{UN-dbdCoNt~;g!k2h(8uiz$*Rv6&y8KpOT-CPQcC9^zsWCr}pA!jS@_JidpYR?TDQ8m5=9Hi~RD+FbSbMh>ufgY&my|6c6 zVCzWPX@1CYBgwgRJkW4HH6TUYiM6p=cq*<#=p6m{(t?dU3?Ol+eIlg!}0B0lYzvIAMrLf$c7LJ#HJK3uo>J z2ssvghx+qn*)YkU@RqKzIemONG6ng8Wg|-cw%|C)YFpd^&o$0&>cfqKa#Q=wg_y0< z2O>7ThD^vzIN4Wwwq;u2UY!GsxCrnuzIJdEaj*Mpb^PZ);xV}G3`;W2lQlNN<;iKB z?PGR(V$)RHR;D=3m#D94yOQ&ngo7d7nD2$QI$XFe-3j|r za++M3y7(mauQ8!2G87`V&oJzN4gBmS_ovSN_yjWOECOq1=q^t{l6VzzsqF2lx8=ZV zx}#HUfOJ3+*Db*E-3)cHobgq{vVYk_{k5O|wkz-a0b8pJEA&~VR|FSjl-r2L5G z>R`qeeX+sQt+44<;9J#UwusD{yc?K$D}tz~ZUI z3D9R)e*J-v=8K>;|DT`l?;loII^L3E5Ck?}J<#^Og%lg;6F=B5Svo+&?*~9IKM)5a zve552wTw~STV<;;i{VH^`xXFakxvT|oJJgkBtMqfVFqL;$#e)< zh`EJ)2=1K+%|_bwsDfW@a6RCK-%{LxR^&C{@XO3t9Ad2()pL}na@JWv7mWg^y?a0t zl#XYt`eC#tVvW>ojrfv90kf#fKe6I7fWGKG$EFjcs+Wq#f7XGE9%Jz)6~g(-O)y#m zs>dZY+pPtg!?@3@$8r*DdY`d)5Z;j@V2H$>C_H(eM0_5pE5Q2O7ikGi3v*N^xpE z9G!wzGxz(%e4_x`Ve1?I+SaN1#P{7TU-!v4XR+SR<7$`_sZuvZ;~jKeV5zK zuThGYnks6BDJJMd9_Q0WToQGQf%LKzEEU00#1!VkffJm2P^{-H2nYE!oKM|>b1C(^ z$%u0mxqdjLxtHIvqJjmH;uo3ZIX4pXp8Pl?C3vR%^2KNHqZ01igBGC@yCWo^`CS2A zH(N5~sAE`hj+p!&A|Fr3R+_RGB5ls6TX2lep!o}8|5t;pQum!FuvJBV4sl*FM4Ob7 zG?))uQZPm1rPcy2W8`=tHHB5vYab|0S09G@@UVdJP^zBzH&cPg-P3K!J#l86Z6K4^Krhh>Xv%IzMs=uvlYd zJ2sjM)85=`;5+d?kil&CP;L2Ol;-d%obaEvVS^6PlJ^0pf&NC1sA(?`5{tqibwVrj zf+r}&cp$chIdmQ(pmF}CSh$vXDvPSytVv*HsC;4`( zb+X51$N)^;O9JkKf=^vY>%BUQZDlhUXw9Ao*(T5;%qAdRP-Nxu3S$kq9H?ui!BV0d zLS9k=`iY`LN8RFtqNDqpKeZgJq@#yA6!mLuOxl=gA$sL8=RW?e!CFtxDrz? z**qCN*j+5h)aByZvtd$n;Yf4T>Jc^WWJ}5-VgwpPIbQ%BTI;ldwoKwGYyB*cuMWx? zy7pxHr$>I5jLGpr#-PVPoi-8U>hGAn7 zmO%Ew8{H80@o6A@=>t1Ium@);@LT@cOzWw_o}R_KaST{WDU0~5wQ*(uX7mkSAZ ziKFWA&W8t`Ou2nwC{$-p8RwI2ZLpSG%^(^Wug|wyzvAD^RB)k;a}o$H=<$5aCw8^m zkJ56Fqx>r#I%SNP3oX#;fc;@l%<^R**@dk? zSW4b_Xxwk5CUIzcSs4x4xV#Y0H6`N9jn#!*HS?ZTs}Pik$HO>xWN94R`vIqtaT;RC z{@JB+%3`w7cctTj1jozdH5)uTMa-D_?mZRL6ir--f4`Xjd|g{Oq#HIfSJ=WBm6CN< zLuxrRl?zdq>nhz3vRRznAciO_^>lFqBNE-*;BwQFnP@~YvfmE3ab$QQrh8w3nq7XH zwM3&tcbeUXNhvoxC8yW=`FQt?@rfb*JrD&4CCph{IYEDz9N!A2nXgpEZ9U(f(Pnik zC+)MOBV$$*Aa(iAul?skNu&_J!*$yPiZY#&VkFO}1(9egL(Gzj1c#i?bcQ$!Pn%TT z64Hh^U_g`23ZPqeI9NtF_%X70s7V>=U9|u%(-tvw@(`#5>p~ysV9l{^jdoTZd`0M_ z<;L0Uucq}eZUv;2n4nUKHJ$dVp=0=oH-}>w4~n{qFbvK`(vw}a(8g*2`o+Apu?cT1 z;LrukVy3MOb$9Tw6t8R_jI8ImkOC?1&s+Y_2f1?w=SoFNEu2k{&Nm|s4qZm)s+CU} zw%eNLu771eH70!6Az}kpj1itZ96hNM(_${DGr#Mzgt4f7-W#7X*+%eM3$b|z zU#d^nEwVP}IYUNi6dYEwL$ytVh0f4lJpl(r`5~tTyW3cHRV{#~8dt5-M3jbO)*jrL zad9CA8j2_o{JNyfw35d{XD_jg5gxJT@8i1!sYmh{wKMCBuhu3>QadbNZ%b3*Tm_CS zV`xvV;XQCreOl5z1hG3Ryjt3*MV_6f5H!rPcp_oSb$kmY!kWsNYqm}sWG2|#Y!VTQ zkF_3J>V#xUv&3X;j&2o>`sHxA8l|0SKaTa=TW}%3!OLEX<#q>5>y1tH7RoH!!h+j zXfaPnF1y}6EW(W5tx}b!uKlnJ%uYYlNa!fX*XS4aIkJPw}N^A$xg$O@QRdmN~hC5R^TP1C6wY|14Ru@!dl*~ z#>1;vY&osXb2jEyBv0*$`mzq4CUEz=m8ukzSZr3dt;cP<^wS{jKTm=`@B0|euebh` zU1t+YK`BQV6lnSbnUXVKeH`)fTh5TxZJ;D$afDInrU+lUSDY%Cu}l~Pv`^Y=eWiA* ziMD9LRCXNZ6ZT>&z!;S2$se$ONUv)iRI?*OGrkVFs+kk8I^TI9%s`LpK^`%rQy91W zgH8>bfn*c%=QE4oWgPf;JX7waH%BouJ&o`uJ0Zd@l5v>Jk6y!7j0h0LVh<- z*E4IGu`=JGUzl9bJXsK$5B(euf4c>+aPKp?ydoK#84jSm!6jthrpO-wuGjji*&I;& z$z&2bq-5_sI7cPKGpagYlbS~|xKfl+j&MJ3ewuT5R&pG%HEjbre?e4n;W(UFNg~K} z3`DK?1Es)zzOvT$HOUJ&d$mZy*q;HRTIX{8m3(lOeQUQm!B?hRA3E`!_%@OU*VTmO z)4P>wO+Zicu@0J5tF9~^+6>mT*IDLueRtu|xu~_hFuDE>Wwv_|t`X^wkjm1jL7ksM z3{({+pQq#OVM3AZsyczvi524oyU=mv(I~O@9r*>1K&~ydJAOJEln65TB||gI@~baDSm(5WjJ!H2V+8SB&O7)x>WPxnUp+pUsZp{;Ypo?#1)!;P8&r_Y8cwAt zwwUz-%s?59xo$DS%LaBP<@jy<8viY%yrf5u*SX19HXbhcj$HU?%VeikmRQpVFoyCUtqK-~hiPr>~u zH$QQB_gp^l9xqgT*@NEiDxfN+$vmMe0+|w_TzL=Dl=WcIX0%X?kAO6Z2eAiu(7SW+ zHKba_TA_zCO#@vrNyH)m2j01;q3zC2>`+4vh2*P^vOO90Q%SN=q;Zz5a-9saYBDUJbge#c zAqoenuCwMR=qd|I{V>@=Q3lTyiX;Ln?&BFVeUQaJF25}X0o^!op*5NLHgQp8fNnZT zcv%VFc$jYf9!>oR8<4aaO1FE2JvF1E$Jg6lS0X}FAa0m4os(`Jel3Y1D|QC}CwIdT z0AK}6df|quOe*?#5h~Jsuk^3CZnTVMTZ*}DW11J|zcs$IK5mg-ZvkE~5i!=iwIUGI z$e%Q)D13E%hG3_WW1s1k((*(MDwGjH0SvbMdvj;i9Z8L0~A9b=vsfNy( z+tKpVnx_qqfmVrE=@XmV1Vo|5AagTaQI6S%=oTly7-h<8_AA*fNCN^AU=&)Xwx*e0 zKr#I#8x9EWpUTEA@|hTb%!8Qw#l~E*F#+!pxBLi;fk0~b^ULf{13?U1aE_RKYZ6(# zH6|`JsL#>}@AEqJ_Gi135o}@6?b@jBr*pqgFMj>hjhMO4-DbGs{vzRu;)27S`XCME z5qcS)nyG;FnsJqWmXeSy$anO{9{+JfDM|o=v`*m|{vxFV)O@D_ zIG%WU{Onak?$cPRb42t;*0{?v910%O-nAdkD%rys9HBly05TqcjnZ4NU7fFSn_G=| zlZHdZ`spPSERw;5o2au#BumIIwX?Xm&E{HPIbx6gYvxaoC7P4nx~iy2;4 zl$dSb6aI&b{olXyf8WnvS>u1KT$lgv)=%@tfSKC@!#FvhIXZ8C)3+3))qG$nmA{Np zIexnlck9}L`B@^)n z>lA775;7&T0g!EF)ToO3^U5jPI`2DUR4-{pITydKsK~%2+?IosUe3OrrFXP!zx5a{ zVdUqvb^*Ee|K1Ols}&mBi~YZ*$PL6DS3BY@{yJE(aM{}PP5ZXDL)$()NIUJ_;^4o! z3Rpw!9`r`}yjC2zw%vv|%Q<1XMrZ`S(^5SpVbA6TPM@$j`peuQ%N4e@|8IYQa;{RC zh{*E!4Eb_Mi;f!BKOFl6@8ph!G4e(b98r4y`mYae9&@ufAIlSY`XBxh@2U8u%v#qA zN2Kq_iT+L!4)nC8#ez>=L*m7o^ig*MtMNW9#F_`Ttp;5G@JsE;#TbdTk9a6#QODyU zU$r7wCin>0^w%#j!o~joyM!dZ-7z)m%g+F<-QiTzceLBFWkd$359C0qM0twUrIB?UDPcKuI&yQT9F8VJ1Hei{IQ)My*CMV=) zA(Dp{Thu<(V{UdJxNLx2b;P~B`)P0Pdo)aFCx zwzaUtXHI@1g25@x4p0};xfNjI0c)~r9K}3_NsLHuT&`gkO4o426H}Z;H4Z!;+e^op zIgNFtFUx!GfZNrC2nw$g0c#K$H8O@u-%0!i%j7pseMD{xRa=VTP}yf1Dz}tm;OVF| zxRGfZAUr~5F>0WGmKqM07Ws-T6psGzAfz8bC+#NW-(p2MGK5D;8oW;Jb z9%%yY>%i=X>$SbgUIPxvkgTI~*h}WJe~p^?gYwzSqV>*)4aguPQh3kpPb9;_)b0kJ zYQz)k8qQ8e?!N((?^Qd2wzOn&<|d{Oe5mdrWfKk-FqjQ38gcyy2z*u=0+qcm|Z<@7LN3$ZZV1c)AKe zVAKN@4PKTa8TF|Zqx*NXT`kIK$*yMW-JaQmp1A=6tCt#IS$9BWa?wx_>VX%H=L|_T zV((bIzO~kNo4dEDTiZJVdM<;-*q&#ZuQnH38FO1sHQ)Sn2&hPuGYklu02OLI8ufnv zfhc?g)i+TQ0N!C41=%iFc3ou^NdH0z!*Yp>OOu7< zeftoi6%fe{5J{qF+xvS=^w!`p;QR&!RAw7K_&bJ;GxDM|DD!jRoS77hSX8G&ZLJ5Z zA}4fXpxBBVM!?9vX);91A;Yf8tH(>|y&a3N0?SR9V5V6%IlozSpW;AhuNF&&Zo@)7 z;4KE_ccwrB9_Sqch>4n8;a;e4;E)|ltwk-kt|VTYud;5nhAHW_GmH!>qRB^wH)p%M z%;zQjsYU71)XUk>j}$(sr0)TTWdacYyn|SO!HElPSz6+&AoP@}gk`VS86!gyNKa5) zO4)HfhOK@C@lrs#YZI=-N;S-rKwYoxzTL~R?l1=hFHDx>yW4`W#^y%74eIp4@?g;{ z_v1TamT`QI^t;t(DR^o)h^FfTQwm59wr{@Q56SK;Xz!G&gFc_elgAA(HLhX~+Ql-V zlS;Y%M+Wkc8}T}B1y5_)Y5I^cZS5u61CdfEY_ZVf_3N&jC_FOOgnHI|svf`K)=hwp ze6nk>MZz%lVmcjjQXG6I&r#1o$7KACw6};*;JFzGjfTP}h+u(zd*A>}ICOKFb;?ji z&gDBGuCa-i2DO_nFR4REdxNe#+g7!4qwFDd_=LLfZ5-cO>`vM z(9Y%ZCZ)Xq1{F)WivurSZ=t_v0vOP|C@0Rmb`+nYnPTpx$IN%P%eF|1ogB)Bo5#l= z!aNoS=iZeY2Y|c3rB<8SUdkwW;JFyfnAciPw6ifE#a<*6iP@kaHuHI>Wv)UWM(1{O z>HtAo1k=JeR{=WY(HG-7axLcFjyJ%6ingw===8MErAsNm3@J(OEGtK3AKM_4XX|(+ zVriE-M4RtR!OK;KvRN6cod6W?7MsxbZB>Alx$7Ebv7(<#Pz#&Wn?wAH0;-s7(QT1s zDf;?p$z-)1)-YjkUTWH&TxE7WZg*5N<#I^K+*|PiSZ!C$U1%ftpT?34TbtbffEhBo z_62c?$TeuGFmU;HhmKW$vN!3zTR|@mh&60_k z)rRLeZwdnVaXM`lAyHrXI!oDm zxfWZM_$1LXGAYi7)CqBonD3;z#D8tYE{4&{POP;TLlS3MHb(pcv`yXum#N77(|iw% zvh}`u5H5e<-Wa#(cN_=^{Bk62a%UFD3uRlsQwVf}yHEDruAJY7V~`v@|I4Mr9}`S_ zey|~u*L%i~bLIjA2?5*|)`KW83AvUv2jEzloW(U%*Cc(`S)JP4h2q&ru=R*U$Q}xr zhYTIc&SYqvz{3ZTL_vKKCUkK_Kq;`#XXBfP!@MTK{q&Iugf+G_ODTVkPVngh5;cL9 zFUQaQcqeCeE7}BtJD)Sh<~a`MOw%;wj6^mt_VKT%JSiEbVggi{VAgP;K(+Z$iwd#y zRJjS!tWGvHz57;_Uh8rC<0=4H;Rw$FnR+XbvO*|J`B)PW_ua5GFY}E}08M>9bbVKJ z2)bUkF&_Gmqb`^=K8wmvXy%=I&&?x2C2Rs_`QiDJ;5!!)XQFh)z@TSQrum33~{qyy?A3!V6cL-y35+gfn zB{t&JIj*S-<8Lz~FFj-luS%t!c z&WfE|iE=NSZ|$v|Ix_NA5;Lm~vsWfNn3G*Wp^P4vp^%<4xirRT7=~5(RE>Yi0mt76 zAOQ>bN7teyWBsB1NRGBkyX8qTxLt$w2jwH4_q2AnJmXQ2O0K=RMu5XE2MZt{7(QwIO~ z+igD3ZzB#x&^sRx5bp;D24Xp--x_H)niv0$GrRdHGTAYgx=VLHR=j|e%tP$}5_#1y zlIKHBU`BD#>;l?~6I{?`>V80*rD*I`0hr+CpiT2S5=WDneRoy;h*oi3IXL~Vyw*SE zC?>YQ)^>Av0Gi{o)|aFD!WH=kc#>{I{o_>Slu5-dWDnsa3L>0fHkBG||J*87N_RdobN*w8~u{C3k22p5XsJvBko5W%~FmLD~$Cjuu+A z08Yi8j9UnqbERkQ^1_Rr%E{h3UpLZ&iwH6F!Frvj%r&CoQte)XnegVxQAlh2A{qG^ zQe*9nazE-|mWCw2ED5ohCz3t{rc~#mElHsMPsnO`!I#6^yne(U;v0EcuZH&2!629b zWEzxwocZE%JZaxng5x$MA2ibSlXm@!c1Lp_2;Ny?pI|BNQZr^pjIU*U5%Oc=Gn540 z9hS-%%h}F`npR=OvCc%u!Ty!O9%Sh5!`LKTdTAYKKPKMLWf6n25-E3(G-1Ftnqs_EnB1~peFJ3LmQ@q z`~VLs;(69Peg}2gdyr}S%m{+VMg#QT6ick<6APgV>#phDNA#Vb2f0rY*VKgv(;IK` zydCIP>diMB5V{g}Bv5gO(&d$Uizic%+NeeWp0W zkom*pPDyPm?i`#MvBh4T)!PB%rI;q@>ngOfZ)=C`Uf7;IfJ}A{I|O>RwwTP94$k!y zrK$+_o)-)DN4e|kndXSmwQyCkYZxY}oT7RM^%KUE=37n0sV`0~f_u)@9Q`J~47I!u z*X}0Ol0L6vP{Z6C<)vvEs{rm!*lp#NBU6J@2>AkR<>r&GGq1%)@fd3N7ChCu(UakZ>d<1T zzv0DJdlW}SBHk9;&bV7AX1+w@W=^Xg|2Tx`Y!brUNe+A?|9p7mA=h(tvGw=S&IZXj6v;Jct^Z(2RR}cd*ocArM3w!1pM) zBStAxj4>qR+TA(Tn^*h=jyOZxWwG)1bw!2C#jK;nCT~lWwISWywiE@j*_;?Bax1_TKPCcc5Z~ni*U@L70bv%aKxXNi04AUtRJhAX-8F)2;wDy zZCAp>@=-ne$Pk2te4`Km^VBL8b&rbwur2Oz00LPr9cq45x`$j&8M&ti{r8Wk+EAoBKcbh9thJWw57Y1L)Dg1{_3|Hb3Ggj>3tC7TQC1;7ue^@!$){|<0V6yf50S~6=%bh86Z0G-<=;tUI=ux2LTJ+lzvX4}AD zcmtd%obULvH!MfoH7FnAw)455sw_+k@*-!vwT71WC3lI$#mck{?8e+Bh_Dv^kh|}Z zmW4C2*|X*3I4)WKw~bME8xX1&(8c$~3>amne+FUXda3yJU!D-4dkJjmJ4+=L4#x=_ zJ;zWCQW0`)n-c@z#Qp;~i+bEMtS^D6adq?h*h>jFqDLYsQ=SQEf_KNU`_IiBvrm_g zJ=B)ycKchfk`P7O=K~NHD7Nx}3sri45Kb>m-%+p_7)?Asm{6bAB0%TG_z`ihs@@r9 z4gzMC$4l`y`_Il>xxAG;hV6p8wRudO@|~?$?Q3|gb`o^>e@EMAuv`uW1~?Lu5VcyM zxe$k({E{v8#^0X#e;z{#xR~^%g_b0D4M)+zcw})RNY=8!KmRXX+B?|_#6v;5fMfAO znaPjXDVe7CN2&vss%vPgasEnNTebn@v%wFhnxgodU{Q5s3OPd%3rCa)pA3;)u?KKb zlU}IZ8xZkf;37yA-H{~0q#tqlS(~iCR!#YY0%BOwSQ6?WD_CkBS%$e!hX!G3R3TvW z#J6+eJRk1idxHqRM9w{gJrkn+TVOZc-3A9I84^vvoqvFP2ig3t3xYC$sJ7W({!IPh zF5-BY5Aj}jV~u4Smahq;Vx$hhy?*zV;|l?ppDtfe8%GG`C)EgVMe~8t7UR05jhf61k~fRBiETGwf1KeG-AM z>_ByHhvNYtXa!yFnfw}AZfufiqgH402EQR5iW5z7Pji1RBi4S45A1lD=%HZZ!aJ8s z9HiyJ_+E73Ako4W%rYWULe=W#KzrM=p9`4y#-?I9y_)mmi60SmDjIY9@%c`is|z>f ztC}}on-3kzQ#tQAwrmB6Kz=;|2#6BxYMg;@5^VN9D&IJG+nmM++SLl3lB~>k_xqs2 zHubio8hG~YjEt6?S#~X>9UdLNCZ37{JDB4(aI?)d2aVzSQ-)%3KKnmp6MmwF&> zJ=G%1dUksbQoaw%(G=ok0glfFz{Ob+QqQ@^U>A@ADlgSeI>`+c#}F)kCx1)owYg+{ zanY{Xp4&}nh;g%;rA1@3-~{OX>wEbaIHpDgnU4JhytoK4er(n{r?cv9`WoW`sLoq7 zq@<>V&>o3%d?W(1pXSOiuYvY+?{1~S`}98)naWz*E6-=M=ZT2=#67Pfm*Fflq+>|Z zoKg~==i!EI*T=*@04XL+qA`tN0q{honEKuNGqzuhLTEiCSuXEGd79{UJ%tkS_Dr-q zu|~(GQ$vsg*uDPuU13z?EUiW`0g9vJjR;KId8-h{aY7}8&pNp~lujj41m!SOS+7X? zoizx10TMH$b?wKbJ2%TP5&!yZHeMSblOpsDLoN8>4z9q8jB~Q=selt1@iz=%*TP$b zaaEV{GCMOKKCCRQkC)b3uL!-IP_4l11grn!=ftv1mEV0K@FL^=B%4@=h25KoJvHt@CHLYs=uTa^mDCp~*^>^og1Jy6kk z-{fpKPD+tgTaj?Xz4x0XXPct}u^ZG84%&BNL&gX~i@O0DQIX*bbT?o|R%m|Y7(fw8 zb6R{_Ye3)2ncoF+)c!Z_ipT(EF(!MNjSZii6RrdDjc}(LG2N9vu7ML;Pnu! zU)6&Ku9V;7k~0(q60478h!uFP=sd8VJ%(;X6hw$~D|xlbte@t0o%vY!i{+7grbbA^ zWGd}-Zkc>U>M387Iy0&l(1lP-OV2g`KwCyR%0N#AM2`ZdS^pG||KpPp+pvxe*rD9*Y{0TxCsR z@A2zcXYg*@V1dh|?Y?iU$74+o$Y2&0MAhx*Mwf@7FKSkMju#%fQ8*h#F^0v|TR^5zf#snwv*1D|kwx5Erd7*~po9$VGVBaXzLN&9uhi(Z`Bqv-N~pJsFe5Ji0bh2eI&eJ1tJ2}}7p0c+q35A`^PUZ3-Ox6O$5$Q;nUbvrtMvMOWc zf(+^*KB1_G!Wuf6EpM%PK}y~TeL~?mdlxb4S^ash@6OF#Wh7@&C-fKlG13D-!kRM0jg1K5wrv{lii;E$g~^!PNUnK4n+)isW(}Q zNf^v~F556Y4`cvf%6lQn+0vPtkO-uLNS{z1nx612xDsH@Cqd0D#kEv-zZ#wKNlUsNRNh$09%9bSD2mp*`XGkQuqXa`} zp1elAytzHEY5hTCIO7lP$fIU;?6-g&I*24lNRb?T-j#Q z&AZnsU-Xk?@VU1c`ltM-)FyX^GP;Taha6Am{oslLPt3AW+&wP^&t!4*pf~`ZokX%? zSp|J&!p0G!eym-53-;1=I;l&f#6#NY;d}-}*W(6vI258671n!LKCjDJMAlfnB6gHa zCsPKY;iwp-DnO?LP zaW5{%5Wg%5OFR1sF`CTa`qJ@!*9+5WMrp8e-OLBN%Iskby>;V0Q39xB#t&m;-J86e zG=r#kX0b4+TT~n?likNuZtc5KChfl8Yo9382nQ&g`t1r)~W++FE`4n$@&oo#nYPX!&tNA!PGLfk;tC6b^r7mbqBPLm0PC zmcC>i+G{5H(5kL=7px)8JDALFY!rYvj$G?W-A!rG#?=cIDPy>_yfz$?#r!87wgUd* znYJ^!Bx*#~;7NJi^Xxa7((U%V=VYu^$D4ZDa=Ifogg4!SDbYF(krdRKb&+j%TbHGr zXJVz&`t(jf3!QO$Bc?D+wje8mhAAaH_%cJ#BDFLp;la0JVI^;M`RANrlsjq4x*4rvDsr5|%5iHgel9x!zVr~u+V?E{)jZ#u0R3xz?N&ugYOohEKU^FFv zySCyMX{A-d97px`89Qed+1>kZ9U5mCG@aE_uZKQ;9_W_Oh845L5vd-XUnYJCklfdu zE)Yy|WG$p@vwgf+ETZCEV|vqxwlCy<=t62)cHcO3Rh`82U3 zwM5&58S-ZWMg}&^=VwBOD*(uxx1N^@Ka8eeNXF3_$mA3sC$07@Gg}Io=MXD9)1!5` zc_UbGhl}fAFMWu&NWV`1)8LL+?C7MIQSzS|R8&~*`^UMVEA zbzWKQxN>l#l=P83q;mI4=$w7BJ)RS(>}=H;X${Y_m9ERBjZTf+4~^?m!7j9icEHFh znYgX`{Wl~-&s*$*I&uz@zo-(7fl@_o{!P=v(W|v8ZyU3+jy38%=SXAJ%4Sy^n@r1n zRc1Cgv8)%&ICVr}Zp zH7j@Py3_&qRbM|JOdX_kZJo^g7T?4{QCRlF(7orU?8KKAhYp^`@0zl0Y;p}w81-^a z9FW=XP1`gpnh6##K7UhoKC|qqg1uSGHQH*0(lZ?&IX9^c>5R?DQ39Ugw~My|Ci%;# z<@0x4)T0eP$rkaq@Rbpy7;8DOemm~_guFqZMY7%Ot_@jO{+SLfUyY)3mWh)#n}Z`G z{mNRmX6lpFQA5=h9Aba<`(1h&?_d;&*&C;JeL}H2$Q-NK#y{@Pq3fPITUm%dO>vL$ zm(IHvH?L3p8K+Ls^Mzp8`Dji#&Lwk~5z-A3ZWjABx}R*Nn@|Y%5bi#LO&I6Qy zAdv0PbxnqObuo2aQRxgaJh!^M@(1~e2Q8$I?|io0&&W6R*o82Xnw2_Ml>zM=(uDp< z5FJwyD(yG!EZk~MFR_v^J#dmblOFIgcHMkn6tmF(lR@!nWeI9#JEYu+$tX@-aA9OX zd0I~Eb>UiW2I==TCVQmDv#2=5l&srCp(XEJ*(S=J7DP}kyKX0s*BB z?qDh&#?kVD{@ExSb9UKH%YmP9XYRpv%(}Vdqw_dxo{7OQ%(UdujIv#Hg|L|}`_Olk zn!@$V(qU}3qO~8M5MpI!Db*EaGd4xX3*hUZyQdlGIn*v&{`}(7xfxF~M$|!jIK30> z@tM@O7+Q*RlFoeDb%(V=JO|tFhZu%>2mLp{9pL+qtjigfC9dA{B{DB@eg>vJ_SW;8wy2-Zq&}^#v>$y_AnHsv?y={HB!RevRe20oLIP*z?iLE zMzSRFT8KuFFjINa0e9+)vukY{0`1!!7D>cKUoDKA3kwMzLVCBtV-5U~i>pxkOlUZG z9PE@+eGuqcRLrytxf@rVv-20f!$qDR-fN$Ye&SgwnB;@rW$=C`+B}m}X%y-}eUQU) zIyt%{G0grt=G+aIoKd`|o2aA=>KQ};j~nrHnN<3KKR!$zeNhWY7kZ$!^JVHg*EjCJ- zweOvX&sonZOBuHim*;xsVR5B;`vFy+U=iDm5%T6aPHx=_u6ai=e+NAKAcZn zdcl};-1(1R*u({DuIIb{okvdp{Z#|HC7lk2)x}(OHbJt9iX)flXty1WUCc&_o0^r> zJW~)=<$-v%T!+5bR&H%rK091iP-fj~fF?@8q)W6D#F!SPPvfUMPwUC-t^nTZu4u3B_S~`!eC`jYI$Jcv6#krwygW%-J5F$rULi8 zj54M%B-K`>&f-Wq26N?81$$E=xezLAcV7=TI zM#{p{?8bfOWdvJe6+%4fJo`jgy|c_*5P1QsYE1}Ds-B(MNt=#-GtabKvD4cOn`8Bs zTiXj(5>IRGc%sDI5k_-(b`(~9r4n5=sb+Kzyf{n`MZFKE@@~tf9bT;pUPqN>_9KrN zh8kBUsKb;Tn6vs8xe15||0;#O(!zwgx>Ub`Ha|hx5#TLK+r6WJ6&jqGR~zSb0^0Z=e21hyha&dVGTE)}g0V_xZ9Ufw(Pk|#mz@VqnW%J#T`%Y4bpPx=Zq)@d7& zU{jX;E6tWNCm}v}drJ(DC~Ke+dD1d{-N}8G+HH?+DU-WVRS1F7I;Fg)?cM--s8C>p zncX|}=;=OV@-0Z?ugth!&RlJ{jS7tDjP$xwyTd!2f|_w8Q1FNZb;RN7-ys?#N3SV_ zqXEQ$Kj#Cm*lX2dJl}Zz?1(90HRqf!J|q(B?qAK)-_gGsy*S@PjopU>tKXqeEKmPi zF57}TsOR|XcP4-uh~<+l6{%m>Bo3gD>>J7*6rc7tGx28fF!OiX+ zcnoUfY2GoKl2UzK^*{F%)-U(BY<{@3_^tMzL|`I!yFPAU(aLt7vFlfaYEHDKGYpZj zM5Fdlt9L#9pIFu_{rifF5wa`}AxK8Pov~f<7MYoc=z81jQ$^;PJr$^jvff@Y={O^C=xUl;vB>;5HQVewnRxO2(RbVt{l9m;-{;&ix zs5}dgd7Qtq$c+Uy;J;Jb#E16)0N_|q#TCd#;1I~$B7@`v)EIfaFRtwO!fHo^f@BXR zbP@HgGZy|^kZ1t_BL1#nd=)DiSde%K##c4}&9s!KZ&&7A!IQdY^#D*aO0O9{4^W4C zd{U(>rf+EKDMngGT9q+4xPwqC^6|PM)Lg5|T~NHYE`5_}nlWW!y#UHcTs#HmQu|@s z``;#8VXuH6#7=W^8RjtH!zV4d z7R)&19{+U?&b1>QC#Z)#5~P1YQeE3DDf#1mPl0FpaA#7|&fO$;maYd$!xyjDj>A4( zaxbS%)`4Oy!BVeC8>q3;mqafCVBwp(3{sF*5W>ccD0rBY`U-l#YbtTe6A$`fKNL89 ze-Rc?-yB5D4|CcK=qn5R@~4nhEYYz;+$nPJ`hn**)VF>7jvV6vNREkKxV?fap7G_3 zp6qS1QT~UCK<@!K=9YA{v7*I9*8l~jzx7p<s_jUzxFdt&|l(kfdZ`>^6suogb>?v&S|M;q7RAu5p>{loUg^R8w7-W1)5a zs4`B#q@2|!9`|fyez3DDOkp+xR0F!rs+Pmul=8kEq1XY!u!x;WQa^w;Of(}^I_tVY z4?WM9P;DCthP~BY%?BNg}OzSuDsqIB4{}p5}%Atn-dbL*s zcHPnE&P>*Vwp?$KUo*EC-)Mf5e?-T?))q#2pPXRa&ne&wuMFhQb z`NwYrK4Uwdsb2!D*T;w+(4b%-{B}!Ti1cQa=-~ymFaVQsKig{uCw>A_X&xf3LjqF_ z1X~qm6N6A$T`g?4b2YU-(6G&e>93ASCN9+d73BkpMwc6~Yahl~kTL_I9rMzD7-tac zHc++lE`IZ2m7z23W%wXPK3YVh{G%AzKj@LsrG0Wbs#KPwF2#vrO-QAYjnRF?QteDq zo)Y0!kD?jQY>imBSUs9@1jM84dedYa;j@>PiX%xN(=j!-ebm#Ql2Jo~_)f zRdRSWdLKgo=*m!1SwO6NUE6KQ>J2RM9TBTCLdd0JD>>RNPC=(#-xs%-2;*FOl*wpm zbqXjN^vpGUH4kN6hD6uSItV|wT3>+I5Vbnz8*~3)eQ#g>5=E)yeu8W_ShpbHH+s?t* zEk|-=A&i@@10ruZeV+?jRyC&i8J5uZiV=cg;)5>!z-vX)J z95%o#V~Wu%xICs489go^mCYt$n^#kydwJNue5M~k#C#X7FttR600eGQ}pT5H63MI&pxZ|() z*M;ky*rT`r{+qT2H}wG#d*Q`7a#Y1pfwcx97_kQ+P32;E76|h$E4MP`AMxMWqt-?G z^ov_Z31W)Zj)!a!qtVaLli4Jerd+2ht>lB_{TD}nJI{`N^7tLTb|!_9)Cv#2KLaED z#s`Z0>3}jJf1&vbX^m6F+>1zO>L;=0yEwx78;yoG_EnS6!#&sO^%gFW_vv?a8Uozu zz^&Tp=w`gx3GHI7i_}to-<^lQ($+=E^_)P0H0k^UK=W<1IF#uqeNQUi+@phg8UxUN zphj-XN!n!)>m<`kN<^|*r!jvaq@=t8RNcK9YmS71^|iBR>=|dlh|~-O9HQz&t*U49;a3@22m6MB$`g5X#C;+>cyK;$KeE=qj`WC zWS0{-OZAnU0jDrZHFm>}Cw{-r1?~vOM=hzWMQ$+P&mPSzrhTjh;!i1i_++25 zdz7x_cxa#(ju7J^Yx-0lRK{-7jY`KupTtA9h&`*Mbf$A*JmL*fd zsS_)MfcC6+%*h71w-H1IpQJLS<&qtS9SKTwzR(uhQ;gww9bQlgYRYhuGfBd}e17sB zmi+Fw8cg;K5pSa3AMUskiK|CK5e?U^yAQi}kQ(Y)Z0Ug$p{YshaX?XuHx&UzKR^RGF}y5eB&;AsITSnMZ-Ah zg5iYs-1_YurYnlUY$@|6K;6TYlTjp#%!DuJ!QbHQul7*Ut&J62I50+otg8mnWr#Pr zl$E`mU+fX&WP8s3#u)%?e02hH=N}Q+TvJktTIFg9VV%V?8fEf61R1JXIrbfs;`nRD zkB2Z4G?UuvB(!`dDK{Ma1*`G~s$`tWnM&h8wKZ*@Ayn$cnbecMFco$K4E!-)UTL%cD13PQ_=SBj<|(J!9lskb7&@Myb4 zP)C1O5sb?%?xY{}PuR{=A4+?C+oh_vVEe52coeDCM*?&cys0U*E;e*D0IaT3+(PxR zmWE4Cb}2v}X8DF)z6SI&YEomTZrky#ZoVY^YmL8pf&+MlZ8V>M|CJWqK*cvhnZTXJ zu9{zKI-debCp%M=c~RFIIYQ^+BnLOljYTbB;me*i*>$7r}qO*O~S zqB4JlsQ*&{X~g+yX{R6fka79Wy>>r5NQ&rP^7>GB9%p1NDg{CfFf>2Kuc}mgU%SEJo9w*aHE}Tr>iQ ze3`%J%E9;E&&PFpss2?@gm_BtZ$5ht8vAS@^0omz)EJ23c3cR6yO4U^G0W^SAp4Ip zQ>fqDsA`^S75FP=fJmMXuAD1*OAOfm$R;*HD6UIs7`@j5BCJy+W4OHH+|J#TC|M#5Nc(VX0U#MnQ)FM<7wEwj5 z73SQz>Qh3D2-5IK~GAJbphd z1iZg!aCA(z0)Y9HH1Lb#A<`CNfIJ6F0NgYqd>3@7BLfA_X*u{+P{zcWg~Ebn6JOtA zbH8#q0G&Z)v9G@+7$oZiI$e?B);O-&&isuWkQ#s3Qpw^fWqj( ztW_QP?E&%R#Q;Ef-NO6t*`fXUstM(Q#sCINIQ|8j%IR?2b#Eu{T(dt4uYjNKWxfPB z8`1^Zb@Vk2H`Td-ntp6rsp%NAVSMR*O)_J>-<)m`egkMmB?h5b0a;Tns7d}HxKSg7 z1X95PAT0M8&SKJG?cYc8+Zz?3iv2+8$ObeOCn?;JM`K2;MWL+V>!uz0>Rt=K!g&Sl z1y5bj9A`~%*_SAl`>%y|1JxP_EqT`s5PQ0T9+V&Bv$&-Lh3)|8&6<7Sjk0KPP+nC2u7Z#t@!{498&;Az)6-^jG!Y;r>u_G@|xW1D*XF`Zyh;q^m zD3sXgUR2@5KqV3)MD~R50|HSLK!6oCV>4Xro{u6h4HuznREn`kL`?n(kL`0nX;2f> zEaKH9YYArPvjQYOjR*QC04-q%2K)m%9d(6(f}>nCdluh=#NqoWY1(AV^=@oL8aH{5 z^5A%%W2yhwrVYaaqokYwX{uk-=Uvz5;0bCPZ`~gug$KI5R64`Z;r@dtvoHrZqXyhr z`q+(>I}1F%f4qsSm#dcmK#2n+r=CX<#8jA>?@-b-$;zydqx60xVIvh+E5Baut)SJ z=TLU-^?wjxQ4;h>W~{w?|MA@8Q1v1y5-QEKvzw}do z1}Dq_}PY=QV`40zcP~c(% z?wy>~7L%pMx?sQ_ebR!CA3hM|L(EBkvfv^Z@gh}9BesKN-7Js8wpm*Y!VevELK9B`FiZT(53fFfQvBod{-g8@#e7kR<@gr5!vwc;;{$*vH8c<2 zF41{5fII?_xUOjU@Nw3zwKf?ja*OEvxN6M-)v~O!Da4h*^(f5U_2PnBaD@lZEDCj9!U{Nj8D4#3*o5Ji@ALJy~8K#Vx*ow8cXm4GXFa|7Vj0uiQe z?_s#Q{W<1wV(DQ!*r%(lz(&x zTx{yXhKG6$^AG0Fvm<7|KICbKiVFq+Q{gbcQSSU9B5)Ek?@Pqg&Bcrqgju#_FC}oH z7Mzo7B~R*0NWgspFtoLl{PXg8=|F?;{I`<(FbEg@#ZZ0F?CPF?637a$2d2w@SG9dl z6ffHPC$$@MVlg&)nEWo%T}-`LHmoYjW<@Q~O7DLa5!sL6#}Pr|xnLXsleolioz9+V{Slo0d~_sNf%5 zRe2d(t3R>f)CnL9)(8VVQSuBIS=+ub&xk*`s@9uVp7q-okP>hL6FNk>@!7_St~3E& zTT0)_9D!LCM1JZ9(w(HDh8GVW@LvfbwZ;5t{>~)_2gnl-y&lOYcET)j#d9VJ$(zb0 zdQWK5w4)mnNn|X6I8qQRZ46+||4wrN`jM;vT$T4AB890;EnRyWAZ5;TLkM`tAo<0z z=Dtx*x&!tPKLO-u@e%*wTi!dxVeb%wsrSK2!ca_K(*kks4M10IrJJoU*F@xK%UJ_J z-}10O0h+%Az+id)o*bwe;ir~>V3#x*n$fxM<5;I!&ZZ#d5vA5>kpyisJL+>_FBT=x0&BD>P%3FS+!*V7 zse%gm8bC;+Em*ApooB39%HZKdiRH3m_lvgXM@1JvKl+WIN@{MfD^&~N^5)`g0gZ#a zFOmsqT?-N{;n=P#pFnt}pF9OD>+P0OLXyINmESQ^2 z4f)LS#mpc;lQ_ju4POw{=E41eHX#s3e15(=MMObT4R?!)4OW1mbleWo;!y|Lerem)(&= z5!%s}5i!iJH_KL{O(#tim@}Uh+m3R$fYf9PDRh-(sjyZ6wABVaKuX<6dU~H9w*em3 zLi!<4b?_rP+Bd*Go)fj|XdNm0TkW!Lry_5tLkr}=M*1y~+oa*4EF6}aYB z15(;(K@1pYuAyH>ym1q(Z79g%Wa;Qd?StPCuK9-M$b#N zbsrdwg67)oOTc6+cVobFZzun*D#cHi+ew#nL2Q}R`(0oJ@S|))mt4{Wz-kQ|)JPc4 z=m2;zQmXY38#-$j*y{f6d>ck8m@ht)nKoTNo{B&A`FX#m4~|T^(Pc-S*Aifxmbvo~ z07!K0yJI6(lRx4Ip4%@gm`)t6j&N%pxYkJ+KY_34C#_NUvA2r(6TLID`AV|N5O3$Y z30P6ePD|)xP5{|i6QEvhW<0|QZea~(sZu0R1=-}6M5po2FMH-yF&$;(_Y&)C>8E$? z$659LW8XJ~GtJko&bI~uVAWi!K-N}pq`51vV%8)K;WKtNB%;hrwwdpzP;Q}_Ey39uQt*mmc6zL9 zI-k9jXO{7N!}1Z}c0PopRph3}8olN++*@1dED9_8xud9Z_1RUwBIf`!-G8{i7-W?V zuY4oARLnKv9>FHICRy%Wo&9|0I=DJr+&Y%5ESnE%>G$<3e8(EKC2fjF)lEh5KQZUm zTO4_p9PSi%-_AK_7ZOIE;j<`_OG4r$`Sz7&1Oe-K0?%@_ZJAZo6oKH0}pt1xxNsG_q@zFqICU*ijU7{_BU zGSLuIYYpsc{y|sC?Jo9o8wu`KnCp36cT0rr-xH%@LlnHMU0Gi8di})EnPOYUic^*} z^|>u@^~mNaT#4$>FF%V>=v>Y^+yaqh@T3T$Q7HsPqW)b=pZiUJjj405F7)0AGhfZK zGyKC{px>R$Y*NHp_0W3TCfO5?qEPxKDqT@8QIFkEVPlM4?P`3aBS9C{Jzg$5CKaPzGC zC&mbDMk;oSu}rv+SDlty;_&t$cxX&$D3(gVo=Son3)}nRe=2Y3VbXS{Nr>IM>5w`c zv`;1D;uW}m8a`&+7D}|^@-3UB3a_17ffcgR%`Kla;f%@c&rwUQWjS(b#zO&#kooMJ z)Ivv~(R$DePc(1=7gBD`J;T>5*SqJMntRsr$=;8xBozgea3aoK>el%rf|#yrf!AfM ztUEaRQ)f(GH@S$wVC_8$C)+dT_Ej7ZS1?(4aa+1r%|ZMwk_$80b&r+7Nl?#yIbacl z`5lv5bgyR!UX;B^(vUeZ-0M0b&b6&L77@6VB=?rt(m-C*bn`(jjS0h^Ox;Fm}v>H#FDBt^MHVho7SS1^-cP$=pGumz-z1 zPU>ZSvEKZQX)rvLMK4yM$`0s8+Y(66&<83y(x}a+ld5{$Q*UR!swzfEBcf;i;B1N) zj_%pkQa{J^yWcVs zE`1~S%%QI0utK-2;($bmf|8{Hj3x+syWuWbH@A{d1&g7VU2GBwazuroYCGyGHUC;) zy6U6S5K`?DO1*PwFA;0tD2jv4e2;6-Q;H^YiO7h|E7%;}s}8UD3s<8Fl7R>JFN>mw ze`>Dtq?0Tb2q3kot!N(pr=SON^wUQkJ~qY*9W>Ml5ff(U7n0k=<~e343X+ga?#Ph{ zC|t>a^7__77UV0c??Bx*IufxVvn^U`l!`k<9y-&=Yta4p0I+ma2Njf#HYeDUx53L0 zKXAV}K^sCqD}GVCz`(4Ue`OHEXN$>x)8iQqT1$cED%Y5vn00}V??`je&R0PVy5--N z`3FG^{2DP*GC6_ph&0wk$G>lGMk7@E&c>R-c}|e?8{!<;@%}7Hy#4HJ!LJ}#AMmJP z*oi;8Qaunby4jm4*Pb>E+Ph^FE(bmS_>RMk_VoqoY8<2>wHqb)IJn?A;+Y|!Y598* zP#`d?3*EUGZ^2!oIt43(=4IQ}S|XnhbfXJ~%?FZ2^H=cVAh}~A*PE-CK#7+r?L_eU ztS?vp+japg3O{?4pI!z)R_Inwb1dNzRjMHm|CV8UoQnaqx&XHA=^L~f(+Iu6B)51M zfpr;r-Pb-bK%#v3NmWkdODmn;zQL4RXwR_w4KKhli$E&gIja)@5j&_%xh7u%WJ-os zEvrvv@GIAv*`-F2(KA_F(xJ;sPLttw{Vr1m{c=S|Qyo3fZ)Ss%P)6ZpQX$DbGlkw` z{hW&Y!OjWT%(XJWQTerqFCq_Jg?KTLj`2S)Mr_@~d1;vZE+NeniuM+k!!so4Jtmj0 zU7qKEP4>jTCH(FF3!ui8rFE%h;WK>Kd$egBu<`xz3#CJTBEzN_Vb*!_3k7X+WUJpz zbuXFP;SmB-jsGlyQhPWr4~n3te0zW~w0DtkQ2^wY?d7YaJ+G%W0FWeAT458&L0?6v z-c8auC$5eHi`3UA^r$E|IH(Y{v_CGl8fu+o&H*r<$h^y~u;<#@XU<&_B?*1NUO6@t z2^wx{ww=kvm`-3j`PW?OP1FJ9n8#IIA6e};$APUWnP`#^IW zWPwDrQO#UYxtHXeJ%7b`ePB$1;hX>)L`h2Ovz%^p0ulBb)A)Czrg67VGCBfXn$N}~ zI1Yh3@#Yxmb|s|1p{K|PGNgLWy|7seB-&W`X*nqL>}3*N*u8+#qS3YcSpOUeQ7qLt zyjk_NPVdkeFM3TH>BzZVJGlfKQ9`?WC6K*d@~^>c)#{llfe2 zHRD^5Ub}GF4ed#xis*h?vDjkiwr#+RgEXpqeL9wVMF_iQ>N8*9VbeOegN~SE&77Hn zL)c0Uf7Syphq9RjAkFDHY`O%3vEEa43UAoj0fU=0_mYVDn;0cQAO^6dqH~TeZIR`& zT*NCdri{J-MAv9K)Av}7`V)-=Nr8PYKmk0@7Q$Zvse2${~MxF393}%;B4R; za5KLxxn;R#|J&;VfP}q$v~>MBAe%9>g)3S8C@z=Nk2&{))AoSagvDjVM&@T{{Gaa< zaA%AAM-p)971(Jv0cK-U=dh|K1hVM5U1GstUaK^96pm*>>Rs=ZsmZx^wRAxqF0=tz z;6f1B&2sSq zkR|@Hka{0D7aOJ^t#4<8;*Es7%tCJU?`$k=8SIY1GvIgRyTCpl(G0dCo**)wJ4h-F zAm+!a^R29^^Ep1)0bjNnTF4@{iqxdP$!Vk(^Ya!)!h2Bn;w1OKE#R~x5zwet>_Av{|BraSwHwr3Wrqf@{ z09B4VNYGNvU20JJ)1dS8{YoDU2f5W)S#m*LqX`qV*ICVZ))Rk zRh@e_z-V>6rCGD4Jp`=AlzivRma9tv+w`$NPL=My=%O%&-b!%)7KW>9YM9FA5pgx#s=oR= z)X*~kWsu|AjS6vhp0WD-qE9C=V z{FS#!bwIKhQ!FW$D8eTvkeohzDvsBoeB?*X@6m+wwACabDzJ@Kcl487DFy%2^MaHG z93aJ`)q||;9jPI^J_nV#1ryy*lg|tr7yqpVV4R^wRfk^-qVsg%4X|OqC1q2JgYky@ znb$B#%81k2O}Z)uZSJXiO1N<%TTV39&CR8t-DQIE9&`r^m3MnBvraRr7zaFks0mGk z4;$nA9K#j3nI#sv5&P&>0;zhHfH2{S$GvlA|lYijrM0{s5~3>@9u1#K^cU}R_E5j)V7 z2uLx-J3t-}kk*k{TVGKZFL3eYrQ0}0f}}8eQ?g$0!gWj}9(Mw=Tr?}aVA?yN&Akwx z#-3QFYdZ^5(C|eCXoRzgF;p?2WU`r%qcH_)fkW*_6Toc;x%QGSo|Ar>K0 znP9IGF!#~oz0qpHjP}Tvb+P(5YM5DW-sO{h;!EZ8*Au)Lh1@==fn3`}BwtoP&oRIL zBK&am^kdcg2H}Shl zJKd$q*Ba$D)zw5ckH98ojdcF8kkDd_4Ryd0T_NqlNm0|6j40cn``Nex8GL!x5ua^n$?#SQ1;XZ(!CJ_9*nUjmtb6~g4!VuS=gnRJ)suC)Z{0EnsGmF0Zp_E#*BCNyr zqbNP6w2ItIT|x=I&6pook|?&Q^xf9Gpuh;D`_U1w^gCDWTJMV@%xPH{%Vc;scc~J1!IARVJ#)9$ejN##a7w< z)ch*FB5+ZTngwlqhrcCUrrOF5=u@z8dI{|w9Z2$U9!UjHEAfHj1;^(0`%WXeYvoHMh)1tCYYcQ-z= z5Po~)sNeJran2{?ny^){iI8g0Nbvbgk%&f%@}D1X%~4y4GnO??Gm<7Ro#!83w2gNx zcQihp$NJ)#+l+Mx)cq#eD-+RQiw^It=dOo6$v1N9ntQbMoPB#hRpiy@JoyvrF4lds zH1-!0g}+cRR9_Pc-Q~mz_T+Qw)Gj+7G($2y8l5kUB}vl8B7xXf)GlYVcDJg&?0qEC zcTkUD(+42quuva@Go9Vb)x#0D6#Bnpjd4t zH2sN!`duR(<=U$C0Mxg4{s60;^>t`6-l+Jm0fnBdhS_f3#4D9dB=+xT{&{qw9p*32 zs%fW&C)BY*_YikK<8z<9`B4}%s4FQe@sHp9^Ibf|C=!Wg{Y5km6#nOnfrofVqh)?` zppGQMHwxfhDFlCROvSn~D1kaT{opwux<&zB^F(wsR{C?5a!}#S>0rGn^1mm&9}`un zsfPTyDfQn+gq`INXaKUNgQ~JUfD2)P!P>(<6bW4GCgC4DS_7V#R*ER?tfEn-ApZWB ze-_kRP81wJjod>PUK|W94^5hHuh{^^3l$Lp^#HaA`IENeXf=g@{sl>6ZP#B| zK>9aLUX5tAFYFeuQMLi7{})tNTLE9}haLDUmsAKM9F3fPKC_^<#()6c z{Uj_hJq4|l2L%{3WfB6t;clp>uMHBh#+IWvZLDuV5yRdFU}Yn<>zwW07(j~2Ko53j zZZ`iR8rsDDQ&1@B0o}y${O3kh8aF&Zq!kVR3!eTAt)8W3la&n^z#M@87(0Ep+%)FM z(R80J5>kbgW*-oFJ@D;5p^hwA_;XWZQsH~`GaHomHW*K-T2$b+sHMmj-PA1>Qev3E z*6}I{b4|EGc5IY!Ou+n!&4tUl zew5IW-SlGPelEM5=+j3icE*l!&l^zFO~>+`_KQBW`4K8kwAgGn8hMrrzfbbQX9XFn z>Dz74=Iu2RzVnb9=8_S?cJZ(QbidyN|E_@sttTc}?;GuapA2dM6aYGbxbUl`t2}D- zlbiSpkWVfDNJHgY(R~hWCh$Eu8ZA0`WU+pI3i9jmGx<|q*(fUnOi*(6wg7#KdTt=Jg58v9XodO``&Lrg2|!Zd z$-Px9L@WGZOLw_-uJ81y?UB2oM3c&6eA@iNn4T<1#2a*lx=l)Q@DCE+eBYqEL>j(v zRYc7W`~?C)V-WK5@@9#dI+yftVwkDf*dBsDY7q@#wi0&2A|8$1%c3T+`nTbtrJgtS z;plSUm5F|!p*n!87m~A%1Q~7R$}_o?uBq*#0i)W3C6(nfJnC|YYf%D_{L$Vt@s;VS zPAgysnnWKGq$b)R*IP~qTGIon6gb36Q!qyMxNZ5Ckz*P~o$4kRaebS%2JX!x^5>f3T4z|F3Ts7c#- zrVjtF5Z(-H1aAz?OiFj*ZV7R{#8iT%$c9{>xy|+`BprSrR6-s_t9cOzKwc-2kh%Id z3@>19L>T!Ca&znf_p&kPq!Hx-urSi=)SQBWI~=X!@^|{L31UzNcBnuCR zmoLoSKZx*L*K{6mAlBH0FAlT}WaO}DZ{1`;v1Fe4>3BI)H9_@|7{qk|R^AI=Uds-V0Cpob(_YpV3l`}SBjHVRcdA>t9W)gE z_qSMzZv4(dQ$qFFV`%(dEN_LH9&JM3l+RtR7^Y6_K@p)*#>uMABbs=GWmJBJFuPna zf8C>8Z?MQ^>8eD>H|Y;d5VMLvrgG311HU>dm}UN9S$=ND>6SAbzrWwufr2_N^qs`| zhn3e%Wy<{#xVw8(nxBwUw+y?6D*hEgEB^8L`t2Kjzm707^PynnBdsE(r zTZI5mJ^E3Yvx2Md<)YuQwRkB`KaV5e#G83S02HVXaf}2Mhcf%dLUV`>G9@tsNu7hH zq(IHMD(J46IZr?J>#SfSZLdUi0xW=ou4BOMWEzc{o%$R{6fW z&I52SK>Oa-;2L=n(HFf6l+n%3IRajg0THQhbrPD)DIOJ|Pc-{k#ZXcHQuC@IfwO40 z5hDhExy*8$%=tUGnoPi@l9+v{X6KMqe{${>xbZUns9WU&xSRL9j(R{|J^&aPK=oA3 zL@(F6BHgyhdTUT=SmJrGP~!HX7{E@y)k`Axxt2o}iB8i6r-4w)3h31DeS7-yz2ZCe zokD(xhT8q%Q%vm_qXX6qb$(2uNdV z=2Yjv)Q2v;(Aau2fSuU2ip~)Xu6?*=YZ^FoI!Eai*>$;GF{jEe-Jmx7vD>ZRybO3* zfnt|{Xe3a)Fc~%9|Kq{brR`b6;Us9|Zu96nTYldYz`?Y;Lw^fSfsD`z<%iQxy3@qj z4&K;;5ABBNQSQ}7`Q?)k~=Cr<*wLE+hKX}iQ8h8k*rxlj<%qr83n3MgWAk^58Jqe${`$A zCj+L5jTQQ>5Gj!6*UdkgujmKM=m|-a?#%{$25V_skVpacniv~#d=|S`+b5g^Xa@>#}$f+P-WdST7Y_@~B zsAo4MCFASqkPkeV%SVh{4yYWmfMx^2-nJ$s_LYIp3VziDExHC3)8N;B zHk6NdSzJxIMiEy#U_c-v9*DbX5L=yy4OBDtck86!FH1}z68cxp_{Cp;cOp9k8d{Tv z({PBSx|@tVPiY6(;&UNAq8}qvt7`ecN5%P*^y%j6o8N`o%&Ov0h~y zaTM^XkhbW9EdbVvqt{TGPYwdSs!q6?0kAUNJ=B8heFVYB)X+nD*Kz$D_5DJRFzjZY z8}AtT1G~{uvGE?6eTadnr-WGMhpM5wl#HA9Y~s5;>F<tS(1Dl&b0*!6KS%(yGz7y*7JhU zp|K&AYgYi0+oWCsYN|t+AGnrT6vpazF)|cAX~2ERetju>!EeZ426DP7IB1S+_Wi)J z1Z-j3IUbNbd~)W3R5McZZS+DIG9Sf9#<0rW$EeW~i-aeBZZ`IOxnC6@(3O%|Q?OS+ zOLo+JB0qMt6ocD#S59EmQojQh+^HRyuygdDa;hY-I{z-4e+n8qFG^Vdu9#^*-Ycj% zp-j9F=BpUx1GOYtpj!JYlA)cMnu<6QPlnHwTibc%;AE^FnSC}5NN(Dco{fCyD^igz zJ$whOx_RE@uvEc$%vj}5gc(tpsULf(j}J|Jmv;c&b)4K3qpf#3+Tt|25_4+ zwzw81QU&ybwuJ5-kaN5tV8n_~(Q5Z3)N$FKD9LboF1jc+cyJ_wA&C~E5E*k0dU)Mn z^mG9Zt6=W%Va(6#(>B4)1W$(qfsH1au`#gue}BbcGTVP0+x{NshjRf6-jjltQFx=l zL7cG_F8)M28f5~VzxoWXnRMNjORgciG^ZFdt@$#fe$4ev3*It#uD`dUtzV6hRk~cW z;HBBf@oM-`9ofCxg#c@gfPhfSH+nBaahfnU-mkF4&iPU#Y^-Moy2~%KH03>+Ob9&E zAlxTNIN+H4wsVx&hd8J#*H}I#Xe+5^KzS#eICOg!&8Ybf!`xF6v6ron>M)N(uoAU^ zSmo$8<2EEPJ`ybUY7^VugpkA&GaiF{$>XJZTk4IQBFYQtnx5MvBZkG_KEExkka*;Q zjxq=2yE`W<@z|))QkqaKRVv?1=ao-pw~}(MQ`+L;5TT8{(AWnI1H1PpKs`U#N|=@$ z#nN+xB#=R9JfP{yTyY{XMQf{j60z2tY~w7 z+n>DjktPo1_-?uxV|U36ORVDs(ZzXv%hKGvEH9u8Gb3B%gEzNMa8&E$ zxVuZ4$puD4*cnFpiDrmtx5oI#df+9FlEihQDH^nMR2tyEHFD*XkLdgfKaDMrkEtK~ z>VL{#FnCJ9v7H$MB4jkj7sg+xX};v73bNlwLBm0zAZfh@aMl7Wd#P9mD%zS)t)8-t z#eFa0SR@6 z$Hr{tRZK)d>F(rJanJQH`6-yWsm{Zt-lLa$EBQet!s70K<}v)tmthm%9rxGt8HSIN z{K^?oT|E9(v4GuWmyeQ5CF`m%xB~WKi9aQmlb%T_L_1x&6x<~qiO*rbT5iy2qDOfr z^vm~KMdZ;Nde!MYCzZ@YAV3)dY6=3Jgr2tJ-Z(NhJ%1TTAiQvNS))f{zY`Pmm`7m# z>SF$+`uP~#2GNic!~^Yvc+mr_Bpw%^L|zxv8tR5%L2$V+;NQfG!TFGP9$d2XvsUg> zWHC}2^RP9l^n>u%4%&zxz?9-Jcz=KWd-yh_WnO0Mo7$yA9WaiWf@mL*F`k;=71-c% zVfEngqvW)E+2UdD{F~T(l(D(-tCd%ZwUDMCaYYBsho$wL+C#Z9H;zU9Sp02}IMXi4|nrT4AkUJB`4~jBRk~`Rr$i)Z;@%uln%SWEz;={D#+6;sPrcK4ej)DB+1iT#FkMX}pkEU#SZR)kGz?(FzyKiW?CC9q53%ZP2z;3n=* z9(0rcrP%VaZtear^`_Pf<-EXRcNW(p7@4^jJJE={>mI|p(S;N&0ZnhQUhmFlw(88J8Fo3t^MK^Vf|dhv;uArymB4a>7g>3!OiVNI)uS$sCAo)n4kF|wj$?_(MNIV3vqc`lq()}xdxSm; zlQdsYrTIP%vuqo=8b?*UYOLS2@zU1Rju!dgp{4|4P|;=iVe{R&hSAL*$P1^Q&YbMMv_g=}>w;gQd#VW?X#vIOArp=;N?w{coh;vmMIn)lSH& z;X8S69f~5j{OupY@ZBUrWOii_9*s$;pR!+nbgr+T=n&uSCL_qUrhDifOaECJD27*~ z&Z>0^&l)Q!BhMeF3_23Hqc%kvS+gMU;JYQc`{^U%(e9Cb_GipF0@3&2pn5^|o&ZOS z*t}FeBW|0{v=$wGZJjDlFzt+{XyD;d&^Nhg_*@23<>&6n@NtCe)!6pdBPLzuG~9Ux zWVjTfDV^+~wAbFq-D$TSyL|J=7N1m|N}9J6&Im718@05u)5bgV-5qN`N?cOgDUsYN zm}NEM6HP3^+NIb%e)j|9?*bfI6b1stM(pXVZ=c`L=bQJ$LHWRiatTz81|W+c6Ty#8 zq~gS5c>F#;NIN*B#4bmd5i#mrd(oM@S&Ot#JV?vg*oul0g`1r%#1) zklJqi!DXy~*E_~IJt|n0VacJFdsVeZrD$pfG?a24)B(~Mb^1n4t%ZT6StxtQvmJJ8 zn#yrxIA<{aBX?PJcH%HKGJ!%PCD%&M8Z2$4j?l1zy-so0O5;@jRpToQ_4yO~%s_UR z!OI5e3(Lyo)3ecILqBMR*sQ2dr@YuI9lG-%5Mw)qS?4~Ao}=;iF;?>N#Eco*)d)-(X^%p%l{LmF|9${z=yK+kGi?$M<;%H;+WQ}P;m zDVECfGFem4aM~Q4f z+~ne*$W2P941J#f9R9sVeecZNC64mlKs6ilF}#G($}*~TI|hv`<@EP#UCnD71vEwa z9x)wvlKQCFX02dx?ty+rA+&Cq*uv9zF~B|P0pt&heBf+l12~`20FT(#4N^@})g0b@ z%S$lGb)N}N#^27Z)k0XNUX{a~ox^0Cy`A41j$?r2h1*4fkt|A}#l8z6(Z4!4?P(vED!eEqTmKee=cG{?FrEJD`EeA4k5t4&W3$E%pn{atX`Jwm%pSwJqz8p2f7U zs+;EFt#9*GZxP09Ky31j8S5Q^jgz%`TubC)^Sy>UE8Q4;sQh# zAl;yd(hbrmAPp)iUD6FocZsBmNJhy-{=T<+47aXL&^$tueO2ao=J;eVe

pJ7mK#R6u;5qW=qy;-A8C#vH0kD_-&NSjZ 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 literal 0 HcmV?d00001 diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a2ace3ec5d..5bdde4a34f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -29,7 +29,7 @@ Usage: `packages` ### Viewing a package: `info` View a specified Travel Package from the list of Packages based on the package ID. -Format: `info {package_id}` +Format: `info {package_number}` Example of usage: @@ -41,7 +41,8 @@ View list of packages sorted by ascending date or price and descending vacancies Format: `all` Example of usage: -`all` +``` +all Sort packages by: 1. Date (Earliest to Latest) @@ -49,7 +50,8 @@ Sort packages by: 3. Price 4. Return to main menu. -`Enter 1-4` +Enter 1-4 +``` @@ -57,11 +59,11 @@ Sort packages by: ### Adding a package: `add` Adds a new Travel Package to the list of Packages. -Format: `add {package_name},{package_id},{startDate},{endDate},{hotel},{price},{country},{vacancies}` +Format: `add {package_name},{package_number},{startDate},{endDate},{hotel},{price},{country},{vacancies}` * The `startDate` and `endDate` must be in the format DD/MM/YYYY. * The `price` can only contain numbers or decimal points. -* `package_id` should be unique. +* `package_number` should be unique. Example of usage: @@ -72,7 +74,7 @@ Example of usage: ### Deleting a package: `delete` Delete a Travel Package from the list of Packages based on the package ID. -Format: `delete {package_id}` +Format: `delete {package_number}` Example of usage: @@ -81,7 +83,7 @@ Example of usage: ### Placing a reservation: `reserve` Add a reservation to a Travel Package. -Format: `reserve {package_id},{contact_name},{contact_number},{number_pax}` +Format: `reserve {package_number},{contact_name},{contact_number},{number_pax}` Example of usage: @@ -90,7 +92,7 @@ Example of usage: ### Removing a reservation: `remove` Remove a reservation from a Travel Package using packageID and contact number. -Format: `remove {package_id},{contact_number}` +Format: `remove {package_number},{contact_number}` Example of usage: @@ -99,12 +101,18 @@ Example of usage: ### View reservations: `reservations` View reservations booked in a Travel Package. -Format: `reservations {package_id}` +Format: `reservations {package_number}` Example of usage: `reservations 2` +### Exit application: +Format and Usage: +``` +bye +``` + ## FAQ **Q**: How do I transfer my data to another computer? @@ -116,17 +124,17 @@ Example of usage: ## Command Summary -| Command | Syntax | -| --- | :--- | -| help | help | -| packages | packages | -| info | info {package_number} | -| all | all | -| add | add {package_name},{package_id},{startDate},{endDate},{hotel},{price},{country},{max_vacancies} | -| delete | delete {package_id} | -| reserve | reserve {package_id},{contact_name},{contact_number},{number_pax} | -| remove | remove {package_id},{conact_number} | -| reservations | reservations {package_id} | +| Command | Syntax | +| --- |:------------------------------------------------------------------------------------------------| +| help | help | +| packages | packages | +| info | info {package_number} | +| all | all | +| add | add {package_name},{package_number},{startDate},{endDate},{hotel},{price},{country},{max_vacancies} | +| delete | delete {package_number} | +| reserve | reserve {package_number},{contact_name},{contact_number},{number_pax} | +| remove | remove {package_number},{contact_number} | +| reservations | reservations {package_number} | diff --git a/src/main/java/seedu/duke/command/HelpCommand.java b/src/main/java/seedu/duke/command/HelpCommand.java index a63649a4cf..7292f1db94 100644 --- a/src/main/java/seedu/duke/command/HelpCommand.java +++ b/src/main/java/seedu/duke/command/HelpCommand.java @@ -52,6 +52,10 @@ public class HelpCommand extends Command { "Format: hotels {package_number}" + "\nUsage: hotels 1\n"; + public static final String HELP_FORMAT = "QUICK HELP\nPrint detailed instructions on " + + "the available commands that user may input\nForma and Usage: help\n"; + public static final String EXIT_FORMAT = "EXIT APPLICATION\nFormat and Usage: bye\n"; + @Override public void execute(Packages packages) { @@ -64,6 +68,8 @@ public void execute(Packages packages) { DELETE_FORMAT + SEPARATOR + RESERVATIONS_FORMAT + SEPARATOR + RESERVE_FORMAT + SEPARATOR + - REMOVE_FORMAT + SEPARATOR); + REMOVE_FORMAT + SEPARATOR + + HELP_FORMAT + SEPARATOR + + EXIT_FORMAT + SEPARATOR); } }