diff --git a/src/main/java/Consumer.java b/src/main/java/Consumer.java index d233629..27f4523 100644 --- a/src/main/java/Consumer.java +++ b/src/main/java/Consumer.java @@ -1,9 +1,67 @@ +import java.time.LocalDate; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class Consumer { + + + private LocalDate currDate; + + Consumer(){ + } + + Consumer(LocalDate currDate){ + this.currDate = currDate; + } public InvoiceStatistics consumeInvoices(List invoices) { - // TODO: Implement the invoice processing logic - return null; + Map invoicesCountByOrgMap = getInvoicesCountByOrg(invoices); + Map overDueInvoicesCountByOrg = getOverDueInvoicesCountByOrg(invoices,currDate); + Map> invoicesCountByOrgMapByMonth = getInvoicesCountByOrgByMonth(invoices); + InvoiceStatistics invoiceStatistics = new InvoiceStatistics(invoicesCountByOrgMap,overDueInvoicesCountByOrg,invoicesCountByOrgMapByMonth); + return invoiceStatistics; + } + + public Map getOverDueInvoicesCountByOrg(List invoices, LocalDate currDate) { + + if(null==currDate) { + currDate = LocalDate.now(); + } + + Map result = new HashMap<>(); + for (Invoice invoice : invoices) { + if( "unpaid".equalsIgnoreCase(invoice.getStatus()) && invoice.getDueDate().isAfter(currDate)){ + int currCount = result.getOrDefault(invoice.getOrganisationId(),0); + result.put(invoice.getOrganisationId(),currCount+1); + } + } + return result; + } + + public Map getInvoicesCountByOrg(List invoices) { + Map result = new HashMap<>(); + for (Invoice invoice : invoices) { + int currCount = result.getOrDefault(invoice.getOrganisationId(),0); + result.put(invoice.getOrganisationId(),currCount+1); + } + return result; } + + + public Map> getInvoicesCountByOrgByMonth(List invoices) { + Map> result = new HashMap<>(); + for (Invoice invoice : invoices) { + if("paid".equalsIgnoreCase(invoice.getStatus())) { + Map countByMonth = result.getOrDefault(invoice.getOrganisationId(),new HashMap<>()); + int invCount = countByMonth.getOrDefault(invoice.getRaisedDate().getMonth().getValue(),0); + countByMonth.put(invoice.getRaisedDate().getMonth().getValue(),invCount+1); + result.put(invoice.getOrganisationId(),countByMonth); + } + + } + return result; + } + + } \ No newline at end of file diff --git a/src/main/java/InvoiceStatistics.java b/src/main/java/InvoiceStatistics.java index f23dbef..39b9890 100644 --- a/src/main/java/InvoiceStatistics.java +++ b/src/main/java/InvoiceStatistics.java @@ -1,4 +1,26 @@ +import java.util.Map; + public class InvoiceStatistics { - public InvoiceStatistics() { + + private final Map invoicesCountByOrgMap; + private final Map overDueInvoicesCountByOrg; + private final Map> invoicesCountByOrgMapByMonth; + + public InvoiceStatistics(Map invoicesCountByOrgMap, Map overDueInvoicesCountByOrg, Map> invoicesCountByOrgMapByMonth) { + this.invoicesCountByOrgMap = invoicesCountByOrgMap; + this.overDueInvoicesCountByOrg = overDueInvoicesCountByOrg; + this.invoicesCountByOrgMapByMonth = invoicesCountByOrgMapByMonth; } -} \ No newline at end of file + + public Map getInvoicesCountByOrgMap() { + return invoicesCountByOrgMap; + } + + public Map getOverDueInvoicesCountByOrg() { + return overDueInvoicesCountByOrg; + } + + public Map> getInvoicesCountByOrgMapByMonth() { + return invoicesCountByOrgMapByMonth; + } +} \ No newline at end of file diff --git a/src/test/java/ConsumerTest.java b/src/test/java/ConsumerTest.java index 57b45cf..4f41056 100644 --- a/src/test/java/ConsumerTest.java +++ b/src/test/java/ConsumerTest.java @@ -4,21 +4,26 @@ import static org.junit.jupiter.api.Assertions.*; import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; import java.util.List; import java.util.ArrayList; import java.io.IOException; +import java.util.Map; class ConsumerTest { private Consumer consumer; - private CsvInvoiceReader csvReader; private List testInvoices; + private InvoiceStatistics stats; @BeforeEach void setUp() throws IOException { - consumer = new Consumer(); - csvReader = new CsvInvoiceReader(); + LocalDate testCurrDate = LocalDate.parse("2019-10-14", DateTimeFormatter.ofPattern("yyyy-MM-dd")); + consumer = new Consumer(testCurrDate); + CsvInvoiceReader csvReader = new CsvInvoiceReader(); testInvoices = csvReader.readInvoices("invoices.csv"); + stats = consumer.consumeInvoices(testInvoices); } @Test @@ -31,4 +36,60 @@ void testEmptyList() { // For now, it will fail because the method returns null assertNotNull(result); } + + + @Test + @DisplayName("test record count match") + void testRecordCount(){ + assertEquals(11,testInvoices.size()); + } + + @Test + @DisplayName("Total number of invoices per organisation should match") + void testInvoicesPerOrgCount(){ + assertNotNull(stats); + Map invoiceCountByOrg = stats.getInvoicesCountByOrgMap(); + + Map expectedResultMap=new HashMap<>(); + expectedResultMap.put(1000,5); + expectedResultMap.put(2000,6); + assertEquals(expectedResultMap,invoiceCountByOrg); + } + + @Test + @DisplayName("Total number of Over due invoices per organisation should match") + void testOverDueInvoicesCountByOrg(){ + + assertNotNull(stats); + Map overDueInvoiceCountByOrg = stats.getOverDueInvoicesCountByOrg(); + + Map expectedResultMap=new HashMap<>(); + expectedResultMap.put(1000,2); + expectedResultMap.put(2000,2); + assertEquals(expectedResultMap,overDueInvoiceCountByOrg); + } + + @Test + @DisplayName("Total number of invoices per organisation per month should match") + void testInvoicesCountByOrgMapByMonth(){ + + assertNotNull(stats); + Map> invoiceCountByOrgByMonth = stats.getInvoicesCountByOrgMapByMonth(); + + Map> expectedResultMap=new HashMap<>(); + HashMap account1MonthlyMap = new HashMap<>();; + account1MonthlyMap.put(10,3); + + expectedResultMap.put(1000, account1MonthlyMap); + + HashMap account2MonthlyMap = new HashMap<>();; + account2MonthlyMap.put(9,4); + + expectedResultMap.put(2000,account2MonthlyMap); + + + assertEquals(expectedResultMap,invoiceCountByOrgByMonth); + } + + } \ No newline at end of file