From b9ffe96f553ee29f48d2cbb9f517d5685fa39b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Fr=C4=85cz?= Date: Sat, 11 Feb 2017 23:58:33 +0100 Subject: [PATCH 1/7] Working all Invoice and Product tests --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 35 +++++++++++++++---- .../edu/agh/mwo/invoice/product/Product.java | 16 ++++++--- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 56fe02359..8599ebb76 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -1,30 +1,51 @@ package pl.edu.agh.mwo.invoice; import java.math.BigDecimal; -import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import pl.edu.agh.mwo.invoice.product.Product; public class Invoice { - private Collection products; + private Map products = new HashMap(); public void addProduct(Product product) { - // TODO: implement + this.products.put(product, 1); } public void addProduct(Product product, Integer quantity) { - // TODO: implement + if (quantity <= 0) { + throw new IllegalArgumentException(); + } + this.products.put(product, quantity); } public BigDecimal getSubtotal() { - return null; + return getTotal().subtract(getTax()); } public BigDecimal getTax() { - return null; + BigDecimal totalTax = new BigDecimal(0); + Iterator> it = products.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = it.next(); + BigDecimal productTax = pair.getKey().getTaxOnly(); + BigDecimal quantity = new BigDecimal(pair.getValue()); + totalTax = totalTax.add(productTax.multiply(quantity)); + } + return totalTax; } public BigDecimal getTotal() { - return null; + BigDecimal total = new BigDecimal(0); + Iterator> it = products.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = it.next(); + BigDecimal productPriceWithTax = pair.getKey().getPriceWithTax(); + BigDecimal quantity = new BigDecimal(pair.getValue()); + total = total.add(productPriceWithTax.multiply(quantity)); + } + return total; } } diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java index 318de9ac9..b73269d75 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java @@ -10,24 +10,32 @@ public abstract class Product { private final BigDecimal taxPercent; protected Product(String name, BigDecimal price, BigDecimal tax) { + if (name == null || name.equals("") || price == null || tax == null || tax.compareTo(new BigDecimal(0)) < 0 + || price.compareTo(new BigDecimal(0)) < 0) { + throw new IllegalArgumentException(); + } this.name = name; this.price = price; this.taxPercent = tax; } public String getName() { - return null; + return name; } public BigDecimal getPrice() { - return null; + return price; } public BigDecimal getTaxPercent() { - return null; + return taxPercent; } public BigDecimal getPriceWithTax() { - return null; + return price.add(getTaxOnly()); + } + + public BigDecimal getTaxOnly() { + return price.multiply(taxPercent); } } From fbb07dceb4407153fa266d69c832f48798da7a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Fr=C4=85cz?= Date: Fri, 24 Feb 2017 23:32:19 +0100 Subject: [PATCH 2/7] Simplify invoice implementation --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 43 ++++++++----------- .../edu/agh/mwo/invoice/product/Product.java | 6 +-- .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 22 +++++----- 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 8599ebb76..72f4048d5 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -2,7 +2,6 @@ import java.math.BigDecimal; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import pl.edu.agh.mwo.invoice.product.Product; @@ -11,41 +10,35 @@ public class Invoice { private Map products = new HashMap(); public void addProduct(Product product) { - this.products.put(product, 1); + addProduct(product, 1); } public void addProduct(Product product, Integer quantity) { - if (quantity <= 0) { + if (product == null || quantity <= 0) { throw new IllegalArgumentException(); } - this.products.put(product, quantity); + products.put(product, quantity); } - public BigDecimal getSubtotal() { - return getTotal().subtract(getTax()); + public BigDecimal getNetTotal() { + BigDecimal totalNet = BigDecimal.ZERO; + for (Product product : products.keySet()) { + BigDecimal quantity = new BigDecimal(products.get(product)); + totalNet = totalNet.add(product.getPrice().multiply(quantity)); + } + return totalNet; } - public BigDecimal getTax() { - BigDecimal totalTax = new BigDecimal(0); - Iterator> it = products.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry pair = it.next(); - BigDecimal productTax = pair.getKey().getTaxOnly(); - BigDecimal quantity = new BigDecimal(pair.getValue()); - totalTax = totalTax.add(productTax.multiply(quantity)); - } - return totalTax; + public BigDecimal getTaxTotal() { + return getGrossTotal().subtract(getNetTotal()); } - public BigDecimal getTotal() { - BigDecimal total = new BigDecimal(0); - Iterator> it = products.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry pair = it.next(); - BigDecimal productPriceWithTax = pair.getKey().getPriceWithTax(); - BigDecimal quantity = new BigDecimal(pair.getValue()); - total = total.add(productPriceWithTax.multiply(quantity)); + public BigDecimal getGrossTotal() { + BigDecimal totalGross = BigDecimal.ZERO; + for (Product product : products.keySet()) { + BigDecimal quantity = new BigDecimal(products.get(product)); + totalGross = totalGross.add(product.getPriceWithTax().multiply(quantity)); } - return total; + return totalGross; } } diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java index b73269d75..cd0f86a48 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java @@ -32,10 +32,6 @@ public BigDecimal getTaxPercent() { } public BigDecimal getPriceWithTax() { - return price.add(getTaxOnly()); - } - - public BigDecimal getTaxOnly() { - return price.multiply(taxPercent); + return price.multiply(taxPercent).add(price); } } diff --git a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java index 7f4b6f795..50513171c 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -23,17 +23,17 @@ public void createEmptyInvoiceForTheTest() { @Test public void testEmptyInvoiceHasEmptySubtotal() { - Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getSubtotal())); + Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getNetTotal())); } @Test public void testEmptyInvoiceHasEmptyTaxAmount() { - Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getTax())); + Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getTaxTotal())); } @Test public void testEmptyInvoiceHasEmptyTotal() { - Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getTotal())); + Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getGrossTotal())); } @Test @@ -42,21 +42,21 @@ public void testInvoiceSubtotalWithTwoDifferentProducts() { Product apples = new TaxFreeProduct("Owoce", new BigDecimal("10")); invoice.addProduct(onions); invoice.addProduct(apples); - Assert.assertThat(new BigDecimal("20"), Matchers.comparesEqualTo(invoice.getSubtotal())); + Assert.assertThat(new BigDecimal("20"), Matchers.comparesEqualTo(invoice.getNetTotal())); } @Test public void testInvoiceSubtotalWithManySameProducts() { Product onions = new TaxFreeProduct("Warzywa", BigDecimal.valueOf(10)); invoice.addProduct(onions, 100); - Assert.assertThat(new BigDecimal("1000"), Matchers.comparesEqualTo(invoice.getSubtotal())); + Assert.assertThat(new BigDecimal("1000"), Matchers.comparesEqualTo(invoice.getNetTotal())); } @Test public void testInvoiceHasTheSameSubtotalAndTotalIfTaxIsZero() { Product taxFreeProduct = new TaxFreeProduct("Warzywa", new BigDecimal("199.99")); invoice.addProduct(taxFreeProduct); - Assert.assertThat(invoice.getTotal(), Matchers.comparesEqualTo(invoice.getSubtotal())); + Assert.assertThat(invoice.getNetTotal(), Matchers.comparesEqualTo(invoice.getGrossTotal())); } @Test @@ -64,7 +64,7 @@ public void testInvoiceHasProperSubtotalForManyProducts() { invoice.addProduct(new TaxFreeProduct("Owoce", new BigDecimal("200"))); invoice.addProduct(new DairyProduct("Maslanka", new BigDecimal("100"))); invoice.addProduct(new OtherProduct("Wino", new BigDecimal("10"))); - Assert.assertThat(new BigDecimal("310"), Matchers.comparesEqualTo(invoice.getSubtotal())); + Assert.assertThat(new BigDecimal("310"), Matchers.comparesEqualTo(invoice.getNetTotal())); } @Test @@ -75,7 +75,7 @@ public void testInvoiceHasProperTaxValueForManyProduct() { invoice.addProduct(new DairyProduct("Kefir", new BigDecimal("100"))); // tax: 2.30 invoice.addProduct(new OtherProduct("Piwko", new BigDecimal("10"))); - Assert.assertThat(new BigDecimal("10.30"), Matchers.comparesEqualTo(invoice.getTax())); + Assert.assertThat(new BigDecimal("10.30"), Matchers.comparesEqualTo(invoice.getTaxTotal())); } @Test @@ -86,7 +86,7 @@ public void testInvoiceHasProperTotalValueForManyProduct() { invoice.addProduct(new DairyProduct("Maslo", new BigDecimal("100"))); // price with tax: 12.30 invoice.addProduct(new OtherProduct("Chipsy", new BigDecimal("10"))); - Assert.assertThat(new BigDecimal("320.30"), Matchers.comparesEqualTo(invoice.getTotal())); + Assert.assertThat(new BigDecimal("320.30"), Matchers.comparesEqualTo(invoice.getGrossTotal())); } @Test @@ -97,7 +97,7 @@ public void testInvoiceHasPropoerSubtotalWithQuantityMoreThanOne() { invoice.addProduct(new DairyProduct("Kozi Serek", new BigDecimal("10")), 3); // 1000x pinezka - price: 10 invoice.addProduct(new OtherProduct("Pinezka", new BigDecimal("0.01")), 1000); - Assert.assertThat(new BigDecimal("50"), Matchers.comparesEqualTo(invoice.getSubtotal())); + Assert.assertThat(new BigDecimal("50"), Matchers.comparesEqualTo(invoice.getNetTotal())); } @Test @@ -108,7 +108,7 @@ public void testInvoiceHasPropoerTotalWithQuantityMoreThanOne() { invoice.addProduct(new DairyProduct("Chedar", new BigDecimal("10")), 3); // 1000x pinezka - price with tax: 12.30 invoice.addProduct(new OtherProduct("Pinezka", new BigDecimal("0.01")), 1000); - Assert.assertThat(new BigDecimal("54.70"), Matchers.comparesEqualTo(invoice.getTotal())); + Assert.assertThat(new BigDecimal("54.70"), Matchers.comparesEqualTo(invoice.getGrossTotal())); } @Test(expected = IllegalArgumentException.class) From c0197fd952e72a1b77469e59d3222174584b90a4 Mon Sep 17 00:00:00 2001 From: MajowyLas Date: Sat, 9 May 2026 14:42:31 +0200 Subject: [PATCH 3/7] Add CI workflow for Java Invoice project --- .github/workflows/github-actions.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/github-actions.yml diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml new file mode 100644 index 000000000..560118517 --- /dev/null +++ b/.github/workflows/github-actions.yml @@ -0,0 +1,15 @@ +name: CI for Java Invoice +on: [push] +jobs: + test: + name: Unit tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'adopt' + - name: Test + run: mvn test From c54986887e35d66d6f2c00b02ed6b5233d7bdd52 Mon Sep 17 00:00:00 2001 From: Anna Maywald Date: Sat, 9 May 2026 16:25:25 +0200 Subject: [PATCH 4/7] added checklist.xmls, added checkist to github actions, amended Product.java --- .github/workflows/github-actions.yml | 3 + checkstyle.xml | 298 ++++++++++++++++++ pom.xml | 21 ++ .../edu/agh/mwo/invoice/product/Product.java | 8 +- 4 files changed, 328 insertions(+), 2 deletions(-) create mode 100644 checkstyle.xml diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 560118517..b477d81d3 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -13,3 +13,6 @@ jobs: distribution: 'adopt' - name: Test run: mvn test + - name: Checkstyle + run: mvn checkstyle:check + diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 000000000..fbcd05132 --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2d40c3e8a..03c23ac83 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,27 @@ 17 + + + org.apache.maven.plugins + + maven-checkstyle-plugin + + 3.6.0 + + + + checkstyle.xml + + true + + true + + + + + + diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java index cd0f86a48..48168bd76 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java @@ -10,9 +10,13 @@ public abstract class Product { private final BigDecimal taxPercent; protected Product(String name, BigDecimal price, BigDecimal tax) { - if (name == null || name.equals("") || price == null || tax == null || tax.compareTo(new BigDecimal(0)) < 0 + if (name == null + || name.equals("") + || price == null + || tax == null + || tax.compareTo(new BigDecimal(0)) < 0 || price.compareTo(new BigDecimal(0)) < 0) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("Invalid product data"); } this.name = name; this.price = price; From 5e6d0b4284122cd7a7491cd6f0f1a77d3470f3eb Mon Sep 17 00:00:00 2001 From: Anna Maywald Date: Sat, 9 May 2026 16:54:41 +0200 Subject: [PATCH 5/7] Add invoice number with auto-increment counter --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 23 +++++++++++++++++++ .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 23 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 72f4048d5..88c146a23 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -7,8 +7,22 @@ import pl.edu.agh.mwo.invoice.product.Product; public class Invoice { + + private static int nextInvoiceNumber = 1; + private final int invoiceNumber; + private Map products = new HashMap(); + + public Invoice() { + this.invoiceNumber = nextInvoiceNumber; + nextInvoiceNumber++; + } + + public static int getInvoiceNumber() { + return nextInvoiceNumber; + } + public void addProduct(Product product) { addProduct(product, 1); } @@ -41,4 +55,13 @@ public BigDecimal getGrossTotal() { } return totalGross; } + + public int generateInvoiceNumber() { + int invoiceNumber = 0; + for (Product product : products.keySet()) { + invoiceNumber = invoiceNumber + 1; + products.put(product, invoiceNumber); + } + return invoiceNumber; + } } diff --git a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java index 50513171c..d1f046399 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -125,4 +125,27 @@ public void testInvoiceWithNegativeQuantity() { public void testAddingNullProduct() { invoice.addProduct(null); } + + @Test + public void testInvoiceHasNumberGreaterThan0 () { + Invoice invoice = new Invoice(); + int number = invoice.getInvoiceNumber(); + Assert.assertThat(number, Matchers.greaterThan(0)); + } + + @Test + public void testTwoInvoicesHaveDifferentNumber() { + int number1 = new Invoice().getInvoiceNumber(); + int number2 = new Invoice().getInvoiceNumber(); + Assert.assertNotEquals(number1, number2); + } + + @Test + public void testInvoiceNumberDoesNotChange() { + Invoice invoice = new Invoice(); + int firstCheck = invoice.getInvoiceNumber(); + int secondCheck = invoice.getInvoiceNumber(); + Assert.assertEquals(firstCheck, secondCheck); + + } } From a1e17b0e017a7f4952ea81d4b16194fa7cae1f24 Mon Sep 17 00:00:00 2001 From: Anna Maywald Date: Sat, 9 May 2026 17:20:11 +0200 Subject: [PATCH 6/7] Add printInvoice method with header, products, position count --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 31 +++++++++++----- .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 36 +++++++++++++++++++ 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 88c146a23..097c8478c 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -19,8 +19,8 @@ public Invoice() { nextInvoiceNumber++; } - public static int getInvoiceNumber() { - return nextInvoiceNumber; + public int getInvoiceNumber() { + return invoiceNumber; } public void addProduct(Product product) { @@ -56,12 +56,27 @@ public BigDecimal getGrossTotal() { return totalGross; } - public int generateInvoiceNumber() { - int invoiceNumber = 0; + + public String printInvoice() { + if (products.isEmpty()) { + throw new IllegalStateException(); + } + + StringBuilder builder = new StringBuilder(); + builder.append("Faktura nr ").append(invoiceNumber).append("\n"); + for (Product product : products.keySet()) { - invoiceNumber = invoiceNumber + 1; - products.put(product, invoiceNumber); + Integer quantity = products.get(product); + builder.append(product.getName()) + .append("\t") + .append(quantity) + .append("\t") + .append(product.getPriceWithTax()) + .append("\n"); } - return invoiceNumber; + + builder.append("Liczba pozycji: ").append(products.size()); + return builder.toString(); } -} + +} \ No newline at end of file diff --git a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java index d1f046399..abe965455 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -148,4 +148,40 @@ public void testInvoiceNumberDoesNotChange() { Assert.assertEquals(firstCheck, secondCheck); } + @Test + public void testPrintInvoiceContainsInvoiceNumber() { + Invoice invoice = new Invoice(); + invoice.addProduct(new OtherProduct("Chleb", new BigDecimal("3.00"))); + String result = invoice.printInvoice(); + Assert.assertTrue(result.contains("Faktura nr " + invoice.getInvoiceNumber())); + } + + + @Test + public void testPrintInvoiceContainsProductNames() { + Invoice invoice = new Invoice(); + invoice.addProduct(new OtherProduct("Chleb", new BigDecimal("3.00")), 2); + invoice.addProduct(new DairyProduct("Mleko", new BigDecimal("4.00")), 1); + String result = invoice.printInvoice(); + Assert.assertTrue(result.contains("Chleb")); + Assert.assertTrue(result.contains("Mleko")); + } + + + @Test + public void testPrintInvoiceEndsWithPositionCount() { + Invoice invoice = new Invoice(); + invoice.addProduct(new OtherProduct("A", new BigDecimal("1.00"))); + invoice.addProduct(new OtherProduct("B", new BigDecimal("2.00"))); + invoice.addProduct(new DairyProduct("C", new BigDecimal("3.00"))); + String result = invoice.printInvoice(); + Assert.assertTrue(result.contains("Liczba pozycji: 3")); + + } + + @Test(expected = IllegalStateException.class) + public void testPrintInvoiceForEmptyInvoiceThrowsException() { + Invoice invoice = new Invoice(); + invoice.printInvoice(); + } } From 8ea22749cf9196dce2ce2e36a2c04b4bc3d6fe23 Mon Sep 17 00:00:00 2001 From: Anna Maywald Date: Sat, 9 May 2026 17:27:23 +0200 Subject: [PATCH 7/7] Merge duplicate products by name and price --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 7 ++++- .../edu/agh/mwo/invoice/product/Product.java | 17 ++++++++++++ .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 27 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java index 097c8478c..87ab080f0 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -30,8 +30,13 @@ public void addProduct(Product product) { public void addProduct(Product product, Integer quantity) { if (product == null || quantity <= 0) { throw new IllegalArgumentException(); + + } + if (products.containsKey(product)) { + products.put(product, products.get(product) + quantity); + } else { + products.put(product, quantity); } - products.put(product, quantity); } public BigDecimal getNetTotal() { diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java index 48168bd76..5951f7d3f 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/Product.java @@ -38,4 +38,21 @@ public BigDecimal getTaxPercent() { public BigDecimal getPriceWithTax() { return price.multiply(taxPercent).add(price); } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + Product other = (Product) obj; + return name.equals(other.name) && price.compareTo(other.price) == 0; + } + + @Override + public int hashCode() { + return java.util.Objects.hash(name, price); + } } diff --git a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java index abe965455..7c350935c 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -184,4 +184,31 @@ public void testPrintInvoiceForEmptyInvoiceThrowsException() { Invoice invoice = new Invoice(); invoice.printInvoice(); } + + @Test + public void testInvoiceMergesDuplicateProductsByName() { + Invoice invoice = new Invoice(); + invoice.addProduct(new OtherProduct("Chleb", new BigDecimal("3.00")), 2); + invoice.addProduct(new OtherProduct("Chleb", new BigDecimal("3.00")), 3); + Assert.assertEquals(new BigDecimal("18.45"), + invoice.getGrossTotal().setScale(2, java.math.RoundingMode.HALF_UP)); + } + + @Test + public void testInvoiceWithDuplicateProductHasOnlyOnePosition() { + Invoice invoice = new Invoice(); + invoice.addProduct(new OtherProduct("Chleb", new BigDecimal("3.00")), 2); + invoice.addProduct(new OtherProduct("Chleb", new BigDecimal("3.00")), 3); + String result = invoice.printInvoice(); + Assert.assertTrue(result.contains("Liczba pozycji: 1")); + } + + @Test + public void testInvoiceTreatsDifferentPricesAsSeparateProducts() { + Invoice invoice = new Invoice(); + invoice.addProduct(new OtherProduct("Chleb", new BigDecimal("3.00")), 2); + invoice.addProduct(new OtherProduct("Chleb", new BigDecimal("2.50")), 3); + String result = invoice.printInvoice(); + Assert.assertTrue(result.contains("Liczba pozycji: 2")); + } }