From 4da2e87fed9f08e5300559471778cfefbda9cefc Mon Sep 17 00:00:00 2001 From: ParasK26 Date: Mon, 29 Oct 2018 23:32:07 +0800 Subject: [PATCH 1/6] Removed ShopDay class. Working toward file system for SalesHistory --- docs/DeveloperGuide.adoc | 2 +- .../logic/commands/AddReminderCommand.java | 6 +- .../logic/commands/AddTransactionCommand.java | 7 +- .../commands/FinishedReminderCommand.java | 11 +- .../commands/ThreadDueRemindersCommand.java | 6 +- .../commands/ViewDueRemindersCommand.java | 6 +- .../commands/ViewLastTransactionCommand.java | 2 +- .../parser/AddReminderCommandParser.java | 4 +- .../parser/AddTransactionCommandParser.java | 4 +- .../parser/FinishedReminderCommandParser.java | 16 +- .../address/logic/parser/ParserUtil.java | 5 +- src/main/java/seedu/address/model/Model.java | 27 +-- .../seedu/address/model/ModelManager.java | 45 ++--- .../seedu/address/model/ProductDatabase.java | 122 ++++++------ .../model/saleshistory/SalesHistory.java | 173 ++++++++--------- .../{shopday => }/Reminder.java | 31 +-- .../TimeIdentifiedClass.java | 17 +- .../{transaction => }/Transaction.java | 23 ++- .../ClosedTransactionException.java | 2 +- .../DuplicateReminderException.java | 2 +- .../DuplicateTransactionException.java | 2 +- .../ProductQuantityMismatchException.java | 15 ++ .../shopday/BusinessDay.java | 183 ------------------ .../exceptions/ClosedShopDayException.java | 14 -- .../transaction/TransactionTest.java | 29 --- .../address/storage/SalesHistoryStorage.java | 7 + .../storage/XmlAdaptedBusinessDay.java | 9 - .../address/storage/XmlAdaptedProduct.java | 2 +- .../address/storage/XmlAdaptedReminder.java | 95 +++++++++ .../storage/XmlAdaptedSalesHistory.java | 8 - .../storage/XmlAdaptedTransaction.java | 78 ++++++-- .../seedu/address/storage/XmlFileStorage.java | 24 +++ .../storage/XmlSerializableSalesHistory.java | 106 ++++++++++ .../logic/commands/DeregisterCommandTest.java | 28 ++- .../logic/commands/LoginCommandTest.java | 20 +- .../logic/commands/LogoutCommandTest.java | 23 +-- .../logic/commands/RegisterCommandTest.java | 22 +-- 37 files changed, 594 insertions(+), 582 deletions(-) rename src/main/java/seedu/address/model/timeidentifiedclass/{shopday => }/Reminder.java (70%) rename src/main/java/seedu/address/model/timeidentifiedclass/{transaction => }/Transaction.java (82%) rename src/main/java/seedu/address/model/timeidentifiedclass/{transaction => }/exceptions/ClosedTransactionException.java (79%) rename src/main/java/seedu/address/model/timeidentifiedclass/{shopday => }/exceptions/DuplicateReminderException.java (83%) rename src/main/java/seedu/address/model/timeidentifiedclass/{shopday => }/exceptions/DuplicateTransactionException.java (86%) create mode 100644 src/main/java/seedu/address/model/timeidentifiedclass/exceptions/ProductQuantityMismatchException.java delete mode 100644 src/main/java/seedu/address/model/timeidentifiedclass/shopday/BusinessDay.java delete mode 100644 src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/ClosedShopDayException.java delete mode 100644 src/main/java/seedu/address/model/timeidentifiedclass/transaction/TransactionTest.java create mode 100644 src/main/java/seedu/address/storage/SalesHistoryStorage.java delete mode 100644 src/main/java/seedu/address/storage/XmlAdaptedBusinessDay.java create mode 100644 src/main/java/seedu/address/storage/XmlAdaptedReminder.java delete mode 100644 src/main/java/seedu/address/storage/XmlAdaptedSalesHistory.java create mode 100644 src/main/java/seedu/address/storage/XmlSerializableSalesHistory.java diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 6bae3172422c..25a7b7e95de0 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -372,7 +372,7 @@ day, that is, the active `ShopDay` in the `SalesHistory` of `AddressBook`. [NOTE] It is important to note that the `ShopDay` class stores each `Transaction` on a `TreeMap`, where each `Transaction` has -its `transactionTime` as its key. This is to facilitate quick access to any transaction on a given day, and to maintain +its `reminderTime` as its key. This is to facilitate quick access to any transaction on a given day, and to maintain the `Transaction` objects in order of their creation times within memory. ==== Alternative Implementations diff --git a/src/main/java/seedu/address/logic/commands/AddReminderCommand.java b/src/main/java/seedu/address/logic/commands/AddReminderCommand.java index 19429c27dac2..c17a4f1bbf55 100644 --- a/src/main/java/seedu/address/logic/commands/AddReminderCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddReminderCommand.java @@ -7,9 +7,9 @@ import seedu.address.logic.CommandHistory; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateReminderException; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateReminderException; /** * Adds a reminder to the Address Book. @@ -43,7 +43,7 @@ public CommandResult execute(Model model, CommandHistory history) throws Command return new CommandResult(e.getExceptionMessage()); } model.commitAddressBook(); - return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd.getMessage(), toAdd.getTime())); + return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd.getReminderMessage(), toAdd.getReminderTime())); } @Override diff --git a/src/main/java/seedu/address/logic/commands/AddTransactionCommand.java b/src/main/java/seedu/address/logic/commands/AddTransactionCommand.java index 3df27f94017d..70cf503db129 100644 --- a/src/main/java/seedu/address/logic/commands/AddTransactionCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTransactionCommand.java @@ -8,10 +8,9 @@ import seedu.address.logic.CommandHistory; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.ClosedShopDayException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateTransactionException; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; /** * Adds a transaction to the address book. @@ -43,8 +42,6 @@ public CommandResult execute(Model model, CommandHistory history) throws Command model.addTransaction(toAdd); } catch (InvalidTimeFormatException e) { return new CommandResult(e.getExceptionMessage() + ". Upon adding this transaction"); - } catch (ClosedShopDayException e) { - return new CommandResult(e.getExceptionMessage() + ". Upon adding this transaction"); } catch (DuplicateTransactionException e) { return new CommandResult(e.getLocalizedMessage() + ". Upon adding this transaction"); } diff --git a/src/main/java/seedu/address/logic/commands/FinishedReminderCommand.java b/src/main/java/seedu/address/logic/commands/FinishedReminderCommand.java index 07bda12ccbb1..0c8212194408 100644 --- a/src/main/java/seedu/address/logic/commands/FinishedReminderCommand.java +++ b/src/main/java/seedu/address/logic/commands/FinishedReminderCommand.java @@ -8,7 +8,6 @@ import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; /** * This class removes a reminder whose task has been finished @@ -25,22 +24,22 @@ public class FinishedReminderCommand extends Command { private static final String MESSAGE_SUCCESS = "Reminder at time %s successfully removed"; private static final String FAILURE_NO_SUCH_REMINDER = "No such reminder has been set"; - private final Reminder toRemove; + private final String toRemoveReminderTime; - public FinishedReminderCommand(Reminder toRemove) { - this.toRemove = toRemove; + public FinishedReminderCommand(String toRemoveReminderTime) { + this.toRemoveReminderTime = toRemoveReminderTime; } @Override public CommandResult execute(Model model, CommandHistory history) throws CommandException { try { - model.removeReminder(toRemove); + model.removeReminder(toRemoveReminderTime); } catch (InvalidTimeFormatException e) { return new CommandResult(e.getExceptionMessage() + "Upon trying to remove this reminder."); } catch (NoSuchElementException e) { return new CommandResult(FAILURE_NO_SUCH_REMINDER); } model.commitAddressBook(); - return new CommandResult(String.format(MESSAGE_SUCCESS, toRemove.getTime())); + return new CommandResult(String.format(MESSAGE_SUCCESS, toRemoveReminderTime)); } } diff --git a/src/main/java/seedu/address/logic/commands/ThreadDueRemindersCommand.java b/src/main/java/seedu/address/logic/commands/ThreadDueRemindersCommand.java index fad2abef3bc9..464274ea4177 100644 --- a/src/main/java/seedu/address/logic/commands/ThreadDueRemindersCommand.java +++ b/src/main/java/seedu/address/logic/commands/ThreadDueRemindersCommand.java @@ -5,7 +5,7 @@ import seedu.address.logic.CommandHistory; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; +import seedu.address.model.timeidentifiedclass.Reminder; /** * This command allows us to view all reminders in the active shop day that are due. @@ -19,7 +19,7 @@ public class ThreadDueRemindersCommand extends Command { @Override public CommandResult execute(Model model, CommandHistory history) throws CommandException { - ArrayList reminders = model.getDueRemindersInActiveBusinessDayForThread(); + ArrayList reminders = model.getOverdueRemindersForThread(); if (reminders.size() == 0) { return new CommandResult(NO_THREAD_REMINDERS); @@ -30,7 +30,7 @@ public CommandResult execute(Model model, CommandHistory history) throws Command allReminders.append("Reminders due:\n"); for (Reminder reminder : reminders) { - allReminders.append(reminder.getTime() + "\t\t" + reminder.getMessage() + "\n"); + allReminders.append(reminder.getReminderTime() + "\t\t" + reminder.getReminderMessage() + "\n"); } return new CommandResult(allReminders.toString()); diff --git a/src/main/java/seedu/address/logic/commands/ViewDueRemindersCommand.java b/src/main/java/seedu/address/logic/commands/ViewDueRemindersCommand.java index 3214b26d3864..cd40604a8f33 100644 --- a/src/main/java/seedu/address/logic/commands/ViewDueRemindersCommand.java +++ b/src/main/java/seedu/address/logic/commands/ViewDueRemindersCommand.java @@ -5,7 +5,7 @@ import seedu.address.logic.CommandHistory; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; +import seedu.address.model.timeidentifiedclass.Reminder; /** * This command allows us to view all reminders in the active shop day that are due. @@ -19,7 +19,7 @@ public class ViewDueRemindersCommand extends Command { @Override public CommandResult execute(Model model, CommandHistory history) throws CommandException { - ArrayList reminders = model.getDueRemindersInActiveBusinessDay(); + ArrayList reminders = model.getOverdueReminders(); if (reminders.size() == 0) { return new CommandResult(NO_REMINDERS_SET); @@ -30,7 +30,7 @@ public CommandResult execute(Model model, CommandHistory history) throws Command allReminders.append("Reminders due as of now today:\n"); for (Reminder reminder : reminders) { - allReminders.append(reminder.getTime() + "\t\t" + reminder.getMessage() + "\n"); + allReminders.append(reminder.getReminderTime() + "\t\t" + reminder.getReminderMessage() + "\n"); } return new CommandResult(allReminders.toString()); diff --git a/src/main/java/seedu/address/logic/commands/ViewLastTransactionCommand.java b/src/main/java/seedu/address/logic/commands/ViewLastTransactionCommand.java index a14792d08aeb..f3ec1a31d9d9 100644 --- a/src/main/java/seedu/address/logic/commands/ViewLastTransactionCommand.java +++ b/src/main/java/seedu/address/logic/commands/ViewLastTransactionCommand.java @@ -3,7 +3,7 @@ import seedu.address.logic.CommandHistory; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; +import seedu.address.model.timeidentifiedclass.Transaction; /** * Javadoc diff --git a/src/main/java/seedu/address/logic/parser/AddReminderCommandParser.java b/src/main/java/seedu/address/logic/parser/AddReminderCommandParser.java index 8b7538565ab2..88eeff73e953 100644 --- a/src/main/java/seedu/address/logic/parser/AddReminderCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddReminderCommandParser.java @@ -8,14 +8,12 @@ import seedu.address.logic.commands.AddReminderCommand; import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.timeidentifiedclass.Reminder; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; - /** * Parses input arguments and creates new AddReminderCommand object. */ - public class AddReminderCommandParser implements Parser { /** diff --git a/src/main/java/seedu/address/logic/parser/AddTransactionCommandParser.java b/src/main/java/seedu/address/logic/parser/AddTransactionCommandParser.java index 668708e63735..97d882ebab0a 100644 --- a/src/main/java/seedu/address/logic/parser/AddTransactionCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddTransactionCommandParser.java @@ -4,8 +4,8 @@ import seedu.address.logic.commands.AddTransactionCommand; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; -import seedu.address.model.timeidentifiedclass.transaction.exceptions.ClosedTransactionException; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.ClosedTransactionException; /** * Parses input arguments and creates a new AddTransactionCommand object diff --git a/src/main/java/seedu/address/logic/parser/FinishedReminderCommandParser.java b/src/main/java/seedu/address/logic/parser/FinishedReminderCommandParser.java index 10a972e02aa9..7ce91dcac518 100644 --- a/src/main/java/seedu/address/logic/parser/FinishedReminderCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FinishedReminderCommandParser.java @@ -7,24 +7,18 @@ import seedu.address.logic.commands.FinishedReminderCommand; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; /** * Parses the arguments for finishing a reminder task. */ public class FinishedReminderCommandParser implements Parser { - private static final String REMINDER_TO_REMOVE = "To be remove"; - /** * Parses the given {@code String} of arguments in the context of AddReminderCommand * and returns an AddReminderCommand object for execution. * @throws ParseException if the user input does not conform the expected format */ public FinishedReminderCommand parse(String args) throws ParseException { - - Reminder toRemoveReminder; ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TIME); if (!arePrefixesPresent(argMultimap, PREFIX_TIME) @@ -34,13 +28,13 @@ public FinishedReminderCommand parse(String args) throws ParseException { FinishedReminderCommand.MESSAGE_USAGE)); } + String toRemoveReminderTime; try { - toRemoveReminder = new Reminder(ParserUtil.parseReminderTime(argMultimap.getValue(PREFIX_TIME).get()), - REMINDER_TO_REMOVE); - } catch (InvalidTimeFormatException e) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, Reminder.REMINDER_TIME_CONSTRAINTS)); + toRemoveReminderTime = ParserUtil.parseReminderTime(argMultimap.getValue(PREFIX_TIME).get()); + } catch (ParseException e) { + throw e; } - return new FinishedReminderCommand(toRemoveReminder); + return new FinishedReminderCommand(toRemoveReminderTime); } /** diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index 0a0da09ab85d..a5a17c150916 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -18,8 +18,7 @@ import seedu.address.model.product.Name; import seedu.address.model.product.SerialNumber; import seedu.address.model.tag.Tag; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; +import seedu.address.model.timeidentifiedclass.Reminder; /** * Contains utility methods used for parsing strings in the various *Parser classes. @@ -66,7 +65,7 @@ public static Name parseName(String name) throws ParseException { public static String parseReminderTime(String reminderTime) throws ParseException { requireNonNull(reminderTime); String trimmedTime = reminderTime.trim(); - if (!Transaction.isValidTransactionTime(reminderTime)) { + if (!Reminder.isValidReminderTime(reminderTime)) { throw new ParseException(Reminder.REMINDER_TIME_CONSTRAINTS); } return trimmedTime; diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 8b8943035ea0..852c93006d86 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -14,12 +14,11 @@ import seedu.address.model.login.exceptions.DuplicateUserException; import seedu.address.model.login.exceptions.UserNotFoundException; import seedu.address.model.product.Product; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateReminderException; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.ClosedShopDayException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateReminderException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateTransactionException; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; /** * The API of the Model component. @@ -136,10 +135,9 @@ public interface Model { * @param transaction * @throws InvalidTimeFormatException * @throws DuplicateTransactionException - * @throws ClosedShopDayException */ void addTransaction(Transaction transaction) throws InvalidTimeFormatException, - DuplicateTransactionException, ClosedShopDayException; + DuplicateTransactionException; /** * Adds a reminder to the active business day. @@ -151,31 +149,26 @@ void addTransaction(Transaction transaction) throws InvalidTimeFormatException, /** * Removes a reminder from the active business day. - * @param reminder + * @param reminderTime * @throws InvalidTimeFormatException * @throws NoSuchElementException */ - void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException; + void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException; /** * Returns the reminders due on the current active day. */ - ArrayList getDueRemindersInActiveBusinessDay(); + ArrayList getOverdueReminders(); /** * Returns the reminders that have not been shown by the thread. */ - ArrayList getDueRemindersInActiveBusinessDayForThread(); + ArrayList getOverdueRemindersForThread(); /** * Returns a given day's transaction history */ - String getDaysHistory(String day); - - /** - * Returns the active day's transaction history - */ - String getActiveDayHistory(); + String getDaysTransactions(String day) throws InvalidTimeFormatException; /** * Returns the latest transaction. diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index c9263a5d5e60..dcc719c8cf17 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -28,13 +28,12 @@ import seedu.address.model.login.exceptions.DuplicateUserException; import seedu.address.model.login.exceptions.UserNotFoundException; import seedu.address.model.product.Product; +import seedu.address.model.timeidentifiedclass.Reminder; import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateReminderException; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.ClosedShopDayException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateReminderException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateTransactionException; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; import seedu.address.model.util.SampleDataUtil; import seedu.address.storage.Storage; @@ -335,36 +334,33 @@ public boolean equals(Object obj) { //=========================== SalesHistory accessories =================================== @Override - public String getActiveDayHistory() { - return versionedAddressBook.getActiveDayHistory(); - } - - @Override - public String getDaysHistory(String day) { - return versionedAddressBook.getDaysHistory(day); + public String getDaysTransactions(String day) throws InvalidTimeFormatException { + try { + return versionedAddressBook.getDaysTransactions(day); + } catch (InvalidTimeFormatException e) { + throw e; + } } @Override public void addTransaction(Transaction transaction) throws InvalidTimeFormatException, - ClosedShopDayException, DuplicateTransactionException { + DuplicateTransactionException { try { versionedAddressBook.addTransaction(transaction); } catch (DuplicateTransactionException e) { throw e; } catch (InvalidTimeFormatException e) { throw e; - } catch (ClosedShopDayException e) { - throw e; } } @Override public void addReminder(Reminder reminder) throws InvalidTimeFormatException, DuplicateReminderException { - if (!TimeIdentifiedClass.isValidDateAndTime(reminder.getTime())) { + if (!TimeIdentifiedClass.isValidDateAndTime(reminder.getReminderTime())) { throw new InvalidTimeFormatException(); } try { - versionedAddressBook.addReminderToActiveBusinessDay(reminder); + versionedAddressBook.addReminder(reminder); } catch (InvalidTimeFormatException e) { throw e; } catch (DuplicateReminderException e) { @@ -373,24 +369,23 @@ public void addReminder(Reminder reminder) throws InvalidTimeFormatException, Du } @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException { try { - versionedAddressBook.removeReminderFromActiveBusinessDay(reminder); + versionedAddressBook.removeReminder(reminderTime); } catch (InvalidTimeFormatException e) { throw e; - } - catch (NoSuchElementException e) { + } catch (NoSuchElementException e) { throw e; } } @Override - public ArrayList getDueRemindersInActiveBusinessDay() { - return versionedAddressBook.getDueRemindersInActiveDay(); + public ArrayList getOverdueReminders() { + return versionedAddressBook.getOverdueReminders(); } - public ArrayList getDueRemindersInActiveBusinessDayForThread() { - return versionedAddressBook.getDueRemindersInActiveDayForThread(); + public ArrayList getOverdueRemindersForThread() { + return versionedAddressBook.getOverDueRemindersForThread(); } @Override diff --git a/src/main/java/seedu/address/model/ProductDatabase.java b/src/main/java/seedu/address/model/ProductDatabase.java index 1108d3b6d16e..41fcb65b17bd 100644 --- a/src/main/java/seedu/address/model/ProductDatabase.java +++ b/src/main/java/seedu/address/model/ProductDatabase.java @@ -8,23 +8,19 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; -import java.util.TreeMap; import javafx.collections.ObservableList; import seedu.address.model.distributor.Distributor; import seedu.address.model.distributor.UniqueDistributorList; - import seedu.address.model.product.Product; import seedu.address.model.product.UniquePersonList; import seedu.address.model.saleshistory.SalesHistory; +import seedu.address.model.timeidentifiedclass.Reminder; import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateReminderException; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.BusinessDay; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.ClosedShopDayException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateReminderException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateTransactionException; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; /** * Wraps all data at the address-book level @@ -168,39 +164,41 @@ public void updateDistributor(Distributor target, Distributor editedDistributor) /** - * Adds a transaction to the active shopday. + * Adds a transaction to the active {@code salesHistory}. * @param transaction * @throws InvalidTimeFormatException - * @throws ClosedShopDayException * @throws DuplicateTransactionException */ public void addTransaction(Transaction transaction) throws InvalidTimeFormatException, - ClosedShopDayException, DuplicateTransactionException { + DuplicateTransactionException { try { salesHistory.addTransaction(transaction); } catch (InvalidTimeFormatException e) { throw e; - } catch (ClosedShopDayException e) { - throw e; } catch (DuplicateTransactionException e) { throw e; } lastTransaction = transaction; } - public String getDaysHistory(String day) { - BusinessDay requiredDay; + public String getDaysTransactions(String day) throws InvalidTimeFormatException { + ArrayList daysTransactions; try { - requiredDay = salesHistory.getDaysHistory(day); - } catch (NoSuchElementException e) { - return "Day does not exist\n"; + daysTransactions = salesHistory.getDaysTransactions(day); + } catch (InvalidTimeFormatException e) { + throw e; + } + if (daysTransactions == null || daysTransactions.isEmpty()) { + return "No transactions found on the specified date!"; + } + + StringBuilder ret = new StringBuilder(); + ret.append("TIMINGS FOR TRANSACTIONS ON " + day + "\n"); + for (Transaction transaction : daysTransactions) { + ret.append(transaction.getTransactionTime() + "\n"); } - return requiredDay.getDaysTransactions(); - } - public String getActiveDayHistory() { - BusinessDay activeDay = salesHistory.getActiveDay(); - return activeDay.getDaysTransactions(); + return ret.toString(); } public Transaction getLastTransaction() { @@ -208,34 +206,30 @@ public Transaction getLastTransaction() { } /** - * This method adds a reminder to the active shop day. + * This method adds a reminder to the {@code salesHistory}. * @param reminder * @throws InvalidTimeFormatException + * @throws DuplicateReminderException */ - public void addReminderToActiveBusinessDay(Reminder reminder) throws InvalidTimeFormatException, - DuplicateReminderException { - - if (!TimeIdentifiedClass.isValidDateAndTime(reminder.getTime())) { - throw new InvalidTimeFormatException(); - } - + public void addReminder(Reminder reminder) throws InvalidTimeFormatException, DuplicateReminderException { try { - salesHistory.getActiveDay().addReminder(reminder); + salesHistory.addReminder(reminder); + } catch (InvalidTimeFormatException e) { + throw e; } catch (DuplicateReminderException e) { throw e; } } /** - * Removes a reminder from the acitve business day. - * @param reminder + * Removes a reminder from the {@code salesHistory}. + * @param reminderTime * @throws InvalidTimeFormatException * @throws NoSuchElementException */ - public void removeReminderFromActiveBusinessDay(Reminder reminder) throws InvalidTimeFormatException, - NoSuchElementException { + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException { try { - salesHistory.removeReminder(reminder); + salesHistory.removeReminder(reminderTime); } catch (InvalidTimeFormatException e) { throw e; } catch (NoSuchElementException e) { @@ -247,43 +241,43 @@ public void removeReminderFromActiveBusinessDay(Reminder reminder) throws Invali * Returns the reminders which are due in the active day. * @return reminder list. */ - public ArrayList getDueRemindersInActiveDay() { - final TreeMap reminderRecord = salesHistory.getActiveDay().getReminderRecord(); + public ArrayList getOverdueReminders() { final String currentTime = TimeIdentifiedClass.getCurrentDateAndTime(); - ArrayList reminders = new ArrayList<>(); + Set reminderSet = salesHistory.getReminderRecord().entrySet(); + Iterator it = reminderSet.iterator(); - // To iterate through the TreeMap. - Set set = reminderRecord.entrySet(); - Iterator it = set.iterator(); + ArrayList remindersToReturn = new ArrayList<>(); - while (it.hasNext()) { - Map.Entry entry = (Map.Entry) it.next(); - String reminderTime = (String) entry.getKey(); + // set to true in order to enter subsequent while-loop + boolean isLesserTime = true; + + while (it.hasNext() && isLesserTime) { + Map.Entry reminderEntry = (Map.Entry) it.next(); + String reminderTime = (String) reminderEntry.getKey(); + Reminder reminderToAdd = (Reminder) reminderEntry.getValue(); - //checks if reminder time is lesser than or equal to the current time. - if (reminderTime.compareTo(currentTime) <= 0) { - reminders.add((Reminder) entry.getValue()); - } else { - break; + // checking if reminder time is lesser than current time + isLesserTime = (reminderTime.compareTo(currentTime) <= 0); + if (isLesserTime) { + remindersToReturn.add(reminderToAdd); } } - return reminders; + return remindersToReturn; } /** - * Returns the reminders which are due in the active day. + * Returns the reminders which are due and have not been shown by the thread, and declares them as shown by the + * thread. * @return reminder list. */ - public ArrayList getDueRemindersInActiveDayForThread() { - final TreeMap reminderRecord = salesHistory.getActiveDay().getReminderRecord(); + public ArrayList getOverDueRemindersForThread() { final String currentTime = TimeIdentifiedClass.getCurrentDateAndTime(); - ArrayList reminders = new ArrayList<>(); + Set reminderSet = salesHistory.getReminderRecord().entrySet(); + Iterator it = reminderSet.iterator(); - // To iterate through the TreeMap. - Set set = reminderRecord.entrySet(); - Iterator it = set.iterator(); + ArrayList remindersToReturn = new ArrayList<>(); // set to true to enter the following while block boolean isLesserTime = true; @@ -291,17 +285,17 @@ public ArrayList getDueRemindersInActiveDayForThread() { while (it.hasNext() && isLesserTime) { Map.Entry entry = (Map.Entry) it.next(); String reminderTime = (String) entry.getKey(); - Reminder reminder = (Reminder) entry.getValue(); + Reminder reminderToAdd = (Reminder) entry.getValue(); // true if reminder time is lesser than or equal to the current time. isLesserTime = (reminderTime.compareTo(currentTime) <= 0); - if (isLesserTime && !reminder.hasBeenShownByThread()) { - reminders.add(reminder); - reminder.declareAsShownByThread(); + if (isLesserTime && !reminderToAdd.hasBeenShownByThread()) { + remindersToReturn.add(reminderToAdd); + reminderToAdd.declareAsShownByThread(); } } - return reminders; + return remindersToReturn; } /** diff --git a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java index 7eb5c04fd803..55da9e9e0619 100644 --- a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java +++ b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java @@ -1,136 +1,129 @@ package seedu.address.model.saleshistory; +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; import java.util.NoSuchElementException; +import java.util.Set; import java.util.TreeMap; -import seedu.address.model.saleshistory.exceptions.DuplicateDayException; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateReminderException; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.BusinessDay; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.ClosedShopDayException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateTransactionException; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; /** - * This class stores all the shopDay objects, with their contained transactions. Each day must have a unique date. + * This class stores all the transactions and reminders. Each day and reminder must have a unique date. */ public class SalesHistory { - private TreeMap salesHistory; - private BusinessDay activeDay; + private TreeMap transactionRecord; + private TreeMap reminderRecord; /** - * The following constructor creates a blank sales history, with today automatically inserted. + * The following constructor creates a blank sales history. */ - public SalesHistory() { - this.salesHistory = new TreeMap<>(); - activeDay = new BusinessDay(); - salesHistory.put(activeDay.getDay(), activeDay); + this.transactionRecord = new TreeMap<>(); + this.reminderRecord = new TreeMap<>(); } /** * The following constructor is to facilitate reading sales history from files. - * @param salesHistory + * @param transactionRecord */ - - public SalesHistory(TreeMap salesHistory) { - this.salesHistory = salesHistory; - BusinessDay today = new BusinessDay(); - if (!salesHistory.containsKey(today.getDay())) { - salesHistory.put(today.getDay(), today); - } + public SalesHistory(TreeMap transactionRecord, TreeMap reminderRecord) { + requireAllNonNull(transactionRecord, reminderRecord); + this.transactionRecord = transactionRecord; + this.reminderRecord = reminderRecord; } - /** - * This method adds a day to the sales history. - * @param day - * @throws DuplicateDayException - */ - public void addDay(BusinessDay day) throws DuplicateDayException { - if (salesHistory.containsKey(day.getDay())) { - throw new DuplicateDayException(); - } - salesHistory.put(day.getDay(), day); + public TreeMap getTransactionRecord() { + return transactionRecord; } - /** - * The following method adds a day to the sales history. - * @param day - * @throws DuplicateDayException - * @throws InvalidTimeFormatException - */ - public void addDay(String day) throws DuplicateDayException, - InvalidTimeFormatException { - if (salesHistory.containsKey(day)) { - throw new DuplicateDayException(); - } - BusinessDay toBeAdded = null; - try { - toBeAdded = new BusinessDay(day); - } catch (InvalidTimeFormatException e) { - throw e; - } + public TreeMap getReminderRecord() { + return reminderRecord; } - public BusinessDay getDaysHistory(String day) throws NoSuchElementException { - try { - return salesHistory.get(day); - } catch (NullPointerException e) { - throw new NoSuchElementException(); - } - } + public ArrayList getDaysTransactions(String day) throws InvalidTimeFormatException { + requireNonNull(day); + day = day.trim(); - public BusinessDay getActiveDay() throws NoSuchElementException { - try { - return getDaysHistory(activeDay.getDay()); - } catch (NoSuchElementException e) { - throw e; + if (!TimeIdentifiedClass.isValidDay(day)) { + throw new InvalidTimeFormatException(); } - } - public void setActiveDay(BusinessDay day) { - try { - addDay(day); - activeDay = salesHistory.get(day.getDay()); - } catch (DuplicateDayException e) { - activeDay = salesHistory.get(day.getDay()); + final String initialTime = day + " 00:00:00"; + final String finalTime = day + " 24:00:00"; + + // To get the day's transactions... + ArrayList daysTransactions = new ArrayList<>(); + Set transactionSet = transactionRecord.subMap(initialTime, finalTime).entrySet(); + Iterator it = transactionSet.iterator(); + + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + daysTransactions.add((Transaction) entry.getValue()); } + return daysTransactions; } - /** - * The following method adds a transaction to the active day. + * The following method adds a transaction with a valid and unique time to the {@code transactionRecord}. * @param transaction + * @throws InvalidTimeFormatException + * @throws DuplicateTransactionException */ - public void addTransaction(Transaction transaction) throws - InvalidTimeFormatException, - ClosedShopDayException, + public void addTransaction(Transaction transaction) throws InvalidTimeFormatException, DuplicateTransactionException { - try { - activeDay.addTransaction(transaction); - } catch (InvalidTimeFormatException e) { - throw e; - } catch (ClosedShopDayException e) { - throw e; - } catch (DuplicateTransactionException e) { - throw e; + requireNonNull(transaction); + if (!Transaction.isValidTransactionTime(transaction.getTransactionTime())) { + throw new InvalidTimeFormatException(); + } + if (transactionRecord.containsKey(transaction.getTransactionTime())) { + throw new DuplicateTransactionException(); } + transactionRecord.put(transaction.getTransactionTime(), transaction); } /** - * Removes given {@code reminder} from the sales history. - * TODO Make this work for more than just the {@code activeDay} + * The following method adds a {@code reminder} with a valid and unique time to the {@code reminderRecord}. * @param reminder * @throws InvalidTimeFormatException + * @throws DuplicateReminderException + */ + public void addReminder(Reminder reminder) throws InvalidTimeFormatException, DuplicateReminderException { + requireNonNull(reminder); + if (!Reminder.isValidReminderTime(reminder.getReminderTime())) { + throw new InvalidTimeFormatException(); + } + if (reminderRecord.containsKey(reminder.getReminderTime())) { + throw new DuplicateReminderException(); + } + reminderRecord.put(reminder.getReminderTime(), reminder); + } + + /** + * Removes given {@code reminder} from the sales history. + * @param reminderTime + * @throws InvalidTimeFormatException * @throws NoSuchElementException */ - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { - try { - activeDay.removeReminder(reminder); - } catch (InvalidTimeFormatException e) { - throw e; - } catch (NoSuchElementException e) { - throw e; + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException { + requireNonNull(reminderTime); + reminderTime = reminderTime.trim(); + + if (!reminderRecord.containsKey(reminderTime)) { + throw new NoSuchElementException(); + } + if (!Reminder.isValidReminderTime(reminderTime)) { + throw new InvalidTimeFormatException(); } + reminderRecord.remove(reminderTime); } } diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/Reminder.java b/src/main/java/seedu/address/model/timeidentifiedclass/Reminder.java similarity index 70% rename from src/main/java/seedu/address/model/timeidentifiedclass/shopday/Reminder.java rename to src/main/java/seedu/address/model/timeidentifiedclass/Reminder.java index f91d44ee03de..12d564f9a089 100644 --- a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/Reminder.java +++ b/src/main/java/seedu/address/model/timeidentifiedclass/Reminder.java @@ -1,9 +1,8 @@ -package seedu.address.model.timeidentifiedclass.shopday; +package seedu.address.model.timeidentifiedclass; import static java.util.Objects.requireNonNull; import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; -import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; /** @@ -15,7 +14,7 @@ public class Reminder extends TimeIdentifiedClass { private String time; private String reminderMessage; - private boolean hasShownByThread; + private boolean hasBeenShownByThread; /** * Constructor to set a reminder with time and reminder message. @@ -26,25 +25,26 @@ public class Reminder extends TimeIdentifiedClass { public Reminder(String time, String reminderMessage) throws InvalidTimeFormatException { requireAllNonNull(time, reminderMessage); time = time.trim(); - // Reminders are set with in date and time format. - if (!super.isValidDateAndTime(time)) { + + if (!isValidReminderTime(time)) { throw new InvalidTimeFormatException(); } this.time = time; this.reminderMessage = reminderMessage.trim(); - this.hasShownByThread = false; + this.hasBeenShownByThread = false; } - public String getMessage() { + public String getReminderMessage() { return reminderMessage; } - public String getTime() { + public String getReminderTime() { return time; } /** - * The following method allows us to change the time for a reminder. + * The following method allows us to change the time for a reminder. It also resets the + * {@code hasBeenShownByThread} after changing the time. * @param time * @throws InvalidTimeFormatException */ @@ -55,6 +55,7 @@ public void changeTime(String time) throws InvalidTimeFormatException { throw new InvalidTimeFormatException(); } this.time = time; + this.hasBeenShownByThread = false; } public void changeMessage(String newMessage) { @@ -62,10 +63,18 @@ public void changeMessage(String newMessage) { } public boolean hasBeenShownByThread() { - return hasShownByThread; + return hasBeenShownByThread; } public void declareAsShownByThread() { - hasShownByThread = true; + hasBeenShownByThread = true; + } + + /** + * The given method checks if the {@code reminderTim} is in the required day and time format. + * @param reminderTime + */ + public static boolean isValidReminderTime(String reminderTime) { + return isValidDateAndTime(reminderTime); } } diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/TimeIdentifiedClass.java b/src/main/java/seedu/address/model/timeidentifiedclass/TimeIdentifiedClass.java index 74d591cd2ae2..9be961b34628 100644 --- a/src/main/java/seedu/address/model/timeidentifiedclass/TimeIdentifiedClass.java +++ b/src/main/java/seedu/address/model/timeidentifiedclass/TimeIdentifiedClass.java @@ -4,8 +4,7 @@ import java.time.format.DateTimeFormatter; /** - * Some of the classes, such as BusinessDay and Transaction, are identified using their time of creation/ - * record. + * Some of the classes, such as Reminder and Transaction, are identified using time. */ public abstract class TimeIdentifiedClass { private static final int NUMBER_OF_MONTHS_IN_YEAR = 12; @@ -14,8 +13,8 @@ public abstract class TimeIdentifiedClass { private static final int NUMBER_OF_MINUTES_IN_HOUR = 60; private static final int NUMBER_OF_SECONDS_IN_HOUR = 60; - private static DateTimeFormatter dateAndTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); - private static DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + private static DateTimeFormatter dateAndTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); + private static DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); private static LocalDateTime time; /** @@ -129,14 +128,14 @@ public static boolean isValidSecond(String second) { public static boolean isValidDateAndTime (String dateAndTime) { String[] times = dateAndTime.split("[/ \\s+ :]"); - for (int i = 0; i < 6; i++) { + for (int i = 0; i < times.length; i++) { times[i].trim(); } // checks on the different components of the transaction time. - if (isValidDay(times[0]) + if (isValidYear(times[0]) && isValidMonth(times[1]) - && isValidYear(times[2]) + && isValidDay(times[2]) && isValidHour(times[3]) && isValidMinute(times[4]) && isValidSecond(times[5])) { @@ -154,9 +153,9 @@ public static boolean isValidDate(String date) { String[] splitDate = date.split("/"); // checking the individual components of the date - if (isValidDay(splitDate[0]) + if (isValidYear(splitDate[0]) && isValidMonth(splitDate[1]) - && isValidYear(splitDate[2])) { + && isValidDay(splitDate[2])) { return true; } return false; diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/transaction/Transaction.java b/src/main/java/seedu/address/model/timeidentifiedclass/Transaction.java similarity index 82% rename from src/main/java/seedu/address/model/timeidentifiedclass/transaction/Transaction.java rename to src/main/java/seedu/address/model/timeidentifiedclass/Transaction.java index 04bd4df8733b..df5d764e9efb 100644 --- a/src/main/java/seedu/address/model/timeidentifiedclass/transaction/Transaction.java +++ b/src/main/java/seedu/address/model/timeidentifiedclass/Transaction.java @@ -1,4 +1,4 @@ -package seedu.address.model.timeidentifiedclass.transaction; +package seedu.address.model.timeidentifiedclass; import static java.util.Objects.requireNonNull; import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; @@ -8,10 +8,8 @@ import java.util.Set; import java.util.TreeMap; -import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; +import seedu.address.model.timeidentifiedclass.exceptions.ClosedTransactionException; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.transaction.exceptions.ClosedTransactionException; - /** * A basic Transaction class, where the Product is taken to be a string. This will be updated with actual Product @@ -30,7 +28,7 @@ public Transaction() { } /** - * Constructor to create transaction with given parameters. Used for reading from file. + * Constructor to create transaction with given parameters. * @param transactionTime * @param transactionRecord * @throws InvalidTimeFormatException @@ -47,6 +45,21 @@ public Transaction(String transactionTime, TreeMap transactionR this.transactionRecord = transactionRecord; } + /** + * Constructor to create a transaction object for a given time with an empty transaction record. + * @param transactionTime + * @throws InvalidTimeFormatException + */ + public Transaction(String transactionTime) throws InvalidTimeFormatException { + requireNonNull(transactionTime); + + if (!isValidTransactionTime(transactionTime)) { + throw new InvalidTimeFormatException(); + } + this.transactionTime = transactionTime; + this.transactionRecord = new TreeMap<>(); + } + public String getTransactionTime() { return transactionTime; } diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/transaction/exceptions/ClosedTransactionException.java b/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/ClosedTransactionException.java similarity index 79% rename from src/main/java/seedu/address/model/timeidentifiedclass/transaction/exceptions/ClosedTransactionException.java rename to src/main/java/seedu/address/model/timeidentifiedclass/exceptions/ClosedTransactionException.java index 3bafe3eb442b..5653f9596c53 100644 --- a/src/main/java/seedu/address/model/timeidentifiedclass/transaction/exceptions/ClosedTransactionException.java +++ b/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/ClosedTransactionException.java @@ -1,4 +1,4 @@ -package seedu.address.model.timeidentifiedclass.transaction.exceptions; +package seedu.address.model.timeidentifiedclass.exceptions; /** * TODO diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/DuplicateReminderException.java b/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/DuplicateReminderException.java similarity index 83% rename from src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/DuplicateReminderException.java rename to src/main/java/seedu/address/model/timeidentifiedclass/exceptions/DuplicateReminderException.java index bae3888ed365..6f08bc784064 100644 --- a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/DuplicateReminderException.java +++ b/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/DuplicateReminderException.java @@ -1,4 +1,4 @@ -package seedu.address.model.timeidentifiedclass.shopday.exceptions; +package seedu.address.model.timeidentifiedclass.exceptions; /** * Exception for duplicate reminders within the same day diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/DuplicateTransactionException.java b/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/DuplicateTransactionException.java similarity index 86% rename from src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/DuplicateTransactionException.java rename to src/main/java/seedu/address/model/timeidentifiedclass/exceptions/DuplicateTransactionException.java index f45f7551f99c..62e9ab8e5bd7 100644 --- a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/DuplicateTransactionException.java +++ b/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/DuplicateTransactionException.java @@ -1,4 +1,4 @@ -package seedu.address.model.timeidentifiedclass.shopday.exceptions; +package seedu.address.model.timeidentifiedclass.exceptions; /** * This class represents Exceptions that are raised when there is a duplicate transaction. diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/ProductQuantityMismatchException.java b/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/ProductQuantityMismatchException.java new file mode 100644 index 000000000000..bb0b9451210e --- /dev/null +++ b/src/main/java/seedu/address/model/timeidentifiedclass/exceptions/ProductQuantityMismatchException.java @@ -0,0 +1,15 @@ +package seedu.address.model.timeidentifiedclass.exceptions; + +/** + * This exception represents a situation in which the product name list is unequal in size to the + * product quantity list for a given transaction. + */ +public class ProductQuantityMismatchException extends Exception { + public static final String EXCEPTION_MESSAGE = "Transaction %s has product list size %s and quantity list size %s!"; + + public ProductQuantityMismatchException() {} + + public String getExceptionMessage() { + return EXCEPTION_MESSAGE; + } +} diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/BusinessDay.java b/src/main/java/seedu/address/model/timeidentifiedclass/shopday/BusinessDay.java deleted file mode 100644 index b346de30e299..000000000000 --- a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/BusinessDay.java +++ /dev/null @@ -1,183 +0,0 @@ -package seedu.address.model.timeidentifiedclass.shopday; - -import static java.util.Objects.requireNonNull; - -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.TreeMap; - -import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; -import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.ClosedShopDayException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateReminderException; -import seedu.address.model.timeidentifiedclass.shopday.exceptions.DuplicateTransactionException; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; - -/** - * This class represents one day of operation in the store, and contains the transactions - * and reminders of that day. - */ -public class BusinessDay extends TimeIdentifiedClass { - - private TreeMap salesRecord; - private TreeMap reminderRecord; - private final String date; - private boolean isActiveDay; - - /** - * The following are the class constructors. - */ - - public BusinessDay() { - this.date = super.getCurrentDate(); - this.initialise(); - } - - /** - * This constructor allows us to create a new BusinessDay object using a date. It is to facilitate - * creation of reminders. - * @param date - * @throws InvalidTimeFormatException - */ - public BusinessDay(String date) throws InvalidTimeFormatException { - requireNonNull(date); - if (isValidDayFormat(date)) { - this.date = date; - this.initialise(); - } else { - throw new InvalidTimeFormatException(); - } - } - - /** - * The following constructor is to be used to facilitate reading from files. - * @param date - * @param salesRecord - * @param reminderRecord - * @throws InvalidTimeFormatException - */ - - public BusinessDay(String date, TreeMap salesRecord, TreeMap reminderRecord) - throws InvalidTimeFormatException { - if (isValidDayFormat(date)) { - this.date = date; - this.salesRecord = salesRecord; - this.reminderRecord = reminderRecord; - } else { - throw new InvalidTimeFormatException(); - } - } - - /** - * The following method is the all-purpose initializer for a new shopDay. - */ - - private void initialise() { - this.salesRecord = new TreeMap<>(); - this.reminderRecord = new TreeMap<>(); - this.openDay(); - } - - - public String getDay() { - return this.date; - } - - /** - * The following method adds a transaction to the given BusinessDay object. - * @param transaction - * @throws InvalidTimeFormatException - * @throws ClosedShopDayException - * @throws DuplicateTransactionException - */ - - public void addTransaction(Transaction transaction) throws InvalidTimeFormatException, - ClosedShopDayException, DuplicateTransactionException { - String transactionTime = transaction.getTransactionTime(); - if (!Transaction.isValidTransactionTime(transactionTime)) { - throw new InvalidTimeFormatException(); - } - if (!this.isActiveDay) { - throw new ClosedShopDayException(); - } else if (salesRecord.containsKey(transactionTime)) { - throw new DuplicateTransactionException(); - } else { - salesRecord.put(transactionTime, transaction); - } - } - - /** - * The following method adds a reminder to the reminder record. - * @param reminder - */ - public void addReminder(Reminder reminder) throws DuplicateReminderException { - if (reminderRecord.containsKey(reminder.getTime())) { - throw new DuplicateReminderException(); - } - reminderRecord.put(reminder.getTime(), reminder); - } - - /** - * The following method removes a reminder from the reminder record. - * @param reminder - */ - - public void removeReminder(Reminder reminder)throws InvalidTimeFormatException, NoSuchElementException { - if (!reminderRecord.containsKey(reminder.getTime())) { - throw new NoSuchElementException(); - } else if (!TimeIdentifiedClass.isValidDateAndTime(reminder.getTime())) { - throw new InvalidTimeFormatException(); - } - reminderRecord.remove(reminder.getTime()); - } - - public String getDaysTransactions() { - StringBuilder ret = new StringBuilder(); - - ret.append("================== Day Record for " + this.getDay() + "==================\n"); - ret.append("TRANSACTION TIMINGS\n"); - - Set set = salesRecord.entrySet(); - Iterator it = set.iterator(); - - while (it.hasNext()) { - Map.Entry entry = (Map.Entry) it.next(); - ret.append(entry.getKey() + "\n"); - } - ret.trimToSize(); - return ret.toString(); - } - - /** - * Obtain the reminder record. - * @return reminderRecord - */ - - public TreeMap getReminderRecord() { - return reminderRecord; - } - - public void openDay() { - this.isActiveDay = true; - } - - public void closeDay() { - this.isActiveDay = false; - } - - public boolean isOpenDay() { - return isActiveDay; - } - - /** - * The following method checks whether a string is in the required date format. - * @param date - * @return true if valid format, false otherwise. - */ - public static boolean isValidDayFormat(String date) { - date = date.trim(); - return isValidDate(date); - } -} diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/ClosedShopDayException.java b/src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/ClosedShopDayException.java deleted file mode 100644 index 1b8272f86d99..000000000000 --- a/src/main/java/seedu/address/model/timeidentifiedclass/shopday/exceptions/ClosedShopDayException.java +++ /dev/null @@ -1,14 +0,0 @@ -package seedu.address.model.timeidentifiedclass.shopday.exceptions; - -/** - * todo - */ -public class ClosedShopDayException extends Exception { - private static final String EXCEPTION_MESSAGE = "Unable to alter a day that is in the past!"; - - public ClosedShopDayException() {} - - public String getExceptionMessage() { - return EXCEPTION_MESSAGE; - } -} diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/transaction/TransactionTest.java b/src/main/java/seedu/address/model/timeidentifiedclass/transaction/TransactionTest.java deleted file mode 100644 index fc51cf8a18b2..000000000000 --- a/src/main/java/seedu/address/model/timeidentifiedclass/transaction/TransactionTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package seedu.address.model.timeidentifiedclass.transaction; - -import seedu.address.model.timeidentifiedclass.transaction.exceptions.ClosedTransactionException; - -/** - * This program checks if Transaction objects behave as they should. If all is well, it should output the current time - * as output on the terminal. - */ -public class TransactionTest { - /** - * todo - */ - public static void main(String[] args) { - Transaction transaction = new Transaction(); - System.out.println(transaction.getTransactionTime()); - try { - for (char i = 'a'; i < 'a' + 5; i++) { - transaction.addProduct("" + i); - transaction.addProduct("" + i); - } - transaction.closeTransaction(); - transaction.addProduct("should not add"); - } catch (ClosedTransactionException c) { - System.out.println("Successfully caught ClosedTransactionException"); - } - System.out.println(transaction.getTransactionRecordAsString()); - System.out.println("Expected output consists of a,b,c,d,e, all of quantity 2."); - } -} diff --git a/src/main/java/seedu/address/storage/SalesHistoryStorage.java b/src/main/java/seedu/address/storage/SalesHistoryStorage.java new file mode 100644 index 000000000000..67b43fa6d027 --- /dev/null +++ b/src/main/java/seedu/address/storage/SalesHistoryStorage.java @@ -0,0 +1,7 @@ +package seedu.address.storage; + +/** + * Interface for the {@code SalesHistory} storage. + */ +public interface SalesHistoryStorage { +} diff --git a/src/main/java/seedu/address/storage/XmlAdaptedBusinessDay.java b/src/main/java/seedu/address/storage/XmlAdaptedBusinessDay.java deleted file mode 100644 index 1acce1a8ad3a..000000000000 --- a/src/main/java/seedu/address/storage/XmlAdaptedBusinessDay.java +++ /dev/null @@ -1,9 +0,0 @@ -package seedu.address.storage; - -/** - * JAXB-friendly version of BusinessDay. - */ - -public class XmlAdaptedBusinessDay { - -} diff --git a/src/main/java/seedu/address/storage/XmlAdaptedProduct.java b/src/main/java/seedu/address/storage/XmlAdaptedProduct.java index 5b4d753815a1..7c1c704d8737 100644 --- a/src/main/java/seedu/address/storage/XmlAdaptedProduct.java +++ b/src/main/java/seedu/address/storage/XmlAdaptedProduct.java @@ -37,7 +37,7 @@ public class XmlAdaptedProduct { private List tagged = new ArrayList<>(); /** - * Constructs an XmlAdaptedProduct. + * Constructs an {@code XmlAdaptedProduct}. * This is the no-arg constructor that is required by JAXB. */ public XmlAdaptedProduct() {} diff --git a/src/main/java/seedu/address/storage/XmlAdaptedReminder.java b/src/main/java/seedu/address/storage/XmlAdaptedReminder.java new file mode 100644 index 000000000000..b057c5500729 --- /dev/null +++ b/src/main/java/seedu/address/storage/XmlAdaptedReminder.java @@ -0,0 +1,95 @@ +package seedu.address.storage; + +import java.util.Objects; +import javax.xml.bind.annotation.XmlElement; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; + +/** + * This class adapts Transaction for JAXB. + */ + +public class XmlAdaptedReminder { + + private static final String INCORRECT_REMINDER_TIME_MESSAGE_FORMAT = "Incorrect reminder time of %s found!"; + private static final String MISSING_FIELD_MESSAGE_FORMAT = "Reminders' %s field is missing!"; + + @XmlElement(required = true) + private String reminderTime; + @XmlElement(required = true) + private String reminderMessage; + + /** + * Constructs an {@code XmlAdaptedReminder}. + * This is the no-arg constructor that is required by JAXB. + */ + public XmlAdaptedReminder() {} + + /** + * Constructs an {@code XmlAdaptedReminder} with the required reminder details. + * + * @param reminderTime + * @param reminderMessage + */ + + public XmlAdaptedReminder(String reminderTime, String reminderMessage) { + this.reminderTime = reminderTime; + this.reminderMessage = reminderMessage; + } + + /** + * Converts a given reminder into this class for JAXB use. + * + * @param reminder + */ + + public XmlAdaptedReminder(Reminder reminder) { + reminderTime = reminder.getReminderTime(); + reminderMessage = reminder.getReminderMessage(); + } + + /** + * This method converts the XmlAdaptedReminder into a Transacation object, and returns it. + * @return reminder + * @throws IllegalValueException + */ + + public Reminder toModelType() throws IllegalValueException { + + if (reminderTime == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "reminder time")); + } + + if (reminderMessage == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "reminder message")); + } + + Reminder reminder; + + try { + reminder = new Reminder(reminderTime, reminderMessage); + } catch (InvalidTimeFormatException e) { + throw new IllegalValueException(String.format(INCORRECT_REMINDER_TIME_MESSAGE_FORMAT, + reminderTime)); + } + return reminder; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof XmlAdaptedReminder)) { + return false; + } + + XmlAdaptedReminder otherReminder = (XmlAdaptedReminder) other; + return Objects.equals(reminderMessage, otherReminder.reminderMessage) + && Objects.equals(reminderTime, otherReminder.reminderTime); + } + +} diff --git a/src/main/java/seedu/address/storage/XmlAdaptedSalesHistory.java b/src/main/java/seedu/address/storage/XmlAdaptedSalesHistory.java deleted file mode 100644 index 704c02f78ae7..000000000000 --- a/src/main/java/seedu/address/storage/XmlAdaptedSalesHistory.java +++ /dev/null @@ -1,8 +0,0 @@ -package seedu.address.storage; - -/** - * JAXB-friendly version of SalesHistory - */ -public class XmlAdaptedSalesHistory { - -} diff --git a/src/main/java/seedu/address/storage/XmlAdaptedTransaction.java b/src/main/java/seedu/address/storage/XmlAdaptedTransaction.java index 0607fbdae4c5..d86867ba7d1b 100644 --- a/src/main/java/seedu/address/storage/XmlAdaptedTransaction.java +++ b/src/main/java/seedu/address/storage/XmlAdaptedTransaction.java @@ -1,12 +1,17 @@ package seedu.address.storage; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Objects; -import java.util.TreeMap; +import java.util.Set; import javax.xml.bind.annotation.XmlElement; import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.ClosedTransactionException; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; + /** * This class adapts Transaction for JAXB. @@ -16,29 +21,36 @@ public class XmlAdaptedTransaction { private static final String INCORRECT_TRANSACTION_TIME_MESSAGE_FORMAT = "Incorrect transaction time of %s found!"; private static final String MISSING_FIELD_MESSAGE_FORMAT = "Transaction's %s field is missing!"; + private static final String PRODUCT_QUANTITY_MISMATCH_MESSAGE = "Transaction %s " + + "has unequal product and quantity list sizes!\n" + + "Product list size: %s" + + "Quantity list size: %s"; + private static final String TRANSACTION_CLOSED_ERROR_MESSAGE = "Transaction %s was set as closed!"; @XmlElement(required = true) private String transactionTime; @XmlElement(required = true) - private TreeMap transactionRecord; + private List productNames; + @XmlElement(required = true) + private List productQuantities; /** - * Constructs an XmlAdaptedTransaction. + * Constructs an XmlAdaptedReminder. * This is the no-arg constructor that is required by JAXB. */ - public XmlAdaptedTransaction() { - } + public XmlAdaptedTransaction() {} /** - * Constructs an {@code XmlAdaptedTransaction} with the required transaction details. - * + * Constructs an {@code XmlAdaptedReminder} with the required transaction details. * @param transactionTime - * @param transactionRecord + * @param productNames + * @param productQuantities */ - public XmlAdaptedTransaction(String transactionTime, TreeMap transactionRecord) { + public XmlAdaptedTransaction(String transactionTime, List productNames, List productQuantities) { this.transactionTime = transactionTime; - this.transactionRecord = transactionRecord; + this.productNames = productNames; + this.productQuantities = productQuantities; } /** @@ -49,28 +61,55 @@ public XmlAdaptedTransaction(String transactionTime, TreeMap tr public XmlAdaptedTransaction(Transaction transaction) { transactionTime = transaction.getTransactionTime(); - transactionRecord = transaction.getTransactionRecord(); + + Set transactionSet = transaction.getTransactionRecord().entrySet(); + Iterator it = transactionSet.iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + productNames.add((String) entry.getKey()); + productQuantities.add(entry.getValue().toString()); + } } /** - * This method converts the XmlAdaptedTransaction into a Transacation object, and returns it. + * This method converts the XmlAdaptedReminder into a Transacation object, and returns it. * @return transaction * @throws IllegalValueException */ public Transaction toModelType() throws IllegalValueException { - if (transactionRecord == null) { - throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "transaction records")); + if (transactionTime == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "transaction time")); + } + + if (productNames == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "product names")); + } + + if (productQuantities == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "product quantities")); + } + + if (productNames.size() != productQuantities.size()) { + throw new IllegalValueException(String.format(PRODUCT_QUANTITY_MISMATCH_MESSAGE, + transactionTime, productNames.size(), productQuantities.size())); } Transaction transaction; try { - transaction = new Transaction(transactionTime, transactionRecord); + transaction = new Transaction(transactionTime); + transaction.openTransaction(); + + for (int i = 0; i < productNames.size(); i++) { + transaction.addProduct(productNames.get(i), Integer.parseInt(productQuantities.get(i))); + } } catch (InvalidTimeFormatException e) { throw new IllegalValueException(String.format(INCORRECT_TRANSACTION_TIME_MESSAGE_FORMAT, - "transaction time")); + transactionTime)); + } catch (ClosedTransactionException e) { + throw new IllegalValueException(String.format(TRANSACTION_CLOSED_ERROR_MESSAGE, transactionTime)); } return transaction; } @@ -81,12 +120,13 @@ public boolean equals(Object other) { return true; } - if (!(other instanceof XmlAdaptedTransaction)) { + if (!(other instanceof XmlAdaptedReminder)) { return false; } XmlAdaptedTransaction otherTransaction = (XmlAdaptedTransaction) other; - return Objects.equals(transactionRecord, otherTransaction.transactionRecord) + return Objects.equals(productNames, otherTransaction.productNames) + && Objects.equals(productQuantities, otherTransaction.productQuantities) && Objects.equals(transactionTime, otherTransaction.transactionTime); } diff --git a/src/main/java/seedu/address/storage/XmlFileStorage.java b/src/main/java/seedu/address/storage/XmlFileStorage.java index 84b94e881c41..9217d96f3113 100644 --- a/src/main/java/seedu/address/storage/XmlFileStorage.java +++ b/src/main/java/seedu/address/storage/XmlFileStorage.java @@ -59,4 +59,28 @@ public static XmlSerializableUserDatabase loadUsersFromSaveFile(Path file) throw } } + /** + * Saves the {@code SalesHistory} data to the specified file + */ + public static void saveSalesHistoryToFile(Path file, XmlSerializableSalesHistory salesHistory) + throws FileNotFoundException { + try { + XmlUtil.saveDataToFile(file, salesHistory); + } catch (JAXBException e) { + throw new AssertionError("Unexpected exception " + e.getMessage(), e); + } + } + + /** + * Returns {@code XmlSerializableSalesHistory} from the file. + */ + public static XmlSerializableSalesHistory loadSalesHistoryFromFile(Path file) throws DataConversionException, + FileNotFoundException { + try { + return XmlUtil.getDataFromFile(file, XmlSerializableSalesHistory.class); + } catch (JAXBException e) { + throw new DataConversionException(e); + } + } + } diff --git a/src/main/java/seedu/address/storage/XmlSerializableSalesHistory.java b/src/main/java/seedu/address/storage/XmlSerializableSalesHistory.java new file mode 100644 index 000000000000..ef4a416c9df5 --- /dev/null +++ b/src/main/java/seedu/address/storage/XmlSerializableSalesHistory.java @@ -0,0 +1,106 @@ +package seedu.address.storage; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.saleshistory.SalesHistory; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.Transaction; + +/** + * JAXB-friendly version of {@code SalesHistory} + */ +@XmlRootElement(name = "SalesHistory") +public class XmlSerializableSalesHistory { + + private static final String DUPLICATE_TIMINGS_MESSAGE = "Duplicate %s timings found!"; + + @XmlElement + private List transactionList; + @XmlElement + private List reminderList; + + /** + * Constructs an {@code XmlSerializableSalesHistory}. + * This is the no-arg constructor that is required for marshalling. + */ + public XmlSerializableSalesHistory() { + transactionList = new ArrayList<>(); + reminderList = new ArrayList<>(); + } + + /** + * Constructs an {@code XmlSerializableSalesHistory} with the required details. + */ + public XmlSerializableSalesHistory(List transactionList, + List reminderList) { + if (transactionList != null) { + this.transactionList = new ArrayList<>(transactionList); + } + if (reminderList != null) { + this.reminderList = new ArrayList<>(reminderList); + } + } + + /** + * Converts a given SalesHistory object into this class for JAXB use. + * @param salesHistory + */ + public XmlSerializableSalesHistory(SalesHistory salesHistory) { + transactionList = new ArrayList<>(); + reminderList = new ArrayList<>(); + + Set transactionSet = salesHistory.getTransactionRecord().entrySet(); + Iterator it = transactionSet.iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + XmlAdaptedTransaction toAdd = new XmlAdaptedTransaction((Transaction) entry.getValue()); + transactionList.add(toAdd); + } + + Set reminderSet = salesHistory.getReminderRecord().entrySet(); + it = reminderSet.iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + XmlAdaptedReminder toAdd = new XmlAdaptedReminder((Reminder) entry.getValue()); + reminderList.add(toAdd); + } + } + + /** + * Converts object of this class into {@code SalesHistory} class + * @return salesHistory + * @throws IllegalValueException + */ + public SalesHistory toModelType() throws IllegalValueException { + TreeMap transactionTreeMap = new TreeMap<>(); + TreeMap reminderTreeMap = new TreeMap<>(); + + for (XmlAdaptedTransaction xmlTransaction : transactionList) { + Transaction transaction = xmlTransaction.toModelType(); + if (transactionTreeMap.containsKey(transaction.getTransactionTime())) { + throw new IllegalValueException(String.format(DUPLICATE_TIMINGS_MESSAGE, + Transaction.class.getSimpleName())); + } + transactionTreeMap.put(transaction.getTransactionTime(), transaction); + } + + for (XmlAdaptedReminder xmlReminder : reminderList) { + Reminder reminder = xmlReminder.toModelType(); + if (reminderTreeMap.containsKey(reminder.getReminderTime())) { + throw new IllegalValueException(String.format(DUPLICATE_TIMINGS_MESSAGE, + Reminder.class.getSimpleName())); + } + reminderTreeMap.put(reminder.getReminderTime(), reminder); + } + + return new SalesHistory(transactionTreeMap, reminderTreeMap); + } +} diff --git a/src/test/java/seedu/address/logic/commands/DeregisterCommandTest.java b/src/test/java/seedu/address/logic/commands/DeregisterCommandTest.java index b0219f64fda6..647a2b6e118a 100644 --- a/src/test/java/seedu/address/logic/commands/DeregisterCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeregisterCommandTest.java @@ -27,9 +27,9 @@ import seedu.address.model.login.exceptions.DuplicateUserException; import seedu.address.model.login.exceptions.UserNotFoundException; import seedu.address.model.product.Product; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.Transaction; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; public class DeregisterCommandTest { @@ -263,17 +263,17 @@ public void addReminder(Reminder reminder) { fail("This method should not be called."); } - public ArrayList getDueRemindersInActiveBusinessDay() { + public ArrayList getOverdueReminders() { fail("This method should not be called."); return null; } - public String getDaysHistory(String day) { + public String getDaysTransactions(String day) { fail("This method should not be called."); return null; } - public String getActiveDayHistory() { + public String getDaysTransactions() { fail("This method should not be called."); return null; } @@ -292,12 +292,10 @@ private class ModelStubAcceptingDeleteUser extends DeregisterCommandTest.ModelSt final ArrayList usersAdded = new ArrayList<>(); @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { - throw new InvalidTimeFormatException(); - } + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException {} @Override - public ArrayList getDueRemindersInActiveBusinessDayForThread() { + public ArrayList getOverdueRemindersForThread() { return null; } @@ -316,12 +314,10 @@ public void deleteUser(User user) throws UserNotFoundException { private class ModelStubThrowingUserNotFoundException extends DeregisterCommandTest.ModelStub { @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { - throw new InvalidTimeFormatException(); - } + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException {} @Override - public ArrayList getDueRemindersInActiveBusinessDayForThread() { + public ArrayList getOverdueRemindersForThread() { return null; } @@ -338,12 +334,10 @@ public void deleteUser(User user) throws UserNotFoundException { private class ModelStubThrowingAuthenticationFailedException extends DeregisterCommandTest.ModelStub { @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { - throw new InvalidTimeFormatException(); - } + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException {} @Override - public ArrayList getDueRemindersInActiveBusinessDayForThread() { + public ArrayList getOverdueRemindersForThread() { return null; } diff --git a/src/test/java/seedu/address/logic/commands/LoginCommandTest.java b/src/test/java/seedu/address/logic/commands/LoginCommandTest.java index 56025fd49792..f00c23456953 100644 --- a/src/test/java/seedu/address/logic/commands/LoginCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/LoginCommandTest.java @@ -27,9 +27,9 @@ import seedu.address.model.login.exceptions.DuplicateUserException; import seedu.address.model.login.exceptions.UserNotFoundException; import seedu.address.model.product.Product; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.Transaction; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; public class LoginCommandTest { @@ -260,17 +260,17 @@ public void addReminder(Reminder reminder) { fail("This method should not be called."); } - public ArrayList getDueRemindersInActiveBusinessDay() { + public ArrayList getOverdueReminders() { fail("This method should not be called."); return null; } - public String getDaysHistory(String day) { + public String getDaysTransactions(String day) { fail("This method should not be called."); return null; } - public String getActiveDayHistory() { + public String getDaysTransactions() { fail("This method should not be called."); return null; } @@ -290,12 +290,12 @@ private class ModelStubAcceptingLogin extends ModelStub { private boolean loginStatus = false; @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException { throw new InvalidTimeFormatException(); } @Override - public ArrayList getDueRemindersInActiveBusinessDayForThread() { + public ArrayList getOverdueRemindersForThread() { return null; } @@ -324,12 +324,10 @@ public boolean hasLoggedIn() { private class ModelStubThrowingAuthenticatedException extends ModelStub { @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { - throw new InvalidTimeFormatException(); - } + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException {} @Override - public ArrayList getDueRemindersInActiveBusinessDayForThread() { + public ArrayList getOverdueRemindersForThread() { return null; } diff --git a/src/test/java/seedu/address/logic/commands/LogoutCommandTest.java b/src/test/java/seedu/address/logic/commands/LogoutCommandTest.java index a966b720ccca..34a5e07fdd0d 100644 --- a/src/test/java/seedu/address/logic/commands/LogoutCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/LogoutCommandTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.fail; import java.util.ArrayList; -import java.util.NoSuchElementException; import java.util.function.Predicate; import org.junit.Rule; @@ -25,9 +24,8 @@ import seedu.address.model.login.exceptions.DuplicateUserException; import seedu.address.model.login.exceptions.UserNotFoundException; import seedu.address.model.product.Product; -import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.Transaction; public class LogoutCommandTest { @@ -229,17 +227,21 @@ public void addReminder(Reminder reminder) { fail("This method should not be called."); } - public ArrayList getDueRemindersInActiveBusinessDay() { + public void removeReminder(String reminderTime) { + fail("This method should not be called."); + } + + public ArrayList getOverdueReminders() { fail("This method should not be called."); return null; } - public String getDaysHistory(String day) { + public String getDaysTransactions(String day) { fail("This method should not be called."); return null; } - public String getActiveDayHistory() { + public String getDaysTransactions() { fail("This method should not be called."); return null; } @@ -259,12 +261,7 @@ private class ModelStubAcceptingLogout extends ModelStub { private boolean loginStatus = false; @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { - throw new InvalidTimeFormatException(); - } - - @Override - public ArrayList getDueRemindersInActiveBusinessDayForThread() { + public ArrayList getOverdueRemindersForThread() { return null; } diff --git a/src/test/java/seedu/address/logic/commands/RegisterCommandTest.java b/src/test/java/seedu/address/logic/commands/RegisterCommandTest.java index e499047a2a11..152af4fe31db 100644 --- a/src/test/java/seedu/address/logic/commands/RegisterCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/RegisterCommandTest.java @@ -26,9 +26,9 @@ import seedu.address.model.login.exceptions.DuplicateUserException; import seedu.address.model.login.exceptions.UserNotFoundException; import seedu.address.model.product.Product; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.Transaction; import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; -import seedu.address.model.timeidentifiedclass.shopday.Reminder; -import seedu.address.model.timeidentifiedclass.transaction.Transaction; public class RegisterCommandTest { @@ -254,17 +254,17 @@ public void addReminder(Reminder reminder) { fail("This method should not be called."); } - public ArrayList getDueRemindersInActiveBusinessDay() { + public ArrayList getOverdueReminders() { fail("This method should not be called."); return null; } - public String getDaysHistory(String day) { + public String getDaysTransactions(String day) { fail("This method should not be called."); return null; } - public String getActiveDayHistory() { + public String getDaysTransactions() { fail("This method should not be called."); return null; } @@ -283,12 +283,10 @@ private class ModelStubAcceptingRegisterUser extends RegisterCommandTest.ModelSt final ArrayList usersAdded = new ArrayList<>(); @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { - throw new InvalidTimeFormatException(); - } + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException {} @Override - public ArrayList getDueRemindersInActiveBusinessDayForThread() { + public ArrayList getOverdueRemindersForThread() { return null; } @@ -306,12 +304,10 @@ public void addUser(User user) throws DuplicateUserException { private class ModelStubThrowingDuplicateUserException extends RegisterCommandTest.ModelStub { @Override - public void removeReminder(Reminder reminder) throws InvalidTimeFormatException, NoSuchElementException { - throw new InvalidTimeFormatException(); - } + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException {} @Override - public ArrayList getDueRemindersInActiveBusinessDayForThread() { + public ArrayList getOverdueRemindersForThread() { return null; } From a2b641f4bd245ab2c9e544ed2a73a85e58f7ebe1 Mon Sep 17 00:00:00 2001 From: ParasK26 Date: Tue, 30 Oct 2018 22:19:01 +0800 Subject: [PATCH 2/6] Created VersionedSalesHistory, SalesHistoryStorage. --- .../model/SalesHistoryChangedEvent.java | 19 +++++ .../seedu/address/model/ProductDatabase.java | 6 ++ .../address/model/VersionedSalesHistory.java | 37 +++++++++ .../saleshistory/ReadOnlySalesHistory.java | 18 +++++ .../model/saleshistory/SalesHistory.java | 78 +++++++++++++++++-- .../address/storage/SalesHistoryStorage.java | 41 +++++++++- .../java/seedu/address/storage/Storage.java | 23 +++++- .../seedu/address/storage/StorageManager.java | 44 ++++++++++- .../storage/XmlSalesHistoryStorage.java | 73 +++++++++++++++++ .../storage/XmlSerializableSalesHistory.java | 11 +++ 10 files changed, 340 insertions(+), 10 deletions(-) create mode 100644 src/main/java/seedu/address/commons/events/model/SalesHistoryChangedEvent.java create mode 100644 src/main/java/seedu/address/model/VersionedSalesHistory.java create mode 100644 src/main/java/seedu/address/model/saleshistory/ReadOnlySalesHistory.java create mode 100644 src/main/java/seedu/address/storage/XmlSalesHistoryStorage.java diff --git a/src/main/java/seedu/address/commons/events/model/SalesHistoryChangedEvent.java b/src/main/java/seedu/address/commons/events/model/SalesHistoryChangedEvent.java new file mode 100644 index 000000000000..6fc025603e4a --- /dev/null +++ b/src/main/java/seedu/address/commons/events/model/SalesHistoryChangedEvent.java @@ -0,0 +1,19 @@ +package seedu.address.commons.events.model; + +import seedu.address.commons.events.BaseEvent; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; + +public class SalesHistoryChangedEvent extends BaseEvent { + + public final ReadOnlySalesHistory data; + + public SalesHistoryChangedEvent(ReadOnlySalesHistory data) { + this.data = data; + } + + @Override + public String toString() { + return "number of transactions: " + data.getTransactionsAsObservableList().size() + + " number of reminders: " + data.getRemindersAsObservableList().size(); + } +} diff --git a/src/main/java/seedu/address/model/ProductDatabase.java b/src/main/java/seedu/address/model/ProductDatabase.java index 41fcb65b17bd..e96dcd7bfe6d 100644 --- a/src/main/java/seedu/address/model/ProductDatabase.java +++ b/src/main/java/seedu/address/model/ProductDatabase.java @@ -162,6 +162,12 @@ public void updateDistributor(Distributor target, Distributor editedDistributor) distributors.setDistributor(target, editedDistributor); } + /** + * Getter for {@code salesHistory} + */ + public SalesHistory getSalesHistory() { + return salesHistory; + } /** * Adds a transaction to the active {@code salesHistory}. diff --git a/src/main/java/seedu/address/model/VersionedSalesHistory.java b/src/main/java/seedu/address/model/VersionedSalesHistory.java new file mode 100644 index 000000000000..9924c84e3c5c --- /dev/null +++ b/src/main/java/seedu/address/model/VersionedSalesHistory.java @@ -0,0 +1,37 @@ +package seedu.address.model; + +import java.util.ArrayList; +import java.util.List; + +import seedu.address.model.saleshistory.ReadOnlySalesHistory; +import seedu.address.model.saleshistory.SalesHistory; + +/** + * {@link SalesHistory} that keeps track fo its own history. + */ +public class VersionedSalesHistory extends SalesHistory { + private final List salesHistoriesStateList; + private int currentStatePointer; + + public VersionedSalesHistory(ReadOnlySalesHistory initialState) { + super(initialState); + + salesHistoriesStateList = new ArrayList<>(); + salesHistoriesStateList.add(initialState); + currentStatePointer = 0; + } + + /** + * Saves a copy of the current {@code SalesHistory} state at the end of the state list + * Undone states are removed from the state list. + */ + public void commit() { + removeStatesAfterCurrentPointer(); + salesHistoriesStateList.add(new SalesHistory(this)); + currentStatePointer++; + } + + private void removeStatesAfterCurrentPointer() { + salesHistoriesStateList.subList(currentStatePointer + 1, salesHistoriesStateList.size()).clear();; + } +} diff --git a/src/main/java/seedu/address/model/saleshistory/ReadOnlySalesHistory.java b/src/main/java/seedu/address/model/saleshistory/ReadOnlySalesHistory.java new file mode 100644 index 000000000000..c8a40e44535e --- /dev/null +++ b/src/main/java/seedu/address/model/saleshistory/ReadOnlySalesHistory.java @@ -0,0 +1,18 @@ +package seedu.address.model.saleshistory; + +import javafx.collections.ObservableList; +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.Transaction; + +/** + * Unmodifiable view of the {@link SalesHistory} + */ +public interface ReadOnlySalesHistory { + + /** + * Returns an unmodifiable view of the transactionRecord and reminderRecord + */ + ObservableList getTransactionsAsObservableList(); + + ObservableList getRemindersAsObservableList(); +} diff --git a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java index 55da9e9e0619..424c81c40341 100644 --- a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java +++ b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java @@ -10,6 +10,9 @@ import java.util.Set; import java.util.TreeMap; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import seedu.address.model.timeidentifiedclass.Reminder; import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; import seedu.address.model.timeidentifiedclass.Transaction; @@ -20,26 +23,71 @@ /** * This class stores all the transactions and reminders. Each day and reminder must have a unique date. */ -public class SalesHistory { +public class SalesHistory implements ReadOnlySalesHistory { private TreeMap transactionRecord; private TreeMap reminderRecord; - + private ObservableList transactionObservableList; + private ObservableList reminderObservableList; /** * The following constructor creates a blank sales history. */ public SalesHistory() { this.transactionRecord = new TreeMap<>(); this.reminderRecord = new TreeMap<>(); + this.transactionObservableList = FXCollections.observableArrayList(); + this.reminderObservableList = FXCollections.observableArrayList(); } /** - * The following constructor is to facilitate reading sales history from files. - * @param transactionRecord + * Creates {@code SalesHistory} given {@code transactionRecord} and {@code salesHistory} */ public SalesHistory(TreeMap transactionRecord, TreeMap reminderRecord) { requireAllNonNull(transactionRecord, reminderRecord); this.transactionRecord = transactionRecord; this.reminderRecord = reminderRecord; + this.transactionObservableList = FXCollections.observableArrayList(); + this.reminderObservableList = FXCollections.observableArrayList(); + + Iterator it = reminderRecord.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + reminderObservableList.add((Reminder) entry.getValue()); + } + + it = transactionRecord.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + transactionObservableList.add((Transaction) entry.getValue()); + } + + } + + /** + * Constructor using {@code ReadOnlySalesHistory} object. + */ + public SalesHistory(ReadOnlySalesHistory toBeCopied) { + this(); + requireNonNull(toBeCopied); + + for (Transaction transaction : toBeCopied.getTransactionsAsObservableList()) { + try { + addTransaction(transaction); + } catch (InvalidTimeFormatException e) { + e.printStackTrace(); + } catch (DuplicateTransactionException e) { + e.printStackTrace(); + } + } + + for (Reminder reminder : toBeCopied.getRemindersAsObservableList()) { + try { + addReminder(reminder); + } catch (InvalidTimeFormatException e) { + e.printStackTrace(); + } catch (DuplicateReminderException e) { + e.printStackTrace(); + } + } } public TreeMap getTransactionRecord() { @@ -89,6 +137,7 @@ public void addTransaction(Transaction transaction) throws InvalidTimeFormatExce throw new DuplicateTransactionException(); } transactionRecord.put(transaction.getTransactionTime(), transaction); + transactionObservableList.add(transaction); } /** @@ -106,6 +155,7 @@ public void addReminder(Reminder reminder) throws InvalidTimeFormatException, Du throw new DuplicateReminderException(); } reminderRecord.put(reminder.getReminderTime(), reminder); + reminderObservableList.add(reminder); } /** @@ -118,12 +168,26 @@ public void removeReminder(String reminderTime) throws InvalidTimeFormatExceptio requireNonNull(reminderTime); reminderTime = reminderTime.trim(); - if (!reminderRecord.containsKey(reminderTime)) { - throw new NoSuchElementException(); - } if (!Reminder.isValidReminderTime(reminderTime)) { throw new InvalidTimeFormatException(); } + + if (!reminderRecord.containsKey(reminderTime)) { + throw new NoSuchElementException(); + } + + Reminder toRemove = reminderRecord.get(reminderTime); reminderRecord.remove(reminderTime); + reminderObservableList.remove(toRemove); + } + + @Override + public ObservableList getTransactionsAsObservableList() { + return FXCollections.unmodifiableObservableList(transactionObservableList); + } + + @Override + public ObservableList getRemindersAsObservableList() { + return FXCollections.unmodifiableObservableList(reminderObservableList); } } diff --git a/src/main/java/seedu/address/storage/SalesHistoryStorage.java b/src/main/java/seedu/address/storage/SalesHistoryStorage.java index 67b43fa6d027..2bef02e2dfcc 100644 --- a/src/main/java/seedu/address/storage/SalesHistoryStorage.java +++ b/src/main/java/seedu/address/storage/SalesHistoryStorage.java @@ -1,7 +1,46 @@ package seedu.address.storage; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Optional; + +import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; +import seedu.address.model.saleshistory.SalesHistory; + /** - * Interface for the {@code SalesHistory} storage. + * Interface for the {@link SalesHistory} storage. */ public interface SalesHistoryStorage { + /** + * Returns the file path of the data file. + */ + Path getSalesHistoryFilePath(); + + /** + * Returns {@link SalesHistory} data as a {@link ReadOnlySalesHistory} + * Returns {@code Optional.empty()} if storage file is not found. + * @throws DataConversionException if the data in storage is not in the expected format. + * @throws IOException if there was any problem when reading from the storage. + */ + Optional readSalesHistory() throws DataConversionException, IOException; + + /** + * @see #getSalesHistoryFilePath() + */ + Optional readSalesHistory(Path filePath) throws DataConversionException, IOException; + + /** + * Saves the given {@link ReadOnlySalesHistory} to the storage. + * @param salesHistory cannot be null. + * @throws IOException if there was any problem writing to the file. + */ + void saveSalesHistory(ReadOnlySalesHistory salesHistory) throws IOException; + + /** + * @see #saveSalesHistory(ReadOnlySalesHistory) + */ + void saveSalesHistory(ReadOnlySalesHistory salesHistory, Path filePath) throws IOException; + + void deleteSalesHistory() throws IOException; } diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java index 38f97e554124..115949455df8 100644 --- a/src/main/java/seedu/address/storage/Storage.java +++ b/src/main/java/seedu/address/storage/Storage.java @@ -5,6 +5,7 @@ import java.util.Optional; import seedu.address.commons.events.model.AddressBookChangedEvent; +import seedu.address.commons.events.model.SalesHistoryChangedEvent; import seedu.address.commons.events.model.UserDatabaseChangedEvent; import seedu.address.commons.events.model.UserDeletedEvent; import seedu.address.commons.events.storage.DataSavingExceptionEvent; @@ -13,11 +14,12 @@ import seedu.address.model.ReadOnlyUserDatabase; import seedu.address.model.UserPrefs; import seedu.address.model.login.User; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; /** * API of the Storage component */ -public interface Storage extends ProductDatabaseStorage, UserPrefsStorage, UserDatabaseStorage { +public interface Storage extends ProductDatabaseStorage, UserPrefsStorage, UserDatabaseStorage, SalesHistoryStorage { @Override Optional readUserPrefs() throws DataConversionException, IOException; @@ -55,6 +57,13 @@ public interface Storage extends ProductDatabaseStorage, UserPrefsStorage, UserD */ void handleUserDeletedEvent(UserDeletedEvent event) throws IOException; + /** + * Saves the current version of the Sales History to the hard disk. + * Creates the data file if missing. + * Raises {@link DataSavingExceptionEvent} if there was an error during saving. + */ + void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) throws IOException; + @Override Path getUserDatabaseFilePath(); @@ -67,5 +76,17 @@ public interface Storage extends ProductDatabaseStorage, UserPrefsStorage, UserD @Override void deleteAddressBook(User user) throws IOException; + @Override + Path getSalesHistoryFilePath(); + + @Override + Optional readSalesHistory() throws DataConversionException, IOException; + + @Override + void saveSalesHistory(ReadOnlySalesHistory salesHistory) throws IOException; + + @Override + void deleteSalesHistory() throws IOException; + void update(User user); } diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index e5d5c84fc7d1..3175abf661f0 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -10,6 +10,7 @@ import seedu.address.commons.core.ComponentManager; import seedu.address.commons.core.LogsCenter; import seedu.address.commons.events.model.AddressBookChangedEvent; +import seedu.address.commons.events.model.SalesHistoryChangedEvent; import seedu.address.commons.events.model.UserDatabaseChangedEvent; import seedu.address.commons.events.model.UserDeletedEvent; import seedu.address.commons.events.storage.DataSavingExceptionEvent; @@ -18,6 +19,7 @@ import seedu.address.model.ReadOnlyUserDatabase; import seedu.address.model.UserPrefs; import seedu.address.model.login.User; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; /** * Manages storage of ProductDatabase data in local storage. @@ -28,14 +30,16 @@ public class StorageManager extends ComponentManager implements Storage { private ProductDatabaseStorage productDatabaseStorage; private UserPrefsStorage userPrefsStorage; private UserDatabaseStorage userDatabaseStorage; + private SalesHistoryStorage salesHistoryStorage; public StorageManager(ProductDatabaseStorage productDatabaseStorage, UserPrefsStorage userPrefsStorage, - UserDatabaseStorage userDatabaseStorage) { + UserDatabaseStorage userDatabaseStorage, SalesHistoryStorage salesHistoryStorage) { super(); this.productDatabaseStorage = productDatabaseStorage; this.userPrefsStorage = userPrefsStorage; this.userDatabaseStorage = userDatabaseStorage; + this.salesHistoryStorage = salesHistoryStorage; } // ================ UserPrefs methods ============================== @@ -137,6 +141,39 @@ public void deleteAddressBook(User user) throws IOException { productDatabaseStorage.deleteAddressBook(user); } + //================ Sales History methods ======================= + @Override + public Path getSalesHistoryFilePath() { + return salesHistoryStorage.getSalesHistoryFilePath(); + } + + @Override + public Optional readSalesHistory() throws DataConversionException, IOException { + return salesHistoryStorage.readSalesHistory(); + } + + @Override + public Optional readSalesHistory(Path filePath) throws DataConversionException, IOException { + logger.fine("Attempting to read data from file: " + filePath); + return salesHistoryStorage.readSalesHistory(filePath); + } + + @Override + public void saveSalesHistory(ReadOnlySalesHistory salesHistory) throws IOException { + salesHistoryStorage.saveSalesHistory(salesHistory, salesHistoryStorage.getSalesHistoryFilePath()); + } + + @Override + public void deleteSalesHistory() throws IOException { + + } + + @Override + public void saveSalesHistory(ReadOnlySalesHistory salesHistory, Path filePath) throws IOException { + logger.fine("Attempting to write to data file: " + filePath); + salesHistoryStorage.saveSalesHistory(salesHistory, filePath); + } + @Override @Subscribe public void handleUserDatabaseChangedEvent(UserDatabaseChangedEvent event) { @@ -155,6 +192,11 @@ public void handleUserDeletedEvent(UserDeletedEvent event) throws IOException { deleteAddressBook(event.data); } + @Override + public void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) throws IOException { + logger.info(LogsCenter.getEventHandlingLogMessage(event, "Sales history has been modified")); + } + // ============== Storage updater ===================== public void update(User user) { diff --git a/src/main/java/seedu/address/storage/XmlSalesHistoryStorage.java b/src/main/java/seedu/address/storage/XmlSalesHistoryStorage.java new file mode 100644 index 000000000000..aad6bf438b02 --- /dev/null +++ b/src/main/java/seedu/address/storage/XmlSalesHistoryStorage.java @@ -0,0 +1,73 @@ +package seedu.address.storage; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; +import java.util.logging.Logger; + +import seedu.address.commons.core.LogsCenter; +import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.commons.util.FileUtil; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; + +public class XmlSalesHistoryStorage implements SalesHistoryStorage { + private static Logger logger = LogsCenter.getLogger(XmlSalesHistoryStorage.class); + + private Path filePath; + + public XmlSalesHistoryStorage(Path filePath) { + this.filePath = filePath; + } + + @Override + public Path getSalesHistoryFilePath() { + return filePath; + } + + @Override + public Optional readSalesHistory() throws DataConversionException, IOException { + return readSalesHistory(filePath); + } + + @Override + public Optional readSalesHistory(Path filePath) throws DataConversionException, IOException { + requireNonNull(filePath); + + if (!Files.exists(filePath)) { + logger.info("Saleshistory file " + filePath + " not found"); + return Optional.empty(); + } + + XmlSerializableSalesHistory xmlSalesHistory = XmlFileStorage.loadSalesHistoryFromFile(filePath); + try { + return Optional.of(xmlSalesHistory.toModelType()); + } catch (IllegalValueException e) { + logger.info("Invalid values found in " + filePath + e.getMessage()); + throw new DataConversionException(e); + } + } + + @Override + public void saveSalesHistory(ReadOnlySalesHistory salesHistory) throws IOException { + saveSalesHistory(salesHistory, filePath); + } + + @Override + public void saveSalesHistory(ReadOnlySalesHistory salesHistory, Path filePath) throws IOException { + requireAllNonNull(salesHistory, filePath); + + FileUtil.createIfMissing(filePath); + XmlFileStorage.saveSalesHistoryToFile(filePath, new XmlSerializableSalesHistory(salesHistory)); + } + + @Override + public void deleteSalesHistory() throws IOException { + requireNonNull(filePath); + Files.delete(filePath); + } +} diff --git a/src/main/java/seedu/address/storage/XmlSerializableSalesHistory.java b/src/main/java/seedu/address/storage/XmlSerializableSalesHistory.java index ef4a416c9df5..ff485d6545b3 100644 --- a/src/main/java/seedu/address/storage/XmlSerializableSalesHistory.java +++ b/src/main/java/seedu/address/storage/XmlSerializableSalesHistory.java @@ -10,6 +10,7 @@ import javax.xml.bind.annotation.XmlRootElement; import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; import seedu.address.model.saleshistory.SalesHistory; import seedu.address.model.timeidentifiedclass.Reminder; import seedu.address.model.timeidentifiedclass.Transaction; @@ -49,6 +50,16 @@ public XmlSerializableSalesHistory(List transactionList, } } + public XmlSerializableSalesHistory(ReadOnlySalesHistory src) { + this(); + for (Transaction transaction : src.getTransactionsAsObservableList()) { + transactionList.add(new XmlAdaptedTransaction(transaction)); + } + for (Reminder reminder : src.getRemindersAsObservableList()) { + reminderList.add(new XmlAdaptedReminder(reminder)); + } + } + /** * Converts a given SalesHistory object into this class for JAXB use. * @param salesHistory From 2695957606c0c55b529bf4c29bb08be42f9d12e7 Mon Sep 17 00:00:00 2001 From: ParasK26 Date: Tue, 30 Oct 2018 22:34:20 +0800 Subject: [PATCH 3/6] Updated VersionedSalesHistory, Storage, StorageManager --- .../address/model/VersionedSalesHistory.java | 2 +- .../java/seedu/address/storage/Storage.java | 2 +- .../seedu/address/storage/StorageManager.java | 40 +++++++++++-------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/main/java/seedu/address/model/VersionedSalesHistory.java b/src/main/java/seedu/address/model/VersionedSalesHistory.java index 9924c84e3c5c..fb45940d1e8d 100644 --- a/src/main/java/seedu/address/model/VersionedSalesHistory.java +++ b/src/main/java/seedu/address/model/VersionedSalesHistory.java @@ -22,7 +22,7 @@ public VersionedSalesHistory(ReadOnlySalesHistory initialState) { } /** - * Saves a copy of the current {@code SalesHistory} state at the end of the state list + * Saves a copy of the current {@code giSalesHistory} state at the end of the state list * Undone states are removed from the state list. */ public void commit() { diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java index 115949455df8..3eb3ce6feea7 100644 --- a/src/main/java/seedu/address/storage/Storage.java +++ b/src/main/java/seedu/address/storage/Storage.java @@ -62,7 +62,7 @@ public interface Storage extends ProductDatabaseStorage, UserPrefsStorage, UserD * Creates the data file if missing. * Raises {@link DataSavingExceptionEvent} if there was an error during saving. */ - void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) throws IOException; + void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event); @Override Path getUserDatabaseFilePath(); diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index 3175abf661f0..d0ca989cc8ce 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -141,6 +141,25 @@ public void deleteAddressBook(User user) throws IOException { productDatabaseStorage.deleteAddressBook(user); } + @Override + @Subscribe + public void handleUserDatabaseChangedEvent(UserDatabaseChangedEvent event) { + logger.info(LogsCenter.getEventHandlingLogMessage(event, "Local users data changed, saving to file")); + try { + saveUserDatabase(event.data); + } catch (IOException e) { + raise(new DataSavingExceptionEvent(e)); + } + } + + @Override + @Subscribe + public void handleUserDeletedEvent(UserDeletedEvent event) throws IOException { + logger.info(LogsCenter.getEventHandlingLogMessage(event, "User has been deleted, deleting files")); + deleteAddressBook(event.data); + deleteSalesHistory(); + } + //================ Sales History methods ======================= @Override public Path getSalesHistoryFilePath() { @@ -165,7 +184,7 @@ public void saveSalesHistory(ReadOnlySalesHistory salesHistory) throws IOExcepti @Override public void deleteSalesHistory() throws IOException { - + salesHistoryStorage.deleteSalesHistory(); } @Override @@ -175,28 +194,15 @@ public void saveSalesHistory(ReadOnlySalesHistory salesHistory, Path filePath) t } @Override - @Subscribe - public void handleUserDatabaseChangedEvent(UserDatabaseChangedEvent event) { - logger.info(LogsCenter.getEventHandlingLogMessage(event, "Local users data changed, saving to file")); + public void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) { + logger.info(LogsCenter.getEventHandlingLogMessage(event, "Sales history data changed, saving to file")); try { - saveUserDatabase(event.data); + saveSalesHistory(event.data); } catch (IOException e) { raise(new DataSavingExceptionEvent(e)); } } - @Override - @Subscribe - public void handleUserDeletedEvent(UserDeletedEvent event) throws IOException { - logger.info(LogsCenter.getEventHandlingLogMessage(event, "User has been deleted, deleting files")); - deleteAddressBook(event.data); - } - - @Override - public void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) throws IOException { - logger.info(LogsCenter.getEventHandlingLogMessage(event, "Sales history has been modified")); - } - // ============== Storage updater ===================== public void update(User user) { From b8aaf2b9d676acea8362610e17ccd96bb6c8d304 Mon Sep 17 00:00:00 2001 From: ParasK26 Date: Wed, 31 Oct 2018 01:48:45 +0800 Subject: [PATCH 4/6] Successfully implemented File management for saleshistory --- src/main/java/seedu/address/MainApp.java | 7 +- .../seedu/address/model/ModelManager.java | 100 ++++++++-- .../seedu/address/model/ProductDatabase.java | 157 +--------------- .../java/seedu/address/model/UserPrefs.java | 5 + .../address/model/VersionedSalesHistory.java | 5 +- .../model/saleshistory/SalesHistory.java | 12 +- .../saleshistory/SalesHistoryManager.java | 173 ++++++++++++++++++ .../address/model/util/SampleDataUtil.java | 27 +++ .../seedu/address/storage/StorageManager.java | 4 +- .../storage/XmlAdaptedTransaction.java | 10 +- .../java/seedu/address/model/TestStorage.java | 37 ++++ 11 files changed, 355 insertions(+), 182 deletions(-) create mode 100644 src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index e25506573bc4..cb3f38d46552 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -31,11 +31,13 @@ import seedu.address.model.util.SampleUsersUtil; import seedu.address.storage.JsonUserPrefsStorage; import seedu.address.storage.ProductDatabaseStorage; +import seedu.address.storage.SalesHistoryStorage; import seedu.address.storage.Storage; import seedu.address.storage.StorageManager; import seedu.address.storage.UserDatabaseStorage; import seedu.address.storage.UserPrefsStorage; import seedu.address.storage.XmlProductDatabaseStorage; +import seedu.address.storage.XmlSalesHistoryStorage; import seedu.address.storage.XmlUserDatabaseStorage; import seedu.address.ui.Ui; import seedu.address.ui.UiManager; @@ -59,7 +61,7 @@ public class MainApp extends Application { @Override public void init() throws Exception { - logger.info("=============================[ Initializing Inventori PRO ]==========================="); + logger.info("=============================[ Initializing Inventarie PRO ]==========================="); super.init(); AppParameters appParameters = AppParameters.parse(getParameters()); @@ -70,7 +72,8 @@ public void init() throws Exception { UserDatabaseStorage usersStorage = new XmlUserDatabaseStorage(userPrefs.getUsersFilePath()); ProductDatabaseStorage productDatabaseStorage = new XmlProductDatabaseStorage(userPrefs.getAddressBookFilePath()); - storage = new StorageManager(productDatabaseStorage, userPrefsStorage, usersStorage); + SalesHistoryStorage salesHistoryStorage = new XmlSalesHistoryStorage(userPrefs.getSalesHistoryFilePath()); + storage = new StorageManager(productDatabaseStorage, userPrefsStorage, usersStorage, salesHistoryStorage); initLogging(config); diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index dcc719c8cf17..654655298c4b 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -16,6 +16,7 @@ import seedu.address.commons.core.ComponentManager; import seedu.address.commons.core.LogsCenter; import seedu.address.commons.events.model.AddressBookChangedEvent; +import seedu.address.commons.events.model.SalesHistoryChangedEvent; import seedu.address.commons.events.model.UserDatabaseChangedEvent; import seedu.address.commons.events.model.UserDeletedEvent; import seedu.address.commons.exceptions.DataConversionException; @@ -28,6 +29,8 @@ import seedu.address.model.login.exceptions.DuplicateUserException; import seedu.address.model.login.exceptions.UserNotFoundException; import seedu.address.model.product.Product; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; +import seedu.address.model.saleshistory.SalesHistory; import seedu.address.model.timeidentifiedclass.Reminder; import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; import seedu.address.model.timeidentifiedclass.Transaction; @@ -46,6 +49,7 @@ public class ModelManager extends ComponentManager implements Model { private final Storage storage; private final VersionedProductDatabase versionedAddressBook; private final VersionedUserDatabase versionedUserDatabase; + private final VersionedSalesHistory versionedSalesHistory; private final FilteredList filteredDistributors; private final FilteredList filteredProducts; @@ -55,21 +59,39 @@ public class ModelManager extends ComponentManager implements Model { * Initializes a ModelManager with the given addressBook and userPrefs. */ public ModelManager(ReadOnlyAddressBook addressBook, UserPrefs userPrefs, - ReadOnlyUserDatabase userDatabase, Storage storage) { + ReadOnlyUserDatabase userDatabase, ReadOnlySalesHistory salesHistory, Storage storage) { super(); requireAllNonNull(addressBook, userPrefs, userDatabase); - logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs - + " and user database " + userDatabase); + logger.fine("Initializing with address book: " + addressBook + ", user prefs " + userPrefs + + ", user database " + userDatabase + ", and sales history " + salesHistory); this.storage = storage; versionedUserDatabase = new VersionedUserDatabase(userDatabase); versionedAddressBook = new VersionedProductDatabase(addressBook); + versionedSalesHistory = new VersionedSalesHistory(salesHistory); filteredDistributors = new FilteredList<>(versionedAddressBook.getDistributorList()); filteredProducts = new FilteredList<>(versionedAddressBook.getPersonList()); } + /** + * Initializes a ModelManager without sales history. + */ + public ModelManager(ReadOnlyAddressBook addressBook, UserPrefs userPrefs, + ReadOnlyUserDatabase userDatabase, Storage storage) { + this(addressBook, userPrefs, userDatabase, new SalesHistory(), storage); + } + public ModelManager(Storage storage) { - this(new ProductDatabase(), new UserPrefs(), new UserDatabase(), storage); + this(new ProductDatabase(), new UserPrefs(), + new UserDatabase(), new SalesHistory(), + storage); + } + + /** + * Allows us to set sales history to what is required. + */ + public void setSalesHistory(ReadOnlySalesHistory salesHistory) { + versionedSalesHistory.resetData(salesHistory); } // ============== ProductDatabase Modifiers ============================================================= @@ -125,23 +147,53 @@ public void deletePerson(Product target) { */ private void reloadAddressBook(Username username) { Optional addressBookOptional; - ReadOnlyAddressBook newData; + ReadOnlyAddressBook newAddressBook; - storage.update(versionedUserDatabase.getUser(username)); try { addressBookOptional = storage.readAddressBook(); if (!addressBookOptional.isPresent()) { logger.info("Data file not found. Will be starting with a sample ProductDatabase"); } - newData = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook); + newAddressBook = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook); } catch (DataConversionException e) { - newData = new ProductDatabase(); + newAddressBook = new ProductDatabase(); logger.warning("Data file not in the correct format. Will be starting with an empty ProductDatabase"); } catch (IOException e) { - newData = new ProductDatabase(); + newAddressBook = new ProductDatabase(); logger.warning("Problem while reading from the file. Will be starting with an empty ProductDatabase"); } - versionedAddressBook.resetData(newData); + versionedAddressBook.resetData(newAddressBook); + } + + /** + * Updates the sales history and its storage path using the {@code username} provided. + * @param username + */ + private void reloadSalesHistory(Username username) { + Optional salesHistoryOptional; + ReadOnlySalesHistory newSalesHistory; + + try { + salesHistoryOptional = storage.readSalesHistory(); + if(!salesHistoryOptional.isPresent()) { + logger.info("Data file not found. Will be starting with a sample SalesHistory"); + } + newSalesHistory = salesHistoryOptional.orElseGet(SampleDataUtil::getSampleSalesHistory); + } catch (DataConversionException e) { + newSalesHistory = new SalesHistory(); + logger.warning("Data file not in the correct format. Will be starting with an empty SalesHistory"); + } catch (IOException e) { + newSalesHistory = new SalesHistory(); + logger.warning("Problem while reading from the file. Will be starting with an empty SalesHistory"); + } + + versionedSalesHistory.resetData(newSalesHistory); + } + + private void reloadAddressBookAndSalesHistory(Username username) { + storage.update(versionedUserDatabase.getUser(username)); + reloadAddressBook(username); + reloadSalesHistory(username); } //============== UserDatabase Modifiers ============================================================= @@ -179,7 +231,7 @@ public synchronized void addUser(User person) throws DuplicateUserException { public boolean checkAuthentication(Username username, Password password) throws AuthenticatedException { boolean result = versionedUserDatabase.checkAuthentication(username, password); if (hasLoggedIn() && result) { - reloadAddressBook(username); + reloadAddressBookAndSalesHistory(username); } return result; } @@ -333,10 +385,18 @@ public boolean equals(Object obj) { //=========================== SalesHistory accessories =================================== + private void indicateSalesHistoryChanged() { + raise(new SalesHistoryChangedEvent(versionedSalesHistory)); + } + + public SalesHistory getSalesHistory() { + return versionedSalesHistory; + } + @Override public String getDaysTransactions(String day) throws InvalidTimeFormatException { try { - return versionedAddressBook.getDaysTransactions(day); + return versionedSalesHistory.getDaysTransactionsAsString(day); } catch (InvalidTimeFormatException e) { throw e; } @@ -346,12 +406,13 @@ public String getDaysTransactions(String day) throws InvalidTimeFormatException public void addTransaction(Transaction transaction) throws InvalidTimeFormatException, DuplicateTransactionException { try { - versionedAddressBook.addTransaction(transaction); + versionedSalesHistory.addTransaction(transaction); } catch (DuplicateTransactionException e) { throw e; } catch (InvalidTimeFormatException e) { throw e; } + indicateSalesHistoryChanged(); } @Override @@ -360,36 +421,39 @@ public void addReminder(Reminder reminder) throws InvalidTimeFormatException, Du throw new InvalidTimeFormatException(); } try { - versionedAddressBook.addReminder(reminder); + versionedSalesHistory.addReminder(reminder); } catch (InvalidTimeFormatException e) { throw e; } catch (DuplicateReminderException e) { throw e; } + indicateSalesHistoryChanged(); } @Override public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException { try { - versionedAddressBook.removeReminder(reminderTime); + versionedSalesHistory.removeReminder(reminderTime); } catch (InvalidTimeFormatException e) { throw e; } catch (NoSuchElementException e) { throw e; } + indicateSalesHistoryChanged(); } @Override public ArrayList getOverdueReminders() { - return versionedAddressBook.getOverdueReminders(); + return versionedSalesHistory.getOverdueReminders(); } + @Override public ArrayList getOverdueRemindersForThread() { - return versionedAddressBook.getOverDueRemindersForThread(); + return versionedSalesHistory.getOverDueRemindersForThread(); } @Override public Transaction getLastTransaction() { - return versionedAddressBook.getLastTransaction(); + return versionedSalesHistory.getLastTransaction(); } } diff --git a/src/main/java/seedu/address/model/ProductDatabase.java b/src/main/java/seedu/address/model/ProductDatabase.java index e96dcd7bfe6d..210222fcadbf 100644 --- a/src/main/java/seedu/address/model/ProductDatabase.java +++ b/src/main/java/seedu/address/model/ProductDatabase.java @@ -5,22 +5,12 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; import javafx.collections.ObservableList; import seedu.address.model.distributor.Distributor; import seedu.address.model.distributor.UniqueDistributorList; import seedu.address.model.product.Product; import seedu.address.model.product.UniquePersonList; -import seedu.address.model.saleshistory.SalesHistory; -import seedu.address.model.timeidentifiedclass.Reminder; -import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; -import seedu.address.model.timeidentifiedclass.Transaction; -import seedu.address.model.timeidentifiedclass.exceptions.DuplicateReminderException; -import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; -import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; /** * Wraps all data at the address-book level @@ -29,8 +19,7 @@ public class ProductDatabase implements ReadOnlyAddressBook { private final UniquePersonList persons; - private final SalesHistory salesHistory; - private Transaction lastTransaction; + /* * The 'unusual' code block below is an non-static initialization block, sometimes used to avoid duplication * between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html @@ -41,8 +30,6 @@ public class ProductDatabase implements ReadOnlyAddressBook { { persons = new UniquePersonList(); - salesHistory = new SalesHistory(); - lastTransaction = null; } private final UniqueDistributorList distributors; @@ -162,148 +149,6 @@ public void updateDistributor(Distributor target, Distributor editedDistributor) distributors.setDistributor(target, editedDistributor); } - /** - * Getter for {@code salesHistory} - */ - public SalesHistory getSalesHistory() { - return salesHistory; - } - - /** - * Adds a transaction to the active {@code salesHistory}. - * @param transaction - * @throws InvalidTimeFormatException - * @throws DuplicateTransactionException - */ - public void addTransaction(Transaction transaction) throws InvalidTimeFormatException, - DuplicateTransactionException { - try { - salesHistory.addTransaction(transaction); - } catch (InvalidTimeFormatException e) { - throw e; - } catch (DuplicateTransactionException e) { - throw e; - } - lastTransaction = transaction; - } - - public String getDaysTransactions(String day) throws InvalidTimeFormatException { - ArrayList daysTransactions; - try { - daysTransactions = salesHistory.getDaysTransactions(day); - } catch (InvalidTimeFormatException e) { - throw e; - } - if (daysTransactions == null || daysTransactions.isEmpty()) { - return "No transactions found on the specified date!"; - } - - StringBuilder ret = new StringBuilder(); - ret.append("TIMINGS FOR TRANSACTIONS ON " + day + "\n"); - for (Transaction transaction : daysTransactions) { - ret.append(transaction.getTransactionTime() + "\n"); - } - - return ret.toString(); - } - - public Transaction getLastTransaction() { - return lastTransaction; - } - - /** - * This method adds a reminder to the {@code salesHistory}. - * @param reminder - * @throws InvalidTimeFormatException - * @throws DuplicateReminderException - */ - public void addReminder(Reminder reminder) throws InvalidTimeFormatException, DuplicateReminderException { - try { - salesHistory.addReminder(reminder); - } catch (InvalidTimeFormatException e) { - throw e; - } catch (DuplicateReminderException e) { - throw e; - } - } - - /** - * Removes a reminder from the {@code salesHistory}. - * @param reminderTime - * @throws InvalidTimeFormatException - * @throws NoSuchElementException - */ - public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException { - try { - salesHistory.removeReminder(reminderTime); - } catch (InvalidTimeFormatException e) { - throw e; - } catch (NoSuchElementException e) { - throw e; - } - } - - /** - * Returns the reminders which are due in the active day. - * @return reminder list. - */ - public ArrayList getOverdueReminders() { - final String currentTime = TimeIdentifiedClass.getCurrentDateAndTime(); - - Set reminderSet = salesHistory.getReminderRecord().entrySet(); - Iterator it = reminderSet.iterator(); - - ArrayList remindersToReturn = new ArrayList<>(); - - // set to true in order to enter subsequent while-loop - boolean isLesserTime = true; - - while (it.hasNext() && isLesserTime) { - Map.Entry reminderEntry = (Map.Entry) it.next(); - String reminderTime = (String) reminderEntry.getKey(); - Reminder reminderToAdd = (Reminder) reminderEntry.getValue(); - - // checking if reminder time is lesser than current time - isLesserTime = (reminderTime.compareTo(currentTime) <= 0); - if (isLesserTime) { - remindersToReturn.add(reminderToAdd); - } - } - return remindersToReturn; - } - - /** - * Returns the reminders which are due and have not been shown by the thread, and declares them as shown by the - * thread. - * @return reminder list. - */ - public ArrayList getOverDueRemindersForThread() { - final String currentTime = TimeIdentifiedClass.getCurrentDateAndTime(); - - Set reminderSet = salesHistory.getReminderRecord().entrySet(); - Iterator it = reminderSet.iterator(); - - ArrayList remindersToReturn = new ArrayList<>(); - - // set to true to enter the following while block - boolean isLesserTime = true; - - while (it.hasNext() && isLesserTime) { - Map.Entry entry = (Map.Entry) it.next(); - String reminderTime = (String) entry.getKey(); - Reminder reminderToAdd = (Reminder) entry.getValue(); - - // true if reminder time is lesser than or equal to the current time. - isLesserTime = (reminderTime.compareTo(currentTime) <= 0); - - if (isLesserTime && !reminderToAdd.hasBeenShownByThread()) { - remindersToReturn.add(reminderToAdd); - reminderToAdd.declareAsShownByThread(); - } - } - return remindersToReturn; - } - /** * Removes {@code key} from this {@code ProductDatabase}. * {@code key} must exist in the address book. diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/seedu/address/model/UserPrefs.java index e618ca785d6b..29bb5c9f57a0 100644 --- a/src/main/java/seedu/address/model/UserPrefs.java +++ b/src/main/java/seedu/address/model/UserPrefs.java @@ -14,6 +14,7 @@ public class UserPrefs { private GuiSettings guiSettings; private Path addressBookFilePath = Paths.get("data" , "addressbook.xml"); private Path usersFilePath = Paths.get("data", "users.xml"); + private Path salesHistoryFilePath = Paths.get("data","saleshistory.xml"); public UserPrefs() { setGuiSettings(500, 500, 0, 0); @@ -35,6 +36,10 @@ public Path getAddressBookFilePath() { return addressBookFilePath; } + public Path getSalesHistoryFilePath() { + return salesHistoryFilePath; + } + public void setAddressBookFilePath(Path addressBookFilePath) { this.addressBookFilePath = addressBookFilePath; } diff --git a/src/main/java/seedu/address/model/VersionedSalesHistory.java b/src/main/java/seedu/address/model/VersionedSalesHistory.java index fb45940d1e8d..f119dcfcae85 100644 --- a/src/main/java/seedu/address/model/VersionedSalesHistory.java +++ b/src/main/java/seedu/address/model/VersionedSalesHistory.java @@ -5,11 +5,12 @@ import seedu.address.model.saleshistory.ReadOnlySalesHistory; import seedu.address.model.saleshistory.SalesHistory; +import seedu.address.model.saleshistory.SalesHistoryManager; /** - * {@link SalesHistory} that keeps track fo its own history. + * {@link SalesHistoryManager} that keeps track fo its own history. */ -public class VersionedSalesHistory extends SalesHistory { +public class VersionedSalesHistory extends SalesHistoryManager { private final List salesHistoriesStateList; private int currentStatePointer; diff --git a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java index 424c81c40341..f91a8f598d57 100644 --- a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java +++ b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java @@ -28,6 +28,7 @@ public class SalesHistory implements ReadOnlySalesHistory { private TreeMap reminderRecord; private ObservableList transactionObservableList; private ObservableList reminderObservableList; + /** * The following constructor creates a blank sales history. */ @@ -68,7 +69,11 @@ public SalesHistory(TreeMap transactionRecord, TreeMap getTransactionsAsObservableList() { return FXCollections.unmodifiableObservableList(transactionObservableList); diff --git a/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java b/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java new file mode 100644 index 000000000000..511d0cd10917 --- /dev/null +++ b/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java @@ -0,0 +1,173 @@ +package seedu.address.model.saleshistory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +import seedu.address.model.timeidentifiedclass.Reminder; +import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateReminderException; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; +import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; + +/** + * This class handles the SalesHistory + */ +public class SalesHistoryManager extends SalesHistory { + + private Transaction lastTransaction; + + /** + * Constructs this class given a {@link ReadOnlySalesHistory} object. + * @param initialState + */ + public SalesHistoryManager(ReadOnlySalesHistory initialState) { + super(initialState); + } + + /** + * Adds a transaction to the SalesHistory. + * @param transaction + * @throws InvalidTimeFormatException + * @throws DuplicateTransactionException + */ + @Override + public void addTransaction(Transaction transaction) throws InvalidTimeFormatException, + DuplicateTransactionException { + try { + super.addTransaction(transaction); + } catch (InvalidTimeFormatException e) { + throw e; + } catch (DuplicateTransactionException e) { + throw e; + } + lastTransaction = transaction; + } + + /** + * Gets the transactions for a given day as a String. + * @param day + * @return + * @throws InvalidTimeFormatException + */ + public String getDaysTransactionsAsString(String day) throws InvalidTimeFormatException { + ArrayList daysTransactions; + try { + daysTransactions = super.getDaysTransactions(day); + } catch (InvalidTimeFormatException e) { + throw e; + } + if (daysTransactions == null || daysTransactions.isEmpty()) { + return "No transactions found on the specified date!"; + } + + StringBuilder ret = new StringBuilder(); + ret.append("TIMINGS FOR TRANSACTIONS ON " + day + "\n"); + for (Transaction transaction : daysTransactions) { + ret.append(transaction.getTransactionTime() + "\n"); + } + + return ret.toString(); + } + + public Transaction getLastTransaction() { + return lastTransaction; + } + + /** + * This method adds a reminder to the {@code SalesHistory}. + * @param reminder + * @throws InvalidTimeFormatException + * @throws DuplicateReminderException + */ + @Override + public void addReminder(Reminder reminder) throws InvalidTimeFormatException, DuplicateReminderException { + try { + super.addReminder(reminder); + } catch (InvalidTimeFormatException e) { + throw e; + } catch (DuplicateReminderException e) { + throw e; + } + } + + /** + * Removes a reminder from the {@code salesHistory}. + * @param reminderTime + * @throws InvalidTimeFormatException + * @throws NoSuchElementException + */ + public void removeReminder(String reminderTime) throws InvalidTimeFormatException, NoSuchElementException { + try { + super.removeReminder(reminderTime); + } catch (InvalidTimeFormatException e) { + throw e; + } catch (NoSuchElementException e) { + throw e; + } + } + + /** + * Returns the reminders which are due in the active day. + * @return reminder list. + */ + public ArrayList getOverdueReminders() { + final String currentTime = TimeIdentifiedClass.getCurrentDateAndTime(); + + Set reminderSet = getReminderRecord().entrySet(); + Iterator it = reminderSet.iterator(); + + ArrayList remindersToReturn = new ArrayList<>(); + + // set to true in order to enter subsequent while-loop + boolean isLesserTime = true; + + while (it.hasNext() && isLesserTime) { + Map.Entry reminderEntry = (Map.Entry) it.next(); + String reminderTime = (String) reminderEntry.getKey(); + Reminder reminderToAdd = (Reminder) reminderEntry.getValue(); + + // checking if reminder time is lesser than current time + isLesserTime = (reminderTime.compareTo(currentTime) <= 0); + if (isLesserTime) { + remindersToReturn.add(reminderToAdd); + } + } + return remindersToReturn; + } + + /** + * Returns the reminders which are due and have not been shown by the thread, and declares them as shown by the + * thread. + * @return reminder list. + */ + public ArrayList getOverDueRemindersForThread() { + final String currentTime = TimeIdentifiedClass.getCurrentDateAndTime(); + + Set reminderSet = getReminderRecord().entrySet(); + Iterator it = reminderSet.iterator(); + + ArrayList remindersToReturn = new ArrayList<>(); + + // set to true to enter the following while block + boolean isLesserTime = true; + + while (it.hasNext() && isLesserTime) { + Map.Entry entry = (Map.Entry) it.next(); + String reminderTime = (String) entry.getKey(); + Reminder reminderToAdd = (Reminder) entry.getValue(); + + // true if reminder time is lesser than or equal to the current time. + isLesserTime = (reminderTime.compareTo(currentTime) <= 0); + + if (isLesserTime && !reminderToAdd.hasBeenShownByThread()) { + remindersToReturn.add(reminderToAdd); + reminderToAdd.declareAsShownByThread(); + } + } + return remindersToReturn; + } +} diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index d1777a522ac5..b0d46366dfe0 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -13,7 +13,13 @@ import seedu.address.model.product.Name; import seedu.address.model.product.Product; import seedu.address.model.product.SerialNumber; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; +import seedu.address.model.saleshistory.SalesHistory; import seedu.address.model.tag.Tag; +import seedu.address.model.timeidentifiedclass.Transaction; +import seedu.address.model.timeidentifiedclass.exceptions.ClosedTransactionException; +import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; +import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; /** * Contains utility methods for populating {@code ProductDatabase} with sample data. @@ -68,6 +74,27 @@ public static ReadOnlyAddressBook getSampleAddressBook() { return sampleAb; } + public static ReadOnlySalesHistory getSampleSalesHistory() { + SalesHistory sampleSh = new SalesHistory(); + Transaction toAdd = new Transaction(); + try { + toAdd.addProduct("Apples"); + } catch (ClosedTransactionException e) { + // should not happen AT ALL. Stack trace will help debug if this occurs. + e.printStackTrace(); + } + try { + sampleSh.addTransaction(toAdd); + } catch (InvalidTimeFormatException e) { + // should not happen AT ALL. Stack trace will help debug if this occurs. + e.printStackTrace(); + } catch (DuplicateTransactionException e) { + // should not happen AT ALL. Stack trace will help debug if this occurs. + e.printStackTrace(); + } + return sampleSh; + } + /** * Returns a tag set containing the list of strings given. */ diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index d0ca989cc8ce..e517bea36bbf 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -32,7 +32,6 @@ public class StorageManager extends ComponentManager implements Storage { private UserDatabaseStorage userDatabaseStorage; private SalesHistoryStorage salesHistoryStorage; - public StorageManager(ProductDatabaseStorage productDatabaseStorage, UserPrefsStorage userPrefsStorage, UserDatabaseStorage userDatabaseStorage, SalesHistoryStorage salesHistoryStorage) { super(); @@ -161,6 +160,7 @@ public void handleUserDeletedEvent(UserDeletedEvent event) throws IOException { } //================ Sales History methods ======================= + @Override public Path getSalesHistoryFilePath() { return salesHistoryStorage.getSalesHistoryFilePath(); @@ -194,6 +194,7 @@ public void saveSalesHistory(ReadOnlySalesHistory salesHistory, Path filePath) t } @Override + @Subscribe public void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) { logger.info(LogsCenter.getEventHandlingLogMessage(event, "Sales history data changed, saving to file")); try { @@ -207,6 +208,7 @@ public void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) { public void update(User user) { this.productDatabaseStorage = new XmlProductDatabaseStorage(user.getAddressBookFilePath()); + this.salesHistoryStorage = new XmlSalesHistoryStorage(user.getSalesHistoryFilePath()); } } diff --git a/src/main/java/seedu/address/storage/XmlAdaptedTransaction.java b/src/main/java/seedu/address/storage/XmlAdaptedTransaction.java index d86867ba7d1b..bf62a33b4e19 100644 --- a/src/main/java/seedu/address/storage/XmlAdaptedTransaction.java +++ b/src/main/java/seedu/address/storage/XmlAdaptedTransaction.java @@ -1,5 +1,6 @@ package seedu.address.storage; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -61,13 +62,18 @@ public XmlAdaptedTransaction(String transactionTime, List productNames, public XmlAdaptedTransaction(Transaction transaction) { transactionTime = transaction.getTransactionTime(); + productNames = new ArrayList<>(); + productQuantities = new ArrayList<>(); Set transactionSet = transaction.getTransactionRecord().entrySet(); Iterator it = transactionSet.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); - productNames.add((String) entry.getKey()); - productQuantities.add(entry.getValue().toString()); + String productName = (String) entry.getKey(); + if (productName != null && !productName.equals("")) { + productNames.add((String) entry.getKey()); + productQuantities.add(entry.getValue().toString()); + } } } diff --git a/src/test/java/seedu/address/model/TestStorage.java b/src/test/java/seedu/address/model/TestStorage.java index 57d1bb25a9f2..0e94b1fac7fe 100644 --- a/src/test/java/seedu/address/model/TestStorage.java +++ b/src/test/java/seedu/address/model/TestStorage.java @@ -7,11 +7,13 @@ import seedu.address.commons.core.ComponentManager; import seedu.address.commons.events.model.AddressBookChangedEvent; +import seedu.address.commons.events.model.SalesHistoryChangedEvent; import seedu.address.commons.events.model.UserDatabaseChangedEvent; import seedu.address.commons.events.model.UserDeletedEvent; import seedu.address.commons.events.storage.DataSavingExceptionEvent; import seedu.address.commons.exceptions.DataConversionException; import seedu.address.model.login.User; +import seedu.address.model.saleshistory.ReadOnlySalesHistory; import seedu.address.storage.Storage; /** @@ -109,9 +111,44 @@ public void update(User user) { public void deleteAddressBook(User user) { } + @Override + public Path getSalesHistoryFilePath() { + return null; + } + + @Override + public Optional readSalesHistory() throws DataConversionException, IOException { + return Optional.empty(); + } + + @Override + public Optional readSalesHistory(Path filePath) throws DataConversionException, IOException { + return Optional.empty(); + } + + @Override + public void saveSalesHistory(ReadOnlySalesHistory salesHistory) throws IOException { + + } + + @Override + public void saveSalesHistory(ReadOnlySalesHistory salesHistory, Path filePath) throws IOException { + + } + + @Override + public void deleteSalesHistory() throws IOException { + + } @Override public void handleUserDeletedEvent(UserDeletedEvent event) { + + } + + @Override + public void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) { + } From d1c567868af971609c2386c218a2e42cff9d5e4a Mon Sep 17 00:00:00 2001 From: ParasK26 Date: Wed, 31 Oct 2018 17:12:18 +0800 Subject: [PATCH 5/6] Preventing display of empty transactions and reminders --- build.gradle | 2 +- .../commands/ViewAllRemindersCommand.java | 10 ++++++++++ .../seedu/address/model/ModelManager.java | 2 +- .../address/model/VersionedSalesHistory.java | 1 - .../model/saleshistory/SalesHistory.java | 3 ++- .../saleshistory/SalesHistoryManager.java | 5 ++++- .../timeidentifiedclass/Transaction.java | 6 ++++-- .../address/model/util/SampleDataUtil.java | 19 +------------------ 8 files changed, 23 insertions(+), 25 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/ViewAllRemindersCommand.java diff --git a/build.gradle b/build.gradle index f8e614f8b49b..a03e3ea577c7 100644 --- a/build.gradle +++ b/build.gradle @@ -51,7 +51,7 @@ jacocoTestReport { } test { - useJUnitPlatform() + //useJUnitPlatform() } dependencies { diff --git a/src/main/java/seedu/address/logic/commands/ViewAllRemindersCommand.java b/src/main/java/seedu/address/logic/commands/ViewAllRemindersCommand.java new file mode 100644 index 000000000000..cf8b0e06cb1e --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/ViewAllRemindersCommand.java @@ -0,0 +1,10 @@ +package seedu.address.logic.commands; + +import seedu.address.model.saleshistory.SalesHistory; + +/** + * This command displays all the reminders in the {@link SalesHistory}. + */ +public class ViewAllRemindersCommand { + +} diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 654655298c4b..c07f2ded6b66 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -176,7 +176,7 @@ private void reloadSalesHistory(Username username) { try { salesHistoryOptional = storage.readSalesHistory(); if(!salesHistoryOptional.isPresent()) { - logger.info("Data file not found. Will be starting with a sample SalesHistory"); + logger.info("Data file not found. Will be starting with an empty SalesHistory"); } newSalesHistory = salesHistoryOptional.orElseGet(SampleDataUtil::getSampleSalesHistory); } catch (DataConversionException e) { diff --git a/src/main/java/seedu/address/model/VersionedSalesHistory.java b/src/main/java/seedu/address/model/VersionedSalesHistory.java index f119dcfcae85..e53f2900bbfe 100644 --- a/src/main/java/seedu/address/model/VersionedSalesHistory.java +++ b/src/main/java/seedu/address/model/VersionedSalesHistory.java @@ -16,7 +16,6 @@ public class VersionedSalesHistory extends SalesHistoryManager { public VersionedSalesHistory(ReadOnlySalesHistory initialState) { super(initialState); - salesHistoriesStateList = new ArrayList<>(); salesHistoriesStateList.add(initialState); currentStatePointer = 0; diff --git a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java index f91a8f598d57..fbcddc3d5f9d 100644 --- a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java +++ b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java @@ -73,8 +73,8 @@ public SalesHistory(ReadOnlySalesHistory toBeCopied) { } private void copyReadOnlySalesHistory(ReadOnlySalesHistory toBeCopied) { - requireNonNull(toBeCopied); for (Transaction transaction : toBeCopied.getTransactionsAsObservableList()) { + // These exceptions should never be raised. Printing the stack trace will help debugging. try { addTransaction(transaction); } catch (InvalidTimeFormatException e) { @@ -84,6 +84,7 @@ private void copyReadOnlySalesHistory(ReadOnlySalesHistory toBeCopied) { } } for (Reminder reminder : toBeCopied.getRemindersAsObservableList()) { + // These exceptions should never be raised. Printing the stack trace will help debugging. try { addReminder(reminder); } catch (InvalidTimeFormatException e) { diff --git a/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java b/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java index 511d0cd10917..bfc49f3d3491 100644 --- a/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java +++ b/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java @@ -26,6 +26,9 @@ public class SalesHistoryManager extends SalesHistory { */ public SalesHistoryManager(ReadOnlySalesHistory initialState) { super(initialState); + if (getTransactionRecord().size() > 0) { + lastTransaction = getTransactionRecord().lastEntry().getValue(); + } } /** @@ -111,7 +114,7 @@ public void removeReminder(String reminderTime) throws InvalidTimeFormatExceptio } /** - * Returns the reminders which are due in the active day. + * Returns the reminders which are due. * @return reminder list. */ public ArrayList getOverdueReminders() { diff --git a/src/main/java/seedu/address/model/timeidentifiedclass/Transaction.java b/src/main/java/seedu/address/model/timeidentifiedclass/Transaction.java index df5d764e9efb..cbbb370d9bf0 100644 --- a/src/main/java/seedu/address/model/timeidentifiedclass/Transaction.java +++ b/src/main/java/seedu/address/model/timeidentifiedclass/Transaction.java @@ -109,10 +109,12 @@ public String getTransactionRecordAsString() { Iterator it = set.iterator(); ret.append("================== Transaction Record " + this.getTransactionTime() + "==================\n"); - ret.append("ITEM\tQTY\n"); + ret.append("PRODUCT NAME: QUANTITY\n"); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); - ret.append(entry.getKey() + "\t\t" + entry.getValue() + "\n"); + if (entry.getKey() != null && !entry.equals("")) { + ret.append(entry.getKey() + ": " + entry.getValue() + "\n"); + } } ret.trimToSize(); return ret.toString(); diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index b0d46366dfe0..94efdb58374c 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -75,24 +75,7 @@ public static ReadOnlyAddressBook getSampleAddressBook() { } public static ReadOnlySalesHistory getSampleSalesHistory() { - SalesHistory sampleSh = new SalesHistory(); - Transaction toAdd = new Transaction(); - try { - toAdd.addProduct("Apples"); - } catch (ClosedTransactionException e) { - // should not happen AT ALL. Stack trace will help debug if this occurs. - e.printStackTrace(); - } - try { - sampleSh.addTransaction(toAdd); - } catch (InvalidTimeFormatException e) { - // should not happen AT ALL. Stack trace will help debug if this occurs. - e.printStackTrace(); - } catch (DuplicateTransactionException e) { - // should not happen AT ALL. Stack trace will help debug if this occurs. - e.printStackTrace(); - } - return sampleSh; + return new SalesHistory(); } /** From bfabdc455941963f939360d9cf5ebb3096594d5e Mon Sep 17 00:00:00 2001 From: ParasK26 Date: Wed, 31 Oct 2018 18:55:35 +0800 Subject: [PATCH 6/6] Style changes for checkstyle. --- .../events/model/SalesHistoryChangedEvent.java | 4 ++++ .../seedu/address/logic/commands/LoginCommand.java | 1 + .../java/seedu/address/model/ModelManager.java | 10 +++++----- .../java/seedu/address/model/ProductDatabase.java | 5 ----- src/main/java/seedu/address/model/UserPrefs.java | 2 +- .../java/seedu/address/model/product/Product.java | 2 +- .../address/model/saleshistory/SalesHistory.java | 14 +++++++++++--- .../model/saleshistory/SalesHistoryManager.java | 5 +---- .../seedu/address/model/util/SampleDataUtil.java | 4 ---- .../java/seedu/address/storage/StorageManager.java | 10 +++++----- .../address/storage/XmlSalesHistoryStorage.java | 4 ++++ 11 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/main/java/seedu/address/commons/events/model/SalesHistoryChangedEvent.java b/src/main/java/seedu/address/commons/events/model/SalesHistoryChangedEvent.java index 6fc025603e4a..58490f088cb2 100644 --- a/src/main/java/seedu/address/commons/events/model/SalesHistoryChangedEvent.java +++ b/src/main/java/seedu/address/commons/events/model/SalesHistoryChangedEvent.java @@ -2,7 +2,11 @@ import seedu.address.commons.events.BaseEvent; import seedu.address.model.saleshistory.ReadOnlySalesHistory; +import seedu.address.model.saleshistory.SalesHistory; +/** + * Indicates a change in the {@link SalesHistory} + */ public class SalesHistoryChangedEvent extends BaseEvent { public final ReadOnlySalesHistory data; diff --git a/src/main/java/seedu/address/logic/commands/LoginCommand.java b/src/main/java/seedu/address/logic/commands/LoginCommand.java index e4403bb0164d..c9c8e9baf373 100644 --- a/src/main/java/seedu/address/logic/commands/LoginCommand.java +++ b/src/main/java/seedu/address/logic/commands/LoginCommand.java @@ -37,6 +37,7 @@ public LoginCommand(Username username, Password password) { this.username = username; this.password = password; } + @Override public CommandResult execute(Model model, CommandHistory history) throws CommandException { requireNonNull(username); diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index b7f63712aeab..0e1ba200ea6b 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -153,16 +153,15 @@ private void reloadAddressBook(Username username) { } /** - * Updates the sales history and its storage path using the {@code username} provided. - * @param username + * Reloads the sales history */ - private void reloadSalesHistory(Username username) { + private void reloadSalesHistory() { Optional salesHistoryOptional; ReadOnlySalesHistory newSalesHistory; try { salesHistoryOptional = storage.readSalesHistory(); - if(!salesHistoryOptional.isPresent()) { + if (!salesHistoryOptional.isPresent()) { logger.info("Data file not found. Will be starting with an empty SalesHistory"); } newSalesHistory = salesHistoryOptional.orElseGet(SampleDataUtil::getSampleSalesHistory); @@ -272,8 +271,9 @@ public synchronized void addUser(User person) throws DuplicateUserException { public boolean checkAuthentication(Username username, Password password) throws AuthenticatedException { boolean result = versionedUserDatabase.checkAuthentication(username, password); if (hasLoggedIn() && result) { + storage.update(versionedUserDatabase.getUser(username)); reloadAddressBook(username); - reloadSalesHistory(username); + reloadSalesHistory(); reloadDistributorBook(username); } return result; diff --git a/src/main/java/seedu/address/model/ProductDatabase.java b/src/main/java/seedu/address/model/ProductDatabase.java index 0fc2c2a673a5..444aa3531db6 100644 --- a/src/main/java/seedu/address/model/ProductDatabase.java +++ b/src/main/java/seedu/address/model/ProductDatabase.java @@ -2,17 +2,12 @@ import static java.util.Objects.requireNonNull; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import javafx.collections.ObservableList; import seedu.address.model.product.Product; import seedu.address.model.product.UniquePersonList; -import seedu.address.model.saleshistory.SalesHistory; -import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; -import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; /** * Wraps all data at the address-book level diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/seedu/address/model/UserPrefs.java index 80fadfb63df2..bd0122df6411 100644 --- a/src/main/java/seedu/address/model/UserPrefs.java +++ b/src/main/java/seedu/address/model/UserPrefs.java @@ -15,7 +15,7 @@ public class UserPrefs { private Path addressBookFilePath = Paths.get("data" , "addressbook.xml"); private Path distributorBookFilePath = Paths.get("data", "distributorbook.xml"); private Path usersFilePath = Paths.get("data", "users.xml"); - private Path salesHistoryFilePath = Paths.get("data","saleshistory.xml"); + private Path salesHistoryFilePath = Paths.get("data", "saleshistory.xml"); public UserPrefs() { setGuiSettings(750, 500, 0, 0); diff --git a/src/main/java/seedu/address/model/product/Product.java b/src/main/java/seedu/address/model/product/Product.java index a9ae95fd143c..8fd25dbdc445 100755 --- a/src/main/java/seedu/address/model/product/Product.java +++ b/src/main/java/seedu/address/model/product/Product.java @@ -66,7 +66,7 @@ public Set getTags() { * This defines a weaker notion of equality between two persons. */ public boolean isSameProduct(Product otherProduct) { - if (otherProduct.getSerialNumber() == this.getSerialNumber() ) { + if (otherProduct.getSerialNumber() == this.getSerialNumber()) { return true; } diff --git a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java index fbcddc3d5f9d..b98e63c4f62c 100644 --- a/src/main/java/seedu/address/model/saleshistory/SalesHistory.java +++ b/src/main/java/seedu/address/model/saleshistory/SalesHistory.java @@ -10,9 +10,9 @@ import java.util.Set; import java.util.TreeMap; - import javafx.collections.FXCollections; import javafx.collections.ObservableList; + import seedu.address.model.timeidentifiedclass.Reminder; import seedu.address.model.timeidentifiedclass.TimeIdentifiedClass; import seedu.address.model.timeidentifiedclass.Transaction; @@ -72,9 +72,13 @@ public SalesHistory(ReadOnlySalesHistory toBeCopied) { copyReadOnlySalesHistory(toBeCopied); } + /** + * Copies the {@code toBeCopied} to the {@code SalesHistory} + * @param toBeCopied + */ private void copyReadOnlySalesHistory(ReadOnlySalesHistory toBeCopied) { for (Transaction transaction : toBeCopied.getTransactionsAsObservableList()) { - // These exceptions should never be raised. Printing the stack trace will help debugging. + // These exceptions should never be thrown. Printing the stack trace will help debugging. try { addTransaction(transaction); } catch (InvalidTimeFormatException e) { @@ -84,7 +88,7 @@ private void copyReadOnlySalesHistory(ReadOnlySalesHistory toBeCopied) { } } for (Reminder reminder : toBeCopied.getRemindersAsObservableList()) { - // These exceptions should never be raised. Printing the stack trace will help debugging. + // These exceptions should never be thrown. Printing the stack trace will help debugging. try { addReminder(reminder); } catch (InvalidTimeFormatException e) { @@ -186,6 +190,10 @@ public void removeReminder(String reminderTime) throws InvalidTimeFormatExceptio reminderObservableList.remove(toRemove); } + /** + * Resets the {@code SalesHistory} according to a {@code ReadOnlySalesHistory} object + * @param src + */ public void resetData(ReadOnlySalesHistory src) { transactionRecord.clear(); reminderRecord.clear(); diff --git a/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java b/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java index bfc49f3d3491..5b5e6eb2a1f7 100644 --- a/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java +++ b/src/main/java/seedu/address/model/saleshistory/SalesHistoryManager.java @@ -26,9 +26,6 @@ public class SalesHistoryManager extends SalesHistory { */ public SalesHistoryManager(ReadOnlySalesHistory initialState) { super(initialState); - if (getTransactionRecord().size() > 0) { - lastTransaction = getTransactionRecord().lastEntry().getValue(); - } } /** @@ -77,7 +74,7 @@ public String getDaysTransactionsAsString(String day) throws InvalidTimeFormatEx } public Transaction getLastTransaction() { - return lastTransaction; + return getTransactionRecord().lastEntry().getValue(); } /** diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index a02bd3819cde..270d2ef052e6 100755 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -14,10 +14,6 @@ import seedu.address.model.saleshistory.ReadOnlySalesHistory; import seedu.address.model.saleshistory.SalesHistory; import seedu.address.model.tag.Tag; -import seedu.address.model.timeidentifiedclass.Transaction; -import seedu.address.model.timeidentifiedclass.exceptions.ClosedTransactionException; -import seedu.address.model.timeidentifiedclass.exceptions.DuplicateTransactionException; -import seedu.address.model.timeidentifiedclass.exceptions.InvalidTimeFormatException; /** * Contains utility methods for populating {@code ProductDatabase} with sample data. diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index 1597ccee03aa..24f10a139107 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -230,17 +230,17 @@ public void saveSalesHistory(ReadOnlySalesHistory salesHistory) throws IOExcepti salesHistoryStorage.saveSalesHistory(salesHistory, salesHistoryStorage.getSalesHistoryFilePath()); } - @Override - public void deleteSalesHistory() throws IOException { - salesHistoryStorage.deleteSalesHistory(); - } - @Override public void saveSalesHistory(ReadOnlySalesHistory salesHistory, Path filePath) throws IOException { logger.fine("Attempting to write to data file: " + filePath); salesHistoryStorage.saveSalesHistory(salesHistory, filePath); } + @Override + public void deleteSalesHistory() throws IOException { + salesHistoryStorage.deleteSalesHistory(); + } + @Override @Subscribe public void handleSalesHistoryChangedEvent(SalesHistoryChangedEvent event) { diff --git a/src/main/java/seedu/address/storage/XmlSalesHistoryStorage.java b/src/main/java/seedu/address/storage/XmlSalesHistoryStorage.java index aad6bf438b02..b7944c9c2f9a 100644 --- a/src/main/java/seedu/address/storage/XmlSalesHistoryStorage.java +++ b/src/main/java/seedu/address/storage/XmlSalesHistoryStorage.java @@ -14,7 +14,11 @@ import seedu.address.commons.exceptions.IllegalValueException; import seedu.address.commons.util.FileUtil; import seedu.address.model.saleshistory.ReadOnlySalesHistory; +import seedu.address.model.saleshistory.SalesHistory; +/** + * A class to access and modify {@link SalesHistory} stored on the hard disk in xml form. + */ public class XmlSalesHistoryStorage implements SalesHistoryStorage { private static Logger logger = LogsCenter.getLogger(XmlSalesHistoryStorage.class);