diff --git a/SplitWiseImpl/.gitignore b/SplitWiseImpl/.gitignore new file mode 100644 index 00000000..ae3c1726 --- /dev/null +++ b/SplitWiseImpl/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/SplitWiseImpl/Jar_File/SplitWise.jar b/SplitWiseImpl/Jar_File/SplitWise.jar new file mode 100644 index 00000000..187008ea Binary files /dev/null and b/SplitWiseImpl/Jar_File/SplitWise.jar differ diff --git a/SplitWiseImpl/Jar_File/Splitwise.sh b/SplitWiseImpl/Jar_File/Splitwise.sh new file mode 100644 index 00000000..c6ff1acc --- /dev/null +++ b/SplitWiseImpl/Jar_File/Splitwise.sh @@ -0,0 +1 @@ +java -cp Splitwise.jar com.main.CommandLineMain diff --git a/SplitWiseImpl/src/com/application/Application.java b/SplitWiseImpl/src/com/application/Application.java new file mode 100644 index 00000000..30ab147a --- /dev/null +++ b/SplitWiseImpl/src/com/application/Application.java @@ -0,0 +1,101 @@ +package com.application; + +import java.util.ArrayList; +import java.util.List; + +import com.dataStore.interfaces.IUserPairOwedAmountDataStore; +import com.enums.SplitStrategyType; +import com.factory.interfaces.IDataStoreFactory; +import com.factory.interfaces.IStrategyListFactory; +import com.interfaces.IApplication; +import com.interfaces.IStrategyList; +import com.strategies.interfaces.ISplitInput; +import com.strategies.splitObjects.SplitResult; + +/** + * The Class Application. + */ +public class Application implements IApplication { + + /** The user pair owed amount data store. */ + private IUserPairOwedAmountDataStore userPairOwedAmountDataStore; + + /** The strategy list. */ + private IStrategyList strategyList; + + + + + /** + * Instantiates a new application. + * + * @param dataStoreFactory the data store factory + * @param strategyListFactory the strategy list factory + * @param strategiesPresnt the strategies presnt + * @param inputReader the input reader + */ + Application(IDataStoreFactory dataStoreFactory, IStrategyListFactory strategyListFactory, List strategiesPresnt) { + + this.userPairOwedAmountDataStore = dataStoreFactory.getUserPairOwedAmountDataStore(); + + this.strategyList = strategyListFactory.getStrategyList(strategiesPresnt); + } + + /** + * Adds the expense. + * + * @param expenseInput the expense input + * @return true, if successful + */ + @Override + /** + * + */ + public boolean addExpense(ISplitInput splitInput) { + + if (splitInput == null) { + return false; + } + + SplitResult splitResult = this.strategyList.getSplitStrategies().get(splitInput.getSplitInputType()).getFinalSplit(splitInput); + + // System.out.println("result " + splitResult.getOwedBy() + " " + splitResult.getOwedTo()); + + return this.userPairOwedAmountDataStore.updateAmountForEntries(splitResult); + } + + + /** + * Gets the balance for user. + * + * @param userId the user id + * @return the balance for user + */ + @Override + public SplitResult getBalanceForUser(String userId) { + + return this.userPairOwedAmountDataStore.getBalancesForUser(userId); + } + + /** + * Gets the all balances. + * + * @return the all balances + */ + @Override + public SplitResult getAllBalances() { + // TODO Auto-generated method stub + return this.userPairOwedAmountDataStore.getBalancesForAllUsers(); + } + + /** + * Gets the strategies name. + * + * @return the strategies name + */ + @Override + public List getStrategiesName() { + return new ArrayList(this.strategyList.getSplitStrategies().keySet()); + } + +} diff --git a/SplitWiseImpl/src/com/application/ApplicationInterface.java b/SplitWiseImpl/src/com/application/ApplicationInterface.java new file mode 100644 index 00000000..f47cc30a --- /dev/null +++ b/SplitWiseImpl/src/com/application/ApplicationInterface.java @@ -0,0 +1,124 @@ +package com.application; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.enums.InputCommand; +import com.enums.SplitStrategyType; +import com.factory.interfaces.IDataStoreFactory; +import com.factory.interfaces.IStrategyListFactory; +import com.interfaces.IApplication; +import com.interfaces.IApplicationInterface; +import com.ioParser.interfaces.IInputReader; +import com.ioParser.interfaces.IResultFormatter; +import com.strategies.splitObjects.SplitResult; +import com.user.UserDetails; + +// TODO: Auto-generated Javadoc +/** + * The Class ApplicationInterface. + */ +public class ApplicationInterface implements IApplicationInterface { + + /** The application. */ + private IApplication application; + + + /** The data store factory. */ + private IDataStoreFactory dataStoreFactory; + + /** The strategy list factory. */ + private IStrategyListFactory strategyListFactory; + + /** The result formatter. */ + private IResultFormatter resultFormatter; + + /** The input reader. */ + private IInputReader inputReader; + + + /** + * Instantiates a new application interface. + * + * @param dataStoreFactory the data store factory + * @param strategyListFactory the strategy list factory + * @param resultFormatter the result formatter + * @param inputReader the input reader + */ + public ApplicationInterface(IDataStoreFactory dataStoreFactory, IStrategyListFactory strategyListFactory, + IResultFormatter resultFormatter, IInputReader inputReader) { + super(); + this.dataStoreFactory = dataStoreFactory; + this.strategyListFactory = strategyListFactory; + this.resultFormatter = resultFormatter; + this.inputReader = inputReader; + } + + /** + * Instantiate application. + */ + @Override + public void instantiateApplication() { + this.application = new Application(dataStoreFactory, strategyListFactory, Arrays.asList((String) SplitStrategyType.EQUAL.name(),(String) SplitStrategyType.EXACT.name(), (String)SplitStrategyType.PERCENT.name())); + + } + + /** + * Run input string. + * + * @param input the input + * @return the list + */ + @Override + public List runInputString(String input) { + String[] inputArr = input.split(" "); + + List inputList = new ArrayList(); + + int i = 1; + + while (i < inputArr.length) { + inputList.add(inputArr[i]); + + i++; + } + + if (InputCommand.EXPENSE == InputCommand.valueOf(inputArr[0])) { + this.application.addExpense(this.inputReader.parseInput(inputList)); + + return Arrays.asList(); + } + + if (InputCommand.SHOW == InputCommand.valueOf(inputArr[0])) { + SplitResult splitResult; + if (inputList.size() == 0) { + splitResult = this.application.getAllBalances(); + } else { + splitResult = this.application.getBalanceForUser(inputList.get(0)); + } + +// System.out.println("result" + splitResult.getOwedBy() + " " + splitResult.getOwedTo()); + + return this.resultFormatter.getFormattedResult(splitResult, this.dataStoreFactory.getUserDataStore()); + + } + + return new ArrayList(); + + } + + /** + * Adds the new user. + * + * @param userDetails the user details + * @return true, if successful + */ + @Override + public boolean addNewUser(UserDetails userDetails) { + return this.dataStoreFactory.getUserDataStore().addNewUser(userDetails); + } + + + +} diff --git a/SplitWiseImpl/src/com/dataStore/UserDataStore.java b/SplitWiseImpl/src/com/dataStore/UserDataStore.java new file mode 100644 index 00000000..31aa14a6 --- /dev/null +++ b/SplitWiseImpl/src/com/dataStore/UserDataStore.java @@ -0,0 +1,88 @@ +package com.dataStore; + +import java.util.HashMap; + +import com.dataStore.interfaces.IUserDataStore; +import com.user.UserDetails; + +/** + * The Class UserDataStore. + */ +public class UserDataStore implements IUserDataStore { + + /** The user detail map. */ + HashMap userDetailMap = new HashMap(); + + /** + * Gets the user details. + * + * @param userId the user id + * @return the user details + */ + @Override + public UserDetails getUserDetails(String userId) { + // TODO Auto-generated method stub + return this.userDetailMap.get(userId); + } + + /** + * Adds the new user. + * + * @param userDetails the user details + * @return true, if successful + */ + @Override + public boolean addNewUser(UserDetails userDetails) { + if (userDetails != null && userDetails.getUserId() != null && !userDetails.getUserId().equals("")) { + this.userDetailMap.put(userDetails.getUserId(), userDetails); + + return true; + } + + return false; + } + + /** + * Delete user. + * + * @param userId the user id + * @return true, if successful + */ + @Override + public boolean deleteUser(String userId) { + if (userId != null && !userId.equals("")) { + this.userDetailMap.remove(userId); + + return true; + } + return false; + } + + /** + * Update user details. + * + * @param userId the user id + * @param userDetails the user details + * @return true, if successful + */ + @Override + public boolean updateUserDetails(String userId, UserDetails userDetails) { + if (userId != null && !userId.equals("") && userDetails != null) { + if (userDetails.getName() != null) { + this.userDetailMap.get(userId).setName(userDetails.getName()); + } + + if (userDetails.getEmail() != null) { + this.userDetailMap.get(userId).setEmail(userDetails.getEmail()); + } + + if (userDetails.getPhoneNumber() != null) { + this.userDetailMap.get(userId).setPhoneNumber(userDetails.getPhoneNumber()); + } + + return true; + } + return false; + } + +} diff --git a/SplitWiseImpl/src/com/dataStore/UserPairOwedAmountDataStore.java b/SplitWiseImpl/src/com/dataStore/UserPairOwedAmountDataStore.java new file mode 100644 index 00000000..2bf79393 --- /dev/null +++ b/SplitWiseImpl/src/com/dataStore/UserPairOwedAmountDataStore.java @@ -0,0 +1,130 @@ +package com.dataStore; + +import java.util.HashMap; +import java.util.Iterator; + +import com.dataStore.interfaces.IUserPairOwedAmountDataStore; +import com.strategies.splitObjects.SplitResult; + +// TODO: Auto-generated Javadoc +/** + * The Class UserPairOwedAmountDataStore. + */ +public class UserPairOwedAmountDataStore implements IUserPairOwedAmountDataStore { + + /** The owed by map. */ + private HashMap> owedByMap = new HashMap>(); + + /** The owes to map. */ + private HashMap> owesToMap = new HashMap>(); + + + /** + * Update amount. + * + * @param userId1 the user id 1 + * @param userId2 the user id 2 + * @param amount the amount + * @return true, if successful + */ + @Override + public boolean updateAmount(String userId1, String userId2, double amount) { + double amountOwed = amount; + if (this.owedByMap.containsKey(userId2) && this.owedByMap.get(userId2).containsKey(userId1)) { + amountOwed = owedByMap.get(userId2).get(userId1) - amount; + + if (amountOwed > 0) { + this.owedByMap.get(userId2).put(userId1, amountOwed); + + this.owesToMap.get(userId1).put(userId2, amountOwed); + + return true; + } + + this.owedByMap.get(userId2).remove(userId1); + this.owesToMap.get(userId1).remove(userId2); + + amountOwed *= -1.0; + } + + + + if (!this.owedByMap.containsKey(userId1)) { + this.owedByMap.put(userId1, new HashMap()); + } + + if (!this.owedByMap.get(userId1).containsKey(userId2)) { + this.owedByMap.get(userId1).put(userId2, 0.0); + } + + this.owedByMap.get(userId1).put(userId2, this.owedByMap.get(userId1).get(userId2) + amountOwed); + + if (!owesToMap.containsKey(userId2)) { + this.owesToMap.put(userId2, new HashMap()); + } + + if (!this.owesToMap.get(userId2).containsKey(userId1)) { + this.owesToMap.get(userId2).put(userId1, 0.0); + } + + this.owesToMap.get(userId2).put(userId1, this.owesToMap.get(userId2).get(userId1) + amountOwed); + + + + return true; + } + + /** + * Gets the balances for user. + * + * @param userId the user id + * @return the balances for user + */ + @Override + public SplitResult getBalancesForUser(String userId) { + SplitResult result = new SplitResult(); + + result.getOwedBy().put(userId, this.owedByMap.get(userId)); + + result.getOwedTo().put(userId, this.owesToMap.get(userId)); + + return result; + } + + /** + * Gets the balances for all users. + * + * @return the balances for all users + */ + @Override + public SplitResult getBalancesForAllUsers() { + return new SplitResult(owedByMap, null, null, null); + } + + /** + * Update amount for entries. + * + * @param splitResult the split result + * @return true, if successful + */ + @Override + public boolean updateAmountForEntries(SplitResult splitResult) { + Iterator it = splitResult.getOwedBy().keySet().iterator(); + while (it.hasNext()) { + String next = it.next(); + + Iterator it1 = splitResult.getOwedBy().get(next).keySet().iterator(); + + while (it1.hasNext()) { + String next1 = it1.next(); + + this.updateAmount(next, next1, splitResult.getOwedBy().get(next).get(next1)); + } + } + +// System.out.println("DS " + this.owedByMap + " " + this.owesToMap); + + return true; + } + +} diff --git a/SplitWiseImpl/src/com/dataStore/interfaces/IUserDataStore.java b/SplitWiseImpl/src/com/dataStore/interfaces/IUserDataStore.java new file mode 100644 index 00000000..95e135d5 --- /dev/null +++ b/SplitWiseImpl/src/com/dataStore/interfaces/IUserDataStore.java @@ -0,0 +1,42 @@ +package com.dataStore.interfaces; + +import com.user.UserDetails; + +/** + * The Interface IUserDataStore. + */ +public interface IUserDataStore { + + /** + * Gets the user details. + * + * @param userId the user id + * @return the user details + */ + UserDetails getUserDetails(String userId); + + /** + * Adds the new user. + * + * @param userDetails the user details + * @return true, if successful + */ + boolean addNewUser(UserDetails userDetails); + + /** + * Delete user. + * + * @param userId the user id + * @return true, if successful + */ + boolean deleteUser(String userId); + + /** + * Update user details. + * + * @param userId the user id + * @param userDetails the user details + * @return true, if successful + */ + boolean updateUserDetails(String userId, UserDetails userDetails); +} diff --git a/SplitWiseImpl/src/com/dataStore/interfaces/IUserPairOwedAmountDataStore.java b/SplitWiseImpl/src/com/dataStore/interfaces/IUserPairOwedAmountDataStore.java new file mode 100644 index 00000000..cf880e71 --- /dev/null +++ b/SplitWiseImpl/src/com/dataStore/interfaces/IUserPairOwedAmountDataStore.java @@ -0,0 +1,43 @@ +package com.dataStore.interfaces; + +import com.strategies.splitObjects.SplitResult; + +// TODO: Auto-generated Javadoc +/** + * The Interface IUserPairOwedAmountDataStore. + */ +public interface IUserPairOwedAmountDataStore { + + /** + * Update amount. + * + * @param userId1 the user id 1 + * @param userId2 the user id 2 + * @param amount the amount + * @return true, if successful + */ + boolean updateAmount(String userId1, String userId2, double amount); + + /** + * Gets the balances for user. + * + * @param userId the user id + * @return the balances for user + */ + SplitResult getBalancesForUser(String userId); + + /** + * Gets the balances for all users. + * + * @return the balances for all users + */ + SplitResult getBalancesForAllUsers(); + + /** + * Update amount for entries. + * + * @param splitResult the split result + * @return true, if successful + */ + boolean updateAmountForEntries(SplitResult splitResult); +} diff --git a/SplitWiseImpl/src/com/enums/InputCommand.java b/SplitWiseImpl/src/com/enums/InputCommand.java new file mode 100644 index 00000000..d58df98b --- /dev/null +++ b/SplitWiseImpl/src/com/enums/InputCommand.java @@ -0,0 +1,6 @@ +package com.enums; + +public enum InputCommand { + EXPENSE, + SHOW +} diff --git a/SplitWiseImpl/src/com/enums/InputValidationResult.java b/SplitWiseImpl/src/com/enums/InputValidationResult.java new file mode 100644 index 00000000..cb5ba789 --- /dev/null +++ b/SplitWiseImpl/src/com/enums/InputValidationResult.java @@ -0,0 +1,16 @@ +package com.enums; + +/** + * The Enum InputValidationResult. + */ +public enum InputValidationResult { + + /** The valid. */ + VALID, + + /** The wrong input format. */ + WRONG_INPUT_FORMAT, + + /** The sum not equal to total paid. */ + SUM_NOT_EQUAL_TO_TOTAL_PAID +} diff --git a/SplitWiseImpl/src/com/enums/SplitStrategyType.java b/SplitWiseImpl/src/com/enums/SplitStrategyType.java new file mode 100644 index 00000000..167fafc7 --- /dev/null +++ b/SplitWiseImpl/src/com/enums/SplitStrategyType.java @@ -0,0 +1,17 @@ +package com.enums; + +// TODO: Auto-generated Javadoc +/** + * The Enum SplitStrategyType. + */ +public enum SplitStrategyType { + + /** The exact. */ + EXACT, + + /** The equal. */ + EQUAL, + + /** The percent. */ + PERCENT +} diff --git a/SplitWiseImpl/src/com/factory/DataStoreFactory.java b/SplitWiseImpl/src/com/factory/DataStoreFactory.java new file mode 100644 index 00000000..fd4eed93 --- /dev/null +++ b/SplitWiseImpl/src/com/factory/DataStoreFactory.java @@ -0,0 +1,48 @@ +package com.factory; + +import com.dataStore.UserDataStore; +import com.dataStore.UserPairOwedAmountDataStore; +import com.dataStore.interfaces.IUserDataStore; +import com.dataStore.interfaces.IUserPairOwedAmountDataStore; +import com.factory.interfaces.IDataStoreFactory; + +// TODO: Auto-generated Javadoc +/** + * A factory for creating DataStore objects. + */ +public class DataStoreFactory implements IDataStoreFactory { + + /** The user data store. */ + private IUserDataStore userDataStore; + + /** The user pair owed amount data store. */ + private IUserPairOwedAmountDataStore userPairOwedAmountDataStore; + + /** + * Gets the user data store. + * + * @return the user data store + */ + @Override + public IUserDataStore getUserDataStore() { + if (userDataStore == null) { + this.userDataStore = new UserDataStore(); + } + return this.userDataStore; + } + + /** + * Gets the user pair owed amount data store. + * + * @return the user pair owed amount data store + */ + @Override + public IUserPairOwedAmountDataStore getUserPairOwedAmountDataStore() { + if (userPairOwedAmountDataStore == null) { + this.userPairOwedAmountDataStore = new UserPairOwedAmountDataStore(); + } + + return this.userPairOwedAmountDataStore; + } + +} diff --git a/SplitWiseImpl/src/com/factory/StrategyListFactory.java b/SplitWiseImpl/src/com/factory/StrategyListFactory.java new file mode 100644 index 00000000..6d210218 --- /dev/null +++ b/SplitWiseImpl/src/com/factory/StrategyListFactory.java @@ -0,0 +1,70 @@ +package com.factory; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.enums.SplitStrategyType; +import com.factory.interfaces.IStrategyListFactory; +import com.interfaces.IStrategyList; +import com.strategies.equalDivisionStrategy.EqualDivisionSplitStrategy; +import com.strategies.exactDivisionStrategy.ExactDivisionSplitStrategy; +import com.strategies.interfaces.ISplitStrategy; +import com.strategies.percentDivisionStrategy.PercentDivisionSplitStrategy; + +// TODO: Auto-generated Javadoc +/** + * A factory for creating StrategyList objects. + */ +public class StrategyListFactory implements IStrategyListFactory { + + /** + * Instantiates a new strategy list factory. + */ + public StrategyListFactory() { + this.strategyMap.put(SplitStrategyType.EXACT, new ExactDivisionSplitStrategy()); + this.strategyMap.put(SplitStrategyType.EQUAL, new EqualDivisionSplitStrategy()); + this.strategyMap.put(SplitStrategyType.PERCENT, new PercentDivisionSplitStrategy()); + } + + + + /** The strategy map. */ + private HashMap strategyMap = new HashMap(); + + + + /** + * Gets the strategy list. + * + * @param strategiesPresent the strategies present + * @return the strategy list + */ + @Override + + public IStrategyList getStrategyList(List strategiesPresent) { + Map result = new LinkedHashMap(); + + Iterator it = strategiesPresent.listIterator(); + + while (it.hasNext()) { + SplitStrategyType next = SplitStrategyType.valueOf(it.next()); + + if (this.strategyMap.containsKey(next)) { + result.put(next, this.strategyMap.get(next)); + } + } + + return new IStrategyList() { + + @Override + public Map getSplitStrategies() { + // TODO Auto-generated method stub + return result; + } + }; + } + +} diff --git a/SplitWiseImpl/src/com/factory/interfaces/IDataStoreFactory.java b/SplitWiseImpl/src/com/factory/interfaces/IDataStoreFactory.java new file mode 100644 index 00000000..c45880de --- /dev/null +++ b/SplitWiseImpl/src/com/factory/interfaces/IDataStoreFactory.java @@ -0,0 +1,25 @@ +package com.factory.interfaces; + +import com.dataStore.interfaces.IUserDataStore; +import com.dataStore.interfaces.IUserPairOwedAmountDataStore; + +// TODO: Auto-generated Javadoc +/** + * A factory for creating IDataStore objects. + */ +public interface IDataStoreFactory { + + /** + * Gets the user data store. + * + * @return the user data store + */ + IUserDataStore getUserDataStore(); + + /** + * Gets the user pair owed amount data store. + * + * @return the user pair owed amount data store + */ + IUserPairOwedAmountDataStore getUserPairOwedAmountDataStore(); +} diff --git a/SplitWiseImpl/src/com/factory/interfaces/IStrategyListFactory.java b/SplitWiseImpl/src/com/factory/interfaces/IStrategyListFactory.java new file mode 100644 index 00000000..881ab263 --- /dev/null +++ b/SplitWiseImpl/src/com/factory/interfaces/IStrategyListFactory.java @@ -0,0 +1,20 @@ +package com.factory.interfaces; + +import java.util.List; + +import com.interfaces.IStrategyList; + +// TODO: Auto-generated Javadoc +/** + * A factory for creating IStrategyList objects. + */ +public interface IStrategyListFactory { + + /** + * Gets the strategy list. + * + * @param strategiesPresent the strategies present + * @return the strategy list + */ + IStrategyList getStrategyList(List strategiesPresent); +} diff --git a/SplitWiseImpl/src/com/interfaces/IApplication.java b/SplitWiseImpl/src/com/interfaces/IApplication.java new file mode 100644 index 00000000..7b3b084f --- /dev/null +++ b/SplitWiseImpl/src/com/interfaces/IApplication.java @@ -0,0 +1,44 @@ +package com.interfaces; + +import java.util.List; + +import com.enums.SplitStrategyType; +import com.strategies.interfaces.ISplitInput; +import com.strategies.splitObjects.SplitResult; + +// TODO: Auto-generated Javadoc +/** + * The Interface IApplication. + */ +public interface IApplication { + + /** + * Adds the expense. + * + * @param expenseInput the expense input + * @return true, if successful + */ + boolean addExpense(ISplitInput splitInput); + + /** + * Gets the balance for user. + * + * @param userId the user id + * @return the balance for user + */ + SplitResult getBalanceForUser(String userId); + + /** + * Gets the all balances. + * + * @return the all balances + */ + SplitResult getAllBalances(); + + /** + * Gets the strategies name. + * + * @return the strategies name + */ + List getStrategiesName(); +} diff --git a/SplitWiseImpl/src/com/interfaces/IApplicationInterface.java b/SplitWiseImpl/src/com/interfaces/IApplicationInterface.java new file mode 100644 index 00000000..cb8ff1a2 --- /dev/null +++ b/SplitWiseImpl/src/com/interfaces/IApplicationInterface.java @@ -0,0 +1,13 @@ +package com.interfaces; + +import java.util.List; + +import com.user.UserDetails; + +public interface IApplicationInterface { + void instantiateApplication(); + + List runInputString(String input); + + boolean addNewUser(UserDetails userDetails); +} diff --git a/SplitWiseImpl/src/com/interfaces/IStrategyList.java b/SplitWiseImpl/src/com/interfaces/IStrategyList.java new file mode 100644 index 00000000..1566f137 --- /dev/null +++ b/SplitWiseImpl/src/com/interfaces/IStrategyList.java @@ -0,0 +1,20 @@ +package com.interfaces; + +import java.util.Map; + +import com.enums.SplitStrategyType; +import com.strategies.interfaces.ISplitStrategy; + +// TODO: Auto-generated Javadoc +/** + * The Interface IStrategyList. + */ +public interface IStrategyList { + + /** + * Gets the split strategies. + * + * @return the split strategies + */ + Map getSplitStrategies(); +} diff --git a/SplitWiseImpl/src/com/ioParser/InputReader.java b/SplitWiseImpl/src/com/ioParser/InputReader.java new file mode 100644 index 00000000..32977f24 --- /dev/null +++ b/SplitWiseImpl/src/com/ioParser/InputReader.java @@ -0,0 +1,87 @@ +package com.ioParser; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import com.enums.SplitStrategyType; +import com.ioParser.interfaces.IInputReader; +import com.strategies.equalDivisionStrategy.EqualStrategyInutGenerator; +import com.strategies.exactDivisionStrategy.ExactStartegyInputGenerator; +import com.strategies.interfaces.ISplitInput; +import com.strategies.interfaces.IStrategyInputGenerator; +import com.strategies.percentDivisionStrategy.PercentDivisionInputGenerator; +import com.strategies.splitObjects.SplitInput; + +// TODO: Auto-generated Javadoc +/** + * The Class InputReader. + */ +public class InputReader implements IInputReader { + + + /** The strategy input generator map. */ + HashMap strategyInputGeneratorMap; + + /** + * Instantiates a new input reader. + */ + public InputReader() { + this.strategyInputGeneratorMap = new HashMap(); + + this.strategyInputGeneratorMap.put(SplitStrategyType.EQUAL, new EqualStrategyInutGenerator()); + + this.strategyInputGeneratorMap.put(SplitStrategyType.EXACT, new ExactStartegyInputGenerator()); + + this.strategyInputGeneratorMap.put(SplitStrategyType.PERCENT, new PercentDivisionInputGenerator()); + } + + /** + * Parses the input. + * + * @param input the input + * @return the i split input + */ + @Override + public ISplitInput parseInput(List input) { + + if (input.size() < 6) { + return null; + } + + + + try { + String userId = input.get(0); + + double amount = Double.parseDouble(input.get(1)); + + int noOfParticipants = Integer.parseInt(input.get(2)); + + List participantList = new ArrayList(); + + int i = 3; + + while (i < 3 + noOfParticipants) { + participantList.add(input.get(i)); + i++; + } + + SplitStrategyType splitStrategyType = SplitStrategyType.valueOf(input.get(i)); + + + return this.strategyInputGeneratorMap.get(splitStrategyType).generateSplitInput(new SplitInput(userId, participantList, amount) { + + @Override + public SplitStrategyType getSplitInputType() { + // TODO Auto-generated method stub + return splitStrategyType; + } + }, input, i); + + } catch (Exception e) { + return null; + } + } + +} diff --git a/SplitWiseImpl/src/com/ioParser/ResultFormatter.java b/SplitWiseImpl/src/com/ioParser/ResultFormatter.java new file mode 100644 index 00000000..fe7ebf5d --- /dev/null +++ b/SplitWiseImpl/src/com/ioParser/ResultFormatter.java @@ -0,0 +1,86 @@ +package com.ioParser; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.dataStore.interfaces.IUserDataStore; +import com.ioParser.interfaces.IResultFormatter; +import com.strategies.splitObjects.SplitResult; + +public class ResultFormatter implements IResultFormatter{ + + + @Override + public List getFormattedResult(SplitResult splitResult, IUserDataStore userDataStore) { + List result = new ArrayList(); + + if (splitResult.getOwedBy() != null) { + Iterator it = splitResult.getOwedBy().keySet().iterator(); + + while (it.hasNext()) { + String next = it.next(); + + if (splitResult.getOwedBy().get(next) == null) { + continue; + } + + Iterator it1 = splitResult.getOwedBy().get(next).keySet().iterator(); + + while (it1.hasNext()) { + String next1 = it1.next(); + + double amount = splitResult.getOwedBy().get(next).get(next1); + + StringBuilder sb = new StringBuilder(); + + sb.append(userDataStore.getUserDetails(next1).getName()); + sb.append(" owes to "); + + sb.append(userDataStore.getUserDetails(next).getName()); + sb.append(": " + amount); + + result.add(sb.toString()); + } + } + } + + if (splitResult.getOwedTo() != null) { + Iterator it = splitResult.getOwedTo().keySet().iterator(); + + while (it.hasNext()) { + String next = it.next(); + + if (splitResult.getOwedTo().get(next) == null) { + continue; + } + + Iterator it1 = splitResult.getOwedTo().get(next).keySet().iterator(); + + while (it1.hasNext()) { + String next1 = it1.next(); + + double amount = splitResult.getOwedTo().get(next).get(next1); + + StringBuilder sb = new StringBuilder(); + + sb.append(userDataStore.getUserDetails(next).getName()); + sb.append(" owes to "); + + sb.append(userDataStore.getUserDetails(next1).getName()); + sb.append(": " + amount); + + result.add(sb.toString()); + } + } + } + + if (result.size() == 0) { + result.add("No Expenses"); + } + + return result; + + } + +} diff --git a/SplitWiseImpl/src/com/ioParser/interfaces/IInputReader.java b/SplitWiseImpl/src/com/ioParser/interfaces/IInputReader.java new file mode 100644 index 00000000..a3c06539 --- /dev/null +++ b/SplitWiseImpl/src/com/ioParser/interfaces/IInputReader.java @@ -0,0 +1,20 @@ +package com.ioParser.interfaces; + +import java.util.List; + +import com.strategies.interfaces.ISplitInput; + +// TODO: Auto-generated Javadoc +/** + * The Interface IInputReader. + */ +public interface IInputReader { + + /** + * Parses the input. + * + * @param input the input + * @return the i split input + */ + ISplitInput parseInput(List input); +} diff --git a/SplitWiseImpl/src/com/ioParser/interfaces/IResultFormatter.java b/SplitWiseImpl/src/com/ioParser/interfaces/IResultFormatter.java new file mode 100644 index 00000000..e46c35fb --- /dev/null +++ b/SplitWiseImpl/src/com/ioParser/interfaces/IResultFormatter.java @@ -0,0 +1,21 @@ +package com.ioParser.interfaces; + +import java.util.List; + +import com.dataStore.interfaces.IUserDataStore; +import com.strategies.splitObjects.SplitResult; + +// TODO: Auto-generated Javadoc +/** + * The Interface IResultFormatter. + */ +public interface IResultFormatter { + + /** + * Gets the formatted result. + * + * @param splitResult the split result + * @return the formatted result + */ + List getFormattedResult(SplitResult splitResult, IUserDataStore userDataStore); +} diff --git a/SplitWiseImpl/src/com/main/CommandLineMain.java b/SplitWiseImpl/src/com/main/CommandLineMain.java new file mode 100644 index 00000000..4445b6d2 --- /dev/null +++ b/SplitWiseImpl/src/com/main/CommandLineMain.java @@ -0,0 +1,37 @@ +package com.main; + +import java.util.Scanner; + +import com.application.ApplicationInterface; +import com.factory.DataStoreFactory; +import com.factory.StrategyListFactory; +import com.interfaces.IApplicationInterface; +import com.ioParser.InputReader; +import com.ioParser.ResultFormatter; +import com.user.UserDetails; + +public class CommandLineMain { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + IApplicationInterface applicationInterface = new ApplicationInterface(new DataStoreFactory(), new StrategyListFactory(), new ResultFormatter(), new InputReader()); + applicationInterface.addNewUser(new UserDetails("u1", "user 1", "user1@gmail.com", "11111")); + applicationInterface.addNewUser(new UserDetails("u2", "user 2", "user2@gmail.com", "22222")); + applicationInterface.addNewUser(new UserDetails("u3", "user 3", "user3@gmail.com", "33333")); + applicationInterface.addNewUser(new UserDetails("u4", "user 4", "user4@gmail.com", "44444")); + + applicationInterface.instantiateApplication(); + while (true) { + String next = sc.nextLine(); + if (next.equals("")) { + break; + } + applicationInterface.runInputString(next).stream().forEach(s -> { + System.out.println(s); + }); + } + + } + +} diff --git a/SplitWiseImpl/src/com/main/Main.java b/SplitWiseImpl/src/com/main/Main.java new file mode 100644 index 00000000..8d190728 --- /dev/null +++ b/SplitWiseImpl/src/com/main/Main.java @@ -0,0 +1,52 @@ +package com.main; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import com.application.ApplicationInterface; +import com.factory.DataStoreFactory; +import com.factory.StrategyListFactory; +import com.interfaces.IApplicationInterface; +import com.ioParser.InputReader; +import com.ioParser.ResultFormatter; +import com.user.UserDetails; + +public class Main { + + public static void main(String[] args) { + IApplicationInterface applicationInterface = new ApplicationInterface(new DataStoreFactory(), new StrategyListFactory(), new ResultFormatter(), new InputReader()); + + + applicationInterface.addNewUser(new UserDetails("u1", "user 1", "user1@gmail.com", "11111")); + applicationInterface.addNewUser(new UserDetails("u2", "user 2", "user2@gmail.com", "22222")); + applicationInterface.addNewUser(new UserDetails("u3", "user 3", "user3@gmail.com", "33333")); + applicationInterface.addNewUser(new UserDetails("u4", "user 4", "user4@gmail.com", "44444")); + + applicationInterface.instantiateApplication(); + List result = new ArrayList(); + Iterator it = Arrays.asList("SHOW", "SHOW u1", "EXPENSE u1 1000 4 u1 u2 u3 u4 EQUAL", "SHOW u4", "SHOW u1", "EXPENSE u1 1250 2 u2 u3 EXACT 370 880", "SHOW", "EXPENSE u4 1200 4 u1 u2 u3 u4 PERCENT 40 20 20 20", "SHOW u1", "SHOW").listIterator(); + + while (it.hasNext()) { + String next = it.next(); + +// System.out.println(next); + + result.addAll(applicationInterface.runInputString(next)); + + // System.out.println( applicationInterface.runInputString(next)); + +// result.add("-----------------"); + + } + + // System.out.println(result); + + result.stream().forEach(s -> { + System.out.println(s); + }); + + } + +} diff --git a/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualDivisionSplitStrategy.java b/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualDivisionSplitStrategy.java new file mode 100644 index 00000000..8a4b36a9 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualDivisionSplitStrategy.java @@ -0,0 +1,113 @@ +package com.strategies.equalDivisionStrategy; + +import java.util.HashMap; +import java.util.ListIterator; + +import com.enums.InputValidationResult; +import com.enums.SplitStrategyType; +import com.strategies.interfaces.ISplitInput; +import com.strategies.interfaces.ISplitStrategy; +import com.strategies.splitObjects.SplitResult; + +// TODO: Auto-generated Javadoc +/** + * The Class EqualDivisionSplitStrategy. + */ +public class EqualDivisionSplitStrategy implements ISplitStrategy { + + + /** + * Instantiates a new equal division split strategy. + */ + public EqualDivisionSplitStrategy() { + // TODO Auto-generated constructor stub + } + + /** + * Gets the final split. + * + * @param splitInput the split input + * @return the final split + */ + @Override + public SplitResult getFinalSplit(ISplitInput splitInput) { + + if (this.verifyInput(splitInput) != InputValidationResult.VALID) { + return null; + } + + EqualStrategySplitInput input; + + input = (EqualStrategySplitInput) splitInput; + + + HashMap> owedByMap = new HashMap>(); + HashMap> owedToMap = new HashMap>(); + HashMap owedMap = new HashMap(); + HashMap owesMap = new HashMap(); + + double amountPerPerson = input.getPaidAmount() / input.getParticipants().size(); + + owedByMap.put(input.getPaidBy(), new HashMap()); + + + ListIterator it = input.getParticipants().listIterator(); + + while (it.hasNext()) { + String next = it.next(); + + if (owedByMap.containsKey(next)) { + continue; + } + + owedByMap.get(input.getPaidBy()).put(next, amountPerPerson); + + if (!owedToMap.containsKey(next)) { + owedToMap.put(next, new HashMap()); + } + + owedToMap.get(next).put(input.getPaidBy(), amountPerPerson); + + owesMap.put(next, amountPerPerson); + + } + + owedMap.put(input.getPaidBy(), amountPerPerson * input.getParticipants().size()); + + return new SplitResult(owedByMap, owedToMap, owedMap, owesMap); + + } + + /** + * Verify input. + * + * @param splitInput the split input + * @return the input validation result + */ + @Override + public InputValidationResult verifyInput(ISplitInput splitInput) { + try { + EqualStrategySplitInput input; + + input = (EqualStrategySplitInput) splitInput; + + return input != null ? InputValidationResult.VALID : InputValidationResult.WRONG_INPUT_FORMAT; + } catch (Exception e) { + return InputValidationResult.WRONG_INPUT_FORMAT; + } + } + + /** + * Gets the spli strategy type. + * + * @return the spli strategy type + */ + @Override + public SplitStrategyType getSpliStrategyType() { + // TODO Auto-generated method stub + return SplitStrategyType.EQUAL; + } + + + +} diff --git a/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualStrategyInutGenerator.java b/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualStrategyInutGenerator.java new file mode 100644 index 00000000..6674c7bf --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualStrategyInutGenerator.java @@ -0,0 +1,29 @@ +package com.strategies.equalDivisionStrategy; + +import java.util.List; + +import com.strategies.interfaces.ISplitInput; +import com.strategies.splitObjects.SplitInput; +import com.strategies.splitObjects.StrategyInputGenerator; + +// TODO: Auto-generated Javadoc +/** + * The Class EqualStrategyInutGenerator. + */ +public class EqualStrategyInutGenerator extends StrategyInputGenerator { + + /** + * Generate split input. + * + * @param baseInput the base input + * @param input the input + * @param lastVisitedIndex the last visited index + * @return the equal strategy split input + */ + @Override + public EqualStrategySplitInput generateSplitInput(ISplitInput baseInput, List input, int lastVisitedIndex) { + SplitInput baseInput2 = super.generateSplitInput(baseInput, input, lastVisitedIndex); + + return new EqualStrategySplitInput(baseInput2.getPaidBy(), baseInput2.getParticipants(), baseInput2.getPaidAmount()); + } +} diff --git a/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualStrategySplitInput.java b/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualStrategySplitInput.java new file mode 100644 index 00000000..ddfe2086 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/equalDivisionStrategy/EqualStrategySplitInput.java @@ -0,0 +1,39 @@ +package com.strategies.equalDivisionStrategy; + +import java.util.List; + +import com.enums.SplitStrategyType; +import com.strategies.splitObjects.SplitInput; + +// TODO: Auto-generated Javadoc +/** + * The Class EqualStrategySplitInput. + */ +public class EqualStrategySplitInput extends SplitInput { + + /** + * Instantiates a new equal strategy split input. + * + * @param paidBy the paid by + * @param participants the participants + * @param paidAmount the paid amount + */ + public EqualStrategySplitInput(String paidBy, List participants, double paidAmount) { + super(paidBy, participants, paidAmount); + } + + /** + * Gets the split input type. + * + * @return the split input type + */ + @Override + public SplitStrategyType getSplitInputType() { + + // TODO Auto-generated method stub + return SplitStrategyType.EQUAL; + } + + + +} diff --git a/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactDivisionSplitStrategy.java b/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactDivisionSplitStrategy.java new file mode 100644 index 00000000..a09a031b --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactDivisionSplitStrategy.java @@ -0,0 +1,116 @@ +package com.strategies.exactDivisionStrategy; + +import java.util.HashMap; +import java.util.Iterator; + +import com.enums.InputValidationResult; +import com.enums.SplitStrategyType; +import com.strategies.interfaces.ISplitInput; +import com.strategies.interfaces.ISplitStrategy; +import com.strategies.splitObjects.SplitResult; + +// TODO: Auto-generated Javadoc +/** + * The Class ExactDivisionSplitStrategy. + */ +public class ExactDivisionSplitStrategy implements ISplitStrategy { + + /** + * Verify input. + * + * @param splitInput the split input + * @return the input validation result + */ + @Override + public InputValidationResult verifyInput(ISplitInput splitInput) { + ExactStrategySplitInput input; + + try { + input = (ExactStrategySplitInput) splitInput; + + double sum = 0.0; + + Iterator it = input.getExactAmountOwedMap().keySet().iterator(); + + while (it.hasNext()) { + sum += input.getExactAmountOwedMap().get(it.next()); + } + + double diff = sum - input.getPaidAmount(); + + if (diff < 0) { + diff *= -1.0; + } + + if (diff > 0.01) { + return InputValidationResult.SUM_NOT_EQUAL_TO_TOTAL_PAID; + } + + return InputValidationResult.VALID; + } catch (Exception e) { + return InputValidationResult.WRONG_INPUT_FORMAT; + } + } + + /** + * Gets the final split. + * + * @param splitInput the split input + * @return the final split + */ + @Override + public SplitResult getFinalSplit(ISplitInput splitInput) { + if (this.verifyInput(splitInput) != InputValidationResult.VALID) { + return null; + } + + ExactStrategySplitInput input = (ExactStrategySplitInput) splitInput; + + HashMap> owedByMap = new HashMap>(); + HashMap> owedToMap = new HashMap>(); + HashMap owedMap = new HashMap(); + HashMap owesMap = new HashMap(); + + owedByMap.put(input.getPaidBy(), new HashMap()); + + Iterator it = input.getExactAmountOwedMap().keySet().iterator(); + + double sum = 0.0; + + while (it.hasNext()) { + String next = it.next(); + + if (owedByMap.containsKey(next)) { + continue; + } + + owedByMap.get(input.getPaidBy()).put(next, input.getExactAmountOwedMap().get(next)); + + if (!owedToMap.containsKey(next)) { + owedToMap.put(next, new HashMap()); + } + + owedToMap.get(next).put(input.getPaidBy(), input.getExactAmountOwedMap().get(next)); + + owesMap.put(next, input.getExactAmountOwedMap().get(next)); + + sum += input.getExactAmountOwedMap().get(next); + } + + owedMap.put(input.getPaidBy(), sum); + + return new SplitResult(owedByMap, owedToMap, owedMap, owesMap); + } + + /** + * Gets the spli strategy type. + * + * @return the spli strategy type + */ + @Override + public SplitStrategyType getSpliStrategyType() { + // TODO Auto-generated method stub + return SplitStrategyType.EXACT; + } + +} diff --git a/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactStartegyInputGenerator.java b/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactStartegyInputGenerator.java new file mode 100644 index 00000000..1594c959 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactStartegyInputGenerator.java @@ -0,0 +1,48 @@ +package com.strategies.exactDivisionStrategy; + +import java.util.HashMap; +import java.util.List; + +import com.strategies.interfaces.ISplitInput; +import com.strategies.splitObjects.SplitInput; +import com.strategies.splitObjects.StrategyInputGenerator; + +// TODO: Auto-generated Javadoc +/** + * The Class ExactStartegyInputGenerator. + */ +public class ExactStartegyInputGenerator extends StrategyInputGenerator { + + /** + * Generate split input. + * + * @param baseInput the base input + * @param input the input + * @param lastVisitedIndex the last visited index + * @return the exact strategy split input + */ + @Override + public ExactStrategySplitInput generateSplitInput(ISplitInput baseInput, List input, int lastVisitedIndex) { + SplitInput baseInput2 = super.generateSplitInput(baseInput, input, lastVisitedIndex); + + int i = lastVisitedIndex; + i++; + HashMap amountOwedMap = new HashMap(); + + int count = 0; + + while (count < baseInput2.getParticipants().size()) { + + if (i < input.size()) { + amountOwedMap.put(baseInput2.getParticipants().get(count), Double.parseDouble(input.get(i))); + i++; + } else { + amountOwedMap.put(baseInput2.getParticipants().get(count), 0.0); + } + + count++; + } + return new ExactStrategySplitInput(baseInput2.getPaidBy(), baseInput2.getParticipants(), baseInput2.getPaidAmount(), amountOwedMap); + + } +} diff --git a/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactStrategySplitInput.java b/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactStrategySplitInput.java new file mode 100644 index 00000000..76aa142b --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/exactDivisionStrategy/ExactStrategySplitInput.java @@ -0,0 +1,54 @@ +package com.strategies.exactDivisionStrategy; + +import java.util.HashMap; +import java.util.List; + +import com.enums.SplitStrategyType; +import com.strategies.splitObjects.SplitInput; + +// TODO: Auto-generated Javadoc +/** + * The Class ExactStrategySplitInput. + */ +public class ExactStrategySplitInput extends SplitInput { + + /** The exact amount owed map. */ + private HashMap exactAmountOwedMap; + + /** + * Instantiates a new exact strategy split input. + * + * @param paidBy the paid by + * @param participants the participants + * @param paidAmount the paid amount + * @param exactAmountOwedMap the exact amount owed map + */ + public ExactStrategySplitInput(String paidBy, List participants, double paidAmount, + HashMap exactAmountOwedMap) { + super(paidBy, participants, paidAmount); + this.exactAmountOwedMap = exactAmountOwedMap; + } + + /** + * Gets the exact amount owed map. + * + * @return the exact amount owed map + */ + public HashMap getExactAmountOwedMap() { + return exactAmountOwedMap; + } + + /** + * Gets the split input type. + * + * @return the split input type + */ + @Override + public SplitStrategyType getSplitInputType() { + + // TODO Auto-generated method stub + return SplitStrategyType.EXACT; + } + + +} diff --git a/SplitWiseImpl/src/com/strategies/interfaces/ISplitInput.java b/SplitWiseImpl/src/com/strategies/interfaces/ISplitInput.java new file mode 100644 index 00000000..ce90af09 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/interfaces/ISplitInput.java @@ -0,0 +1,17 @@ +package com.strategies.interfaces; + +import com.enums.SplitStrategyType; + +// TODO: Auto-generated Javadoc +/** + * The Interface ISplitInput. + */ +public interface ISplitInput { + + /** + * Gets the split input type. + * + * @return the split input type + */ + SplitStrategyType getSplitInputType(); +} diff --git a/SplitWiseImpl/src/com/strategies/interfaces/ISplitStrategy.java b/SplitWiseImpl/src/com/strategies/interfaces/ISplitStrategy.java new file mode 100644 index 00000000..1b7e26a6 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/interfaces/ISplitStrategy.java @@ -0,0 +1,34 @@ +package com.strategies.interfaces; +import com.enums.InputValidationResult; +import com.enums.SplitStrategyType; +import com.strategies.splitObjects.SplitResult; + +// TODO: Auto-generated Javadoc +/** + * The Interface ISplitStrategy. + */ +public interface ISplitStrategy { + + /** + * Verify input. + * + * @param splitInput the split input + * @return the input validation result + */ + InputValidationResult verifyInput(ISplitInput splitInput); + + /** + * Gets the final split. + * + * @param splitInput the split input + * @return the final split + */ + SplitResult getFinalSplit(ISplitInput splitInput); + + /** + * Gets the spli strategy type. + * + * @return the spli strategy type + */ + SplitStrategyType getSpliStrategyType(); +} diff --git a/SplitWiseImpl/src/com/strategies/interfaces/IStrategyInputGenerator.java b/SplitWiseImpl/src/com/strategies/interfaces/IStrategyInputGenerator.java new file mode 100644 index 00000000..619130f2 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/interfaces/IStrategyInputGenerator.java @@ -0,0 +1,20 @@ +package com.strategies.interfaces; + +import java.util.List; + +// TODO: Auto-generated Javadoc +/** + * The Interface IStrategyInputGenerator. + */ +public interface IStrategyInputGenerator { + + /** + * Generate split input. + * + * @param baseInput the base input + * @param input the input + * @param lastVisitedIndex the last visited index + * @return the i split input + */ + ISplitInput generateSplitInput(ISplitInput baseInput, List input, int lastVisitedIndex); +} diff --git a/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionInputGenerator.java b/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionInputGenerator.java new file mode 100644 index 00000000..2fa35d3f --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionInputGenerator.java @@ -0,0 +1,48 @@ +package com.strategies.percentDivisionStrategy; + +import java.util.HashMap; +import java.util.List; + +import com.strategies.interfaces.ISplitInput; +import com.strategies.splitObjects.SplitInput; +import com.strategies.splitObjects.StrategyInputGenerator; + +// TODO: Auto-generated Javadoc +/** + * The Class PercentDivisionInputGenerator. + */ +public class PercentDivisionInputGenerator extends StrategyInputGenerator { + + /** + * Generate split input. + * + * @param baseInput the base input + * @param input the input + * @param lastVisitedIndex the last visited index + * @return the percent division split input + */ + @Override + public PercentDivisionSplitInput generateSplitInput(ISplitInput baseInput, List input, int lastVisitedIndex) { + SplitInput baseInput2 = super.generateSplitInput(baseInput, input, lastVisitedIndex); + + int i = lastVisitedIndex; + i++; + HashMap percentOwedMap = new HashMap(); + + int count = 0; + + while (count < baseInput2.getParticipants().size()) { + + if (i < input.size()) { + percentOwedMap.put(baseInput2.getParticipants().get(count), Double.parseDouble(input.get(i))); + i++; + } else { + percentOwedMap.put(baseInput2.getParticipants().get(count), 0.0); + } + + count++; + } + return new PercentDivisionSplitInput(baseInput2.getPaidBy(), baseInput2.getParticipants(), baseInput2.getPaidAmount(), percentOwedMap); + + } +} diff --git a/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionSplitInput.java b/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionSplitInput.java new file mode 100644 index 00000000..7077aa2a --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionSplitInput.java @@ -0,0 +1,51 @@ +package com.strategies.percentDivisionStrategy; + +import java.util.HashMap; +import java.util.List; + +import com.enums.SplitStrategyType; +import com.strategies.splitObjects.SplitInput; + +// TODO: Auto-generated Javadoc +/** + * The Class PercentDivisionSplitInput. + */ +public class PercentDivisionSplitInput extends SplitInput { + + /** The percent owed map. */ + private HashMap percentOwedMap; + + /** + * Instantiates a new percent division split input. + * + * @param paidBy the paid by + * @param participants the participants + * @param paidAmount the paid amount + * @param percentOwedMap the percent owed map + */ + public PercentDivisionSplitInput(String paidBy, List participants, double paidAmount, + HashMap percentOwedMap) { + super(paidBy, participants, paidAmount); + this.percentOwedMap = percentOwedMap; + } + + /** + * Gets the percent owed map. + * + * @return the percent owed map + */ + public HashMap getPercentOwedMap() { + return percentOwedMap; + } + + /** + * Gets the split input type. + * + * @return the split input type + */ + @Override + public SplitStrategyType getSplitInputType() { + + return SplitStrategyType.PERCENT; + } +} diff --git a/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionSplitStrategy.java b/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionSplitStrategy.java new file mode 100644 index 00000000..7cf0a3d5 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/percentDivisionStrategy/PercentDivisionSplitStrategy.java @@ -0,0 +1,112 @@ +package com.strategies.percentDivisionStrategy; + +import java.util.HashMap; +import java.util.Iterator; + +import com.enums.InputValidationResult; +import com.enums.SplitStrategyType; +import com.strategies.interfaces.ISplitInput; +import com.strategies.interfaces.ISplitStrategy; +import com.strategies.splitObjects.SplitResult; + +// TODO: Auto-generated Javadoc +/** + * The Class PercentDivisionSplitStrategy. + */ +public class PercentDivisionSplitStrategy implements ISplitStrategy { + + /** The percentage 100. */ + static public double PERCENTAGE_100 = 100.0; + + /** + * Verify input. + * + * @param splitInput the split input + * @return the input validation result + */ + @Override + public InputValidationResult verifyInput(ISplitInput splitInput) { + try { + PercentDivisionSplitInput input = (PercentDivisionSplitInput) splitInput; + + Iterator it = input.getPercentOwedMap().keySet().iterator(); + double sum = 0.0; + while (it.hasNext()) { + sum += input.getPercentOwedMap().get(it.next()); + } + + if (sum != PercentDivisionSplitStrategy.PERCENTAGE_100) { + return InputValidationResult.SUM_NOT_EQUAL_TO_TOTAL_PAID; + } + + return InputValidationResult.VALID; + } catch (Exception e) { + return InputValidationResult.WRONG_INPUT_FORMAT; + } + } + + /** + * Gets the final split. + * + * @param splitInput the split input + * @return the final split + */ + @Override + public SplitResult getFinalSplit(ISplitInput splitInput) { + if (this.verifyInput(splitInput) != InputValidationResult.VALID) { + return null; + } + + PercentDivisionSplitInput input = (PercentDivisionSplitInput) splitInput; + + HashMap> owedByMap = new HashMap>(); + HashMap> owedToMap = new HashMap>(); + HashMap owedMap = new HashMap(); + HashMap owesMap = new HashMap(); + + owedByMap.put(input.getPaidBy(), new HashMap()); + + Iterator it = input.getPercentOwedMap().keySet().iterator(); + + double sum = 0.0; + + while (it.hasNext()) { + String next = it.next(); + + if (owedByMap.containsKey(next)) { + continue; + } + + double amountOwed = (input.getPercentOwedMap().get(next) * input.getPaidAmount()) / 100.0; + + owedByMap.get(input.getPaidBy()).put(next, amountOwed); + + if (!owedToMap.containsKey(next)) { + owedToMap.put(next, new HashMap()); + } + + + owedToMap.get(next).put(input.getPaidBy(), amountOwed); + + owesMap.put(next, amountOwed); + + sum += amountOwed; + } + + owedMap.put(input.getPaidBy(), sum); + + return new SplitResult(owedByMap, owedToMap, owedMap, owesMap); + } + + /** + * Gets the spli strategy type. + * + * @return the spli strategy type + */ + @Override + public SplitStrategyType getSpliStrategyType() { + // TODO Auto-generated method stub + return SplitStrategyType.PERCENT; + } + +} diff --git a/SplitWiseImpl/src/com/strategies/splitObjects/SplitInput.java b/SplitWiseImpl/src/com/strategies/splitObjects/SplitInput.java new file mode 100644 index 00000000..296f4031 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/splitObjects/SplitInput.java @@ -0,0 +1,93 @@ +package com.strategies.splitObjects; + +import java.util.List; + +import com.strategies.interfaces.ISplitInput; + +// TODO: Auto-generated Javadoc +/** + * The Class SplitInput. + */ +public abstract class SplitInput implements ISplitInput { + + /** + * Instantiates a new split input. + * + * @param paidBy the paid by + * @param participants the participants + * @param paidAmount the paid amount + */ + public SplitInput(String paidBy, List participants, double paidAmount) { + super(); + this.paidBy = paidBy; + this.participants = participants; + this.paidAmount = paidAmount; + } + + /** The paid by. */ + private String paidBy; + + /** The participants. */ + private List participants; + + /** The paid amount. */ + private double paidAmount; + + + + /** + * Gets the paid by. + * + * @return the paid by + */ + public String getPaidBy() { + return paidBy; + } + + /** + * Gets the paid amount. + * + * @return the paid amount + */ + public double getPaidAmount() { + return paidAmount; + } + + /** + * Sets the paid amount. + * + * @param paidAmount the new paid amount + */ + public void setPaidAmount(double paidAmount) { + this.paidAmount = paidAmount; + } + + /** + * Sets the paid by. + * + * @param paidBy the new paid by + */ + public void setPaidBy(String paidBy) { + this.paidBy = paidBy; + } + + /** + * Gets the participants. + * + * @return the participants + */ + public List getParticipants() { + return participants; + } + + /** + * Sets the participants. + * + * @param participants the new participants + */ + public void setParticipants(List participants) { + this.participants = participants; + } + + +} diff --git a/SplitWiseImpl/src/com/strategies/splitObjects/SplitResult.java b/SplitWiseImpl/src/com/strategies/splitObjects/SplitResult.java new file mode 100644 index 00000000..f8c94064 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/splitObjects/SplitResult.java @@ -0,0 +1,70 @@ +package com.strategies.splitObjects; + +import java.util.HashMap; + +// TODO: Auto-generated Javadoc +/** + * The Class SplitResult. + */ +public class SplitResult { + + /** The owed by. */ + HashMap> owedBy; + + /** The owed to. */ + HashMap> owedTo; + + /** The owed map. */ + HashMap owedMap; + + /** The owes map. */ + HashMap owesMap; + + + + /** + * Instantiates a new split result. + */ + public SplitResult() { + super(); + this.owedBy = new HashMap>(); + this.owedTo = new HashMap>(); + this.owedMap = new HashMap(); + this.owesMap = new HashMap(); + } + + /** + * Instantiates a new split result. + * + * @param owedBy the owed by + * @param owedTo the owed to + * @param owedMap the owed map + * @param owesMap the owes map + */ + public SplitResult(HashMap> owedBy, HashMap> owedTo, + HashMap owedMap, HashMap owesMap) { + super(); + this.owedBy = owedBy; + this.owedTo = owedTo; + this.owedMap = owedMap; + this.owesMap = owesMap; + } + + /** + * Gets the owed by. + * + * @return the owed by + */ + public HashMap> getOwedBy() { + return owedBy; + } + + /** + * Gets the owed to. + * + * @return the owed to + */ + public HashMap> getOwedTo() { + return owedTo; + } +} diff --git a/SplitWiseImpl/src/com/strategies/splitObjects/StrategyInputGenerator.java b/SplitWiseImpl/src/com/strategies/splitObjects/StrategyInputGenerator.java new file mode 100644 index 00000000..c36aadc0 --- /dev/null +++ b/SplitWiseImpl/src/com/strategies/splitObjects/StrategyInputGenerator.java @@ -0,0 +1,31 @@ +package com.strategies.splitObjects; + +import java.util.List; + +import com.strategies.interfaces.ISplitInput; +import com.strategies.interfaces.IStrategyInputGenerator; + +// TODO: Auto-generated Javadoc +/** + * The Class StrategyInputGenerator. + */ +public abstract class StrategyInputGenerator implements IStrategyInputGenerator { + + /** + * Generate split input. + * + * @param baseInput the base input + * @param input the input + * @param lastVisitedIndex the last visited index + * @return the split input + */ + @Override + public SplitInput generateSplitInput(ISplitInput baseInput, List input, int lastVisitedIndex) { + try { + return (SplitInput) baseInput; + } catch (Exception e) { + return null; + } + } + +} diff --git a/SplitWiseImpl/src/com/user/User.java b/SplitWiseImpl/src/com/user/User.java new file mode 100644 index 00000000..1dcd9348 --- /dev/null +++ b/SplitWiseImpl/src/com/user/User.java @@ -0,0 +1,46 @@ +package com.user; + +import com.dataStore.interfaces.IUserDataStore; +import com.user.interfaces.IUser; + +public class User implements IUser{ + private UserDetails userDetails; + + private String userId; + + private IUserDataStore userDataStore; + + + public User(String userId, IUserDataStore userDataStore) { + super(); + this.userId = userId; + this.userDataStore = userDataStore; + } + + @Override + public UserDetails getUserDetails() { + if (this.userDetails != null) { + return this.userDetails; + } + + this.userDetails = this.userDataStore.getUserDetails(this.userId); + + return this.userDetails; + } + + @Override + public boolean updateUserDetails(UserDetails userDetails) { + boolean result = this.userDataStore.updateUserDetails(this.userId, userDetails); + + if (!result) { + return false; + } + + this.userDetails = this.userDataStore.getUserDetails(this.userId); + + return true; + + } + + +} diff --git a/SplitWiseImpl/src/com/user/UserDetails.java b/SplitWiseImpl/src/com/user/UserDetails.java new file mode 100644 index 00000000..1622a8ea --- /dev/null +++ b/SplitWiseImpl/src/com/user/UserDetails.java @@ -0,0 +1,111 @@ +package com.user; + +// TODO: Auto-generated Javadoc +/** + * The Class UserDetails. + */ +public class UserDetails { + + /** The user id. */ + String userId; + + /** The name. */ + String name; + + /** The email. */ + String email; + + /** The phone number. */ + String phoneNumber; + + /** + * Instantiates a new user details. + * + * @param userId the user id + * @param name the name + * @param email the email + * @param phoneNumber the phone number + */ + public UserDetails(String userId, String name, String email, String phoneNumber) { + super(); + this.userId = userId; + this.name = name; + this.email = email; + this.phoneNumber = phoneNumber; + } + + + /** + * Gets the user id. + * + * @return the user id + */ + public String getUserId() { + return userId; + } + + /** + * Sets the user id. + * + * @param userId the new user id + */ + public void setUserId(String userId) { + this.userId = userId; + } + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Sets the name. + * + * @param name the new name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the email. + * + * @return the email + */ + public String getEmail() { + return email; + } + + /** + * Sets the email. + * + * @param email the new email + */ + public void setEmail(String email) { + this.email = email; + } + + /** + * Gets the phone number. + * + * @return the phone number + */ + public String getPhoneNumber() { + return phoneNumber; + } + + /** + * Sets the phone number. + * + * @param phoneNumber the new phone number + */ + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + +} diff --git a/SplitWiseImpl/src/com/user/interfaces/IUser.java b/SplitWiseImpl/src/com/user/interfaces/IUser.java new file mode 100644 index 00000000..68232f54 --- /dev/null +++ b/SplitWiseImpl/src/com/user/interfaces/IUser.java @@ -0,0 +1,27 @@ +package com.user.interfaces; + +import com.user.UserDetails; + +// TODO: Auto-generated Javadoc +/** + * The Interface IUser. + */ +public interface IUser { + + /** + * Gets the user details. + * + * @param userId the user id + * @return the user details + */ + UserDetails getUserDetails(); + + /** + * Update user details. + * + * @param userId the user id + * @param userDetails the user details + * @return true, if successful + */ + boolean updateUserDetails(UserDetails userDetails); +} diff --git a/SplitWiseImpl/src/module-info.java b/SplitWiseImpl/src/module-info.java new file mode 100644 index 00000000..7839cd4b --- /dev/null +++ b/SplitWiseImpl/src/module-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * + */ +module SplitwiseImpl { +} \ No newline at end of file