diff --git a/.classpath b/.classpath new file mode 100644 index 00000000..68a6cf82 --- /dev/null +++ b/.classpath @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..60e67366 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +/target/ +metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 00000000..b177a606 --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + cashregister + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/SOLUTION.md b/SOLUTION.md new file mode 100644 index 00000000..98ea654d --- /dev/null +++ b/SOLUTION.md @@ -0,0 +1,2 @@ +To test the solution, go to the tests for the file parser service and run. Check the output.txt file to see the output. +Feel free to add files for testing. Just make sure to update the file paths in the tests. diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..6c197231 --- /dev/null +++ b/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.5.4 + + + com.softwriters + cashregister + 0.0.1-SNAPSHOT + cashregister + Softwriters Code Assessment + + 1.8 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + diff --git a/src/main/java/com/softwriters/cashregister/CashregisterApplication.java b/src/main/java/com/softwriters/cashregister/CashregisterApplication.java new file mode 100644 index 00000000..3a04b8e0 --- /dev/null +++ b/src/main/java/com/softwriters/cashregister/CashregisterApplication.java @@ -0,0 +1,13 @@ +package com.softwriters.cashregister; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CashregisterApplication { + + public static void main(String[] args) { + SpringApplication.run(CashregisterApplication.class, args); + } + +} diff --git a/src/main/java/com/softwriters/cashregister/model/ChangeModel.java b/src/main/java/com/softwriters/cashregister/model/ChangeModel.java new file mode 100644 index 00000000..1df1fe3f --- /dev/null +++ b/src/main/java/com/softwriters/cashregister/model/ChangeModel.java @@ -0,0 +1,52 @@ +package com.softwriters.cashregister.model; + +import java.math.BigDecimal; + +public class ChangeModel { + + private BigDecimal value; + + private String currencyNameSingular; + + private String currencyNamePlural; + + public ChangeModel(String value, String currencyNameSingular, String currencyNamePlural) { + this.value = new BigDecimal(value); + this.currencyNameSingular = currencyNameSingular; + this.currencyNamePlural = currencyNamePlural; + } + + public BigDecimal getValue() { + return value; + } + + public void setValue(BigDecimal value) { + this.value = value; + } + + public String getCurrencyNameSingular() { + return currencyNameSingular; + } + + public void setCurrencyNameSingular(String currencyNameSingular) { + this.currencyNameSingular = currencyNameSingular; + } + + public String getCurrencyNamePlural() { + return currencyNamePlural; + } + + public void setCurrencyNamePlural(String currencyNamePlural) { + this.currencyNamePlural = currencyNamePlural; + } + + public String getCurrencyName(int numberOfDenominations) { + if(numberOfDenominations>1) { + return this.currencyNamePlural; + } + else { + return this.currencyNameSingular; + } + } + +} diff --git a/src/main/java/com/softwriters/cashregister/service/ChangeProcessingService.java b/src/main/java/com/softwriters/cashregister/service/ChangeProcessingService.java new file mode 100644 index 00000000..d3d7588e --- /dev/null +++ b/src/main/java/com/softwriters/cashregister/service/ChangeProcessingService.java @@ -0,0 +1,88 @@ +package com.softwriters.cashregister.service; + +import java.math.BigDecimal; +import java.util.HashSet; + +import com.softwriters.cashregister.util.ChangeUtil; + +public class ChangeProcessingService { + + public ChangeProcessingService() { + + } + + public String calculateChange(BigDecimal totalDue, BigDecimal amountGiven) { + + String change = ""; + //Determine change needed + BigDecimal changeNeeded = amountGiven.subtract(totalDue); + + for(int i=0;i0) + change += numberOfChange + " " + ChangeUtil.change[i].getCurrencyName(numberOfChange) + ","; + + + } + + return change.substring(0, change.length()-1); + } + + public String calculateRandomChange(BigDecimal totalDue, BigDecimal amountGiven) { + + String change = ""; + + //Determine change needed + BigDecimal changeNeeded = amountGiven.subtract(totalDue); + + //Create a hash set to keep track of used change value indexes + HashSet indexSet = new HashSet<>(); + + //While all denominations haven't been used and change needed isn't zero + while(indexSet.size()!=ChangeUtil.change.length && changeNeeded.compareTo(ChangeUtil.zero)!= 0) { + + //generate random index + int randomIndex = generateRandomIndex(); + + //check to see if random index already used; if so re-calculate till find one + while(indexSet.contains(randomIndex)) { + randomIndex = generateRandomIndex(); + } + + int numberOfChange = 0; + + //subtract change till at zero or less than zero + while((changeNeeded.subtract(ChangeUtil.change[randomIndex].getValue()).compareTo(ChangeUtil.zero)==1)|| + (changeNeeded.subtract(ChangeUtil.change[randomIndex].getValue()).compareTo(ChangeUtil.zero)==0)) { + + numberOfChange++; + changeNeeded = changeNeeded.subtract(ChangeUtil.change[randomIndex].getValue()); + } + + if(numberOfChange>0) + change += numberOfChange + " " + ChangeUtil.change[randomIndex].getCurrencyName(numberOfChange) + ","; + + //Add index to set + indexSet.add(randomIndex); + } + + + return change.substring(0, change.length()-1); + } + + private int generateRandomIndex() { + int random = (int)(Math.random() * ChangeUtil.change.length); + return random; + } +} diff --git a/src/main/java/com/softwriters/cashregister/service/FlatFileParserService.java b/src/main/java/com/softwriters/cashregister/service/FlatFileParserService.java new file mode 100644 index 00000000..652709fc --- /dev/null +++ b/src/main/java/com/softwriters/cashregister/service/FlatFileParserService.java @@ -0,0 +1,82 @@ +package com.softwriters.cashregister.service; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Scanner; + +public class FlatFileParserService { + + public FlatFileParserService() { + + } + + public File processFile(File inputFile) throws IOException { + + //Create Change Processing Service + ChangeProcessingService changeProcessor = new ChangeProcessingService(); + + //Scan in the input file + Scanner readFile = new Scanner(inputFile); + + //Create an output file + File output = new File("output.txt"); + output.createNewFile(); + + //Create a file writer to write to output file + FileWriter fileWriter = new FileWriter("output.txt"); + //While the scanner sees new tokens + while(readFile.hasNext()) { + + //Grab the next String token and split using a delimiter + String currentString = readFile.next(); + String[] values = currentString.split(","); + + //Convert two numbers to double values + BigDecimal totalDue = new BigDecimal(values[0]); + BigDecimal paid = new BigDecimal(values[1]); + + //Write change due strings to the file + if(isDivisibleByThree(values[0])) { + fileWriter.write("\n"+changeProcessor.calculateRandomChange(totalDue, paid)); + } + else { + fileWriter.write("\n"+changeProcessor.calculateChange(totalDue, paid)); + } + + //If more input in file, go to next line + if(readFile.hasNextLine()) { + readFile.nextLine(); + } + } + + //close scanner and writer + fileWriter.close(); + readFile.close(); + + return output; + } + + + private boolean isDivisibleByThree(String totalDue) { + + int sumOfDigits = 0; + //Add each digit in the string + for(int i = 0;i