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/9] 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/9] 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 bb14e3621b1308a923c4c96738aad81e67082cc3 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Sun, 14 Jun 2026 20:16:45 +0200 Subject: [PATCH 3/9] 1 --- .github/workflows/github-actions.yml | 15 +++++++ .github/workflows/qodana_code_quality.yml | 40 ++++++++++++++++++ qodana.yaml | 49 +++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 .github/workflows/github-actions.yml create mode 100644 .github/workflows/qodana_code_quality.yml create mode 100644 qodana.yaml diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml new file mode 100644 index 000000000..8fb587348 --- /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 \ No newline at end of file diff --git a/.github/workflows/qodana_code_quality.yml b/.github/workflows/qodana_code_quality.yml new file mode 100644 index 000000000..d1f49a71a --- /dev/null +++ b/.github/workflows/qodana_code_quality.yml @@ -0,0 +1,40 @@ +#-------------------------------------------------------------------------------# +# Discover all capabilities of Qodana in our documentation # +# https://www.jetbrains.com/help/qodana/about-qodana.html # +#-------------------------------------------------------------------------------# + +name: Qodana +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + - tdd + +jobs: + qodana: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + checks: write + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + - name: 'Qodana Scan' + uses: JetBrains/qodana-action@v2026.1 + env: + QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} + with: + # When pr-mode is set to true, Qodana analyzes only the files that have been changed + pr-mode: false + use-caches: true + post-pr-comment: true + use-annotations: true + # Upload Qodana results (SARIF, other artifacts, logs) as an artifact to the job + upload-result: false + # quick-fixes available in Ultimate and Ultimate Plus plans + push-fixes: 'none' \ No newline at end of file diff --git a/qodana.yaml b/qodana.yaml new file mode 100644 index 000000000..fcaa9673e --- /dev/null +++ b/qodana.yaml @@ -0,0 +1,49 @@ +#-------------------------------------------------------------------------------# +# Qodana analysis is configured by qodana.yaml file # +# https://www.jetbrains.com/help/qodana/qodana-yaml.html # +#-------------------------------------------------------------------------------# + +################################################################################# +# WARNING: Do not store sensitive information in this file, # +# as its contents will be included in the Qodana report. # +################################################################################# +version: "1.0" + +#Specify inspection profile for code analysis +profile: + name: qodana.starter + +#Enable inspections +#include: +# - name: + +#Disable inspections +#exclude: +# - name: +# paths: +# - + +projectJDK: "26" #(Applied in CI/CD pipeline) + +#Execute shell command before Qodana execution (Applied in CI/CD pipeline) +#bootstrap: sh ./prepare-qodana.sh + +#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) +#plugins: +# - id: #(plugin id can be found at https://plugins.jetbrains.com) + +# Quality gate. Will fail the CI/CD pipeline if any condition is not met +# severityThresholds - configures maximum thresholds for different problem severities +# testCoverageThresholds - configures minimum code coverage on a whole project and newly added code +# Code Coverage is available in Ultimate and Ultimate Plus plans +#failureConditions: +# severityThresholds: +# any: 15 +# critical: 5 +# testCoverageThresholds: +# fresh: 70 +# total: 50 + +#Qodana supports other languages, for example, Python, JavaScript, TypeScript, Go, C#, PHP +#For all supported languages see https://www.jetbrains.com/help/qodana/linters.html +linter: jetbrains/qodana-jvm-community:2026.1 From 51a62b4b19b52d6cc226c63d2ec0e04b66cc4a25 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Wed, 17 Jun 2026 14:46:21 +0200 Subject: [PATCH 4/9] 2 --- config/checkstyle.xml | 295 ++++++++++++++++++ pom.xml | 28 +- .../pl/edu/agh/mwo/invoice/package-info.java | 4 + .../agh/mwo/invoice/product/package-info.java | 4 + 4 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 config/checkstyle.xml create mode 100644 src/main/java/pl/edu/agh/mwo/invoice/package-info.java create mode 100644 src/main/java/pl/edu/agh/mwo/invoice/product/package-info.java diff --git a/config/checkstyle.xml b/config/checkstyle.xml new file mode 100644 index 000000000..24335bb6c --- /dev/null +++ b/config/checkstyle.xml @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2d40c3e8a..17a596e95 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,26 @@ src/main/java + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.2.1 + + config/checkstyle.xml + true + true + false + + + + validate + validate + + check + + + + org.apache.maven.plugins maven-compiler-plugin @@ -40,5 +60,11 @@ hamcrest-all 1.3 + + org.hamcrest + hamcrest + 2.2 + test + - + \ No newline at end of file diff --git a/src/main/java/pl/edu/agh/mwo/invoice/package-info.java b/src/main/java/pl/edu/agh/mwo/invoice/package-info.java new file mode 100644 index 000000000..05fbd5def --- /dev/null +++ b/src/main/java/pl/edu/agh/mwo/invoice/package-info.java @@ -0,0 +1,4 @@ +/** + * Provides classes for creating and managing invoices. + */ +package pl.edu.agh.mwo.invoice; \ No newline at end of file diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/package-info.java b/src/main/java/pl/edu/agh/mwo/invoice/product/package-info.java new file mode 100644 index 000000000..b08eb4784 --- /dev/null +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/package-info.java @@ -0,0 +1,4 @@ +/** + * Provides classes representing different types of products. + */ +package pl.edu.agh.mwo.invoice.product; \ No newline at end of file From 378ea5ad89325700837447fb750b3f508237a9cd Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Wed, 17 Jun 2026 14:49:49 +0200 Subject: [PATCH 5/9] 2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 17a596e95..2027618f0 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ junit junit - 4.12 + 4.13.2 test From b3eab2ff2c35c8a88ead48d1cf9f3cf010953e75 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Wed, 17 Jun 2026 18:56:54 +0200 Subject: [PATCH 6/9] Numerowanie faktur --- effective-pom.xml | 273 ++++++++++++++++++ pom.xml | 20 +- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 12 +- .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 12 + 4 files changed, 307 insertions(+), 10 deletions(-) create mode 100644 effective-pom.xml diff --git a/effective-pom.xml b/effective-pom.xml new file mode 100644 index 000000000..21a89f947 --- /dev/null +++ b/effective-pom.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + 4.0.0 + pl.edu.agh.mwo.hellomaven + hello-maven + 1.0.0-SNAPSHOT + + 17 + 17 + 3.2.0 + UTF-8 + + + + org.junit.jupiter + junit-jupiter-api + 6.0.3 + test + + + + + + false + + central + Central Repository + https://repo.maven.apache.org/maven2 + + + + + + false + + central + Central Repository + https://repo.maven.apache.org/maven2 + + + + /Users/olenka/Desktop/java-invoice-tdd/src/main/java + /Users/olenka/Desktop/java-invoice-tdd/src/main/scripts + /Users/olenka/Desktop/java-invoice-tdd/src/test/java + /Users/olenka/Desktop/java-invoice-tdd/target/classes + /Users/olenka/Desktop/java-invoice-tdd/target/test-classes + + + /Users/olenka/Desktop/java-invoice-tdd/src/main/resources + + + + + /Users/olenka/Desktop/java-invoice-tdd/src/test/resources + + + /Users/olenka/Desktop/java-invoice-tdd/target + hello-maven-1.0.0-SNAPSHOT + + + + maven-antrun-plugin + 3.1.0 + + + maven-assembly-plugin + 3.7.1 + + + maven-dependency-plugin + 3.7.0 + + + maven-release-plugin + 3.0.1 + + + + + + maven-jar-plugin + 3.2.0 + + + default-jar + package + + jar + + + + + true + pl.edu.agh.mwo.hellomaven.App + + + + + + + + + true + pl.edu.agh.mwo.hellomaven.App + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + pl.edu.agh.mwo.hellomaven.App + + + + maven-clean-plugin + 3.2.0 + + + default-clean + clean + + clean + + + + + + maven-resources-plugin + 3.4.0 + + + default-testResources + process-test-resources + + testResources + + + + default-resources + process-resources + + resources + + + + + + maven-compiler-plugin + 3.15.0 + + + default-compile + compile + + compile + + + + default-testCompile + test-compile + + testCompile + + + + + + maven-surefire-plugin + 3.5.4 + + + default-test + test + + test + + + + + + maven-install-plugin + 3.1.4 + + + default-install + install + + install + + + + + + maven-deploy-plugin + 3.1.4 + + + default-deploy + deploy + + deploy + + + + + + maven-site-plugin + 3.12.1 + + + default-site + site + + site + + + /Users/olenka/Desktop/java-invoice-tdd/target/site + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + + + default-deploy + site-deploy + + deploy + + + /Users/olenka/Desktop/java-invoice-tdd/target/site + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + + + + /Users/olenka/Desktop/java-invoice-tdd/target/site + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + + + + + /Users/olenka/Desktop/java-invoice-tdd/target/site + + diff --git a/pom.xml b/pom.xml index 2027618f0..411c4d9c9 100644 --- a/pom.xml +++ b/pom.xml @@ -20,13 +20,15 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.2.1 + 3.3.1 - config/checkstyle.xml + + ${project.basedir}/config/checkstyle.xml + true - true - false - + true + false + validate @@ -40,10 +42,10 @@ org.apache.maven.plugins maven-compiler-plugin - - 17 - 17 - + 3.13.0 + 17 + 17 + 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..c756ee549 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -7,7 +7,17 @@ import pl.edu.agh.mwo.invoice.product.Product; public class Invoice { - private Map products = new HashMap(); + private static int nextNumber = 1; + private final int number; + private final Map products = new HashMap(); + + public Invoice() { + number = nextNumber++; + } + + public int getNumber() { + return number; + } public void addProduct(Product product) { addProduct(product, 1); 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..13ac02a96 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -16,6 +16,7 @@ public class InvoiceTest { private Invoice invoice; + @Before public void createEmptyInvoiceForTheTest() { invoice = new Invoice(); @@ -125,4 +126,15 @@ public void testInvoiceWithNegativeQuantity() { public void testAddingNullProduct() { invoice.addProduct(null); } + + @Test + public void testInvoiceNumbersAreAssignedAutomatically() { + Invoice firstInvoice = new Invoice(); + Invoice secondInvoice = new Invoice(); + + Assert.assertEquals( + firstInvoice.getNumber() + 1, + secondInvoice.getNumber() + ); + } } From 501b6ab692a36ef679d47991c052b862b2f0b752 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Wed, 17 Jun 2026 19:35:11 +0200 Subject: [PATCH 7/9] Drukowanie faktury --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 30 +++++++++++++++++-- .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 23 +++++++++++++- 2 files changed, 50 insertions(+), 3 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 c756ee549..26011d98e 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -1,7 +1,7 @@ package pl.edu.agh.mwo.invoice; import java.math.BigDecimal; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import pl.edu.agh.mwo.invoice.product.Product; @@ -9,7 +9,7 @@ public class Invoice { private static int nextNumber = 1; private final int number; - private final Map products = new HashMap(); + private final Map products = new LinkedHashMap(); public Invoice() { number = nextNumber++; @@ -19,6 +19,32 @@ public int getNumber() { return number; } + public String getPrintout() { + StringBuilder printout = new StringBuilder(); + String separator = System.lineSeparator(); + + printout.append("Numer faktury: ") + .append(number) + .append(separator); + + for (Map.Entry entry : products.entrySet()) { + Product product = entry.getKey(); + Integer quantity = entry.getValue(); + + printout.append(product.getName()) + .append(", ") + .append(quantity) + .append(" szt., ") + .append(product.getPrice()) + .append(separator); + } + + printout.append("Liczba pozycji: ") + .append(products.size()); + + return printout.toString(); + } + public void addProduct(Product product) { addProduct(product, 1); } 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 13ac02a96..8607017c9 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -137,4 +137,25 @@ public void testInvoiceNumbersAreAssignedAutomatically() { secondInvoice.getNumber() ); } -} + + @Test + public void testInvoicePrintoutContainsProductsAndInvoiceNumber() { + invoice.addProduct( + new TaxFreeProduct("Kubek", new BigDecimal("5")), 2); + invoice.addProduct( + new DairyProduct("Ser", new BigDecimal("10")), 3); + + String separator = System.lineSeparator(); + + String expected = "Numer faktury: " + + invoice.getNumber() + + separator + + "Kubek, 2 szt., 5" + + separator + + "Ser, 3 szt., 10" + + separator + + "Liczba pozycji: 2"; + + Assert.assertEquals(expected, invoice.getPrintout()); + } + } From b3b65a5529278d3cff0773855aafd5be53612e1d Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Wed, 17 Jun 2026 21:31:03 +0200 Subject: [PATCH 8/9] =?UTF-8?q?Duplikaty=20produkt=C3=B3w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 9 ++++++- .../edu/agh/mwo/invoice/product/Product.java | 25 +++++++++++++++++++ .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 23 +++++++++++++++++ 3 files changed, 56 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 26011d98e..9df7f3e97 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -53,7 +53,14 @@ public void addProduct(Product product, Integer quantity) { if (product == null || quantity <= 0) { throw new IllegalArgumentException(); } - products.put(product, quantity); + + Integer currentQuantity = products.get(product); + + if (currentQuantity == null) { + products.put(product, quantity); + } else { + products.put(product, currentQuantity + 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 cd0f86a48..6ceba79d1 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 @@ -1,6 +1,7 @@ package pl.edu.agh.mwo.invoice.product; import java.math.BigDecimal; +import java.util.Objects; public abstract class Product { private final String name; @@ -34,4 +35,28 @@ public BigDecimal getTaxPercent() { public BigDecimal getPriceWithTax() { return price.multiply(taxPercent).add(price); } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + + if (object == null || getClass() != object.getClass()) { + return false; + } + + Product product = (Product) object; + + return Objects.equals(getName(), product.getName()) + && getPrice().compareTo(product.getPrice()) == 0; + } + + @Override + public int hashCode() { + return Objects.hash( + getClass(), + getName(), + getPrice().stripTrailingZeros()); + } } 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 8607017c9..1b68b87f0 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -158,4 +158,27 @@ public void testInvoicePrintoutContainsProductsAndInvoiceNumber() { Assert.assertEquals(expected, invoice.getPrintout()); } + + @Test + public void testAddingEquivalentProductsIncreasesQuantity() { + Product firstMug = new TaxFreeProduct( + "Kubek", new BigDecimal("5")); + + Product secondMug = new TaxFreeProduct( + "Kubek", new BigDecimal("5.00")); + + invoice.addProduct(firstMug, 2); + invoice.addProduct(secondMug, 3); + + String separator = System.lineSeparator(); + + String expected = "Numer faktury: " + + invoice.getNumber() + + separator + + "Kubek, 5 szt., 5" + + separator + + "Liczba pozycji: 1"; + + Assert.assertEquals(expected, invoice.getPrintout()); + } } From cb0bb2a89023da04fd8a92b59dfc7813c680b0dd Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Wed, 17 Jun 2026 21:49:02 +0200 Subject: [PATCH 9/9] VAT --- .../agh/mwo/invoice/product/BottleOfWine.java | 18 +++++++++++++++ .../agh/mwo/invoice/product/FuelCanister.java | 18 +++++++++++++++ .../pl/edu/agh/mwo/invoice/InvoiceTest.java | 22 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 src/main/java/pl/edu/agh/mwo/invoice/product/BottleOfWine.java create mode 100644 src/main/java/pl/edu/agh/mwo/invoice/product/FuelCanister.java diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/BottleOfWine.java b/src/main/java/pl/edu/agh/mwo/invoice/product/BottleOfWine.java new file mode 100644 index 000000000..933fd3e05 --- /dev/null +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/BottleOfWine.java @@ -0,0 +1,18 @@ +package pl.edu.agh.mwo.invoice.product; + +import java.math.BigDecimal; + +public class BottleOfWine extends OtherProduct { + + private static final BigDecimal EXCISE_DUTY = + new BigDecimal("5.56"); + + public BottleOfWine(String name, BigDecimal price) { + super(name, price); + } + + @Override + public BigDecimal getPriceWithTax() { + return super.getPriceWithTax().add(EXCISE_DUTY); + } +} \ No newline at end of file diff --git a/src/main/java/pl/edu/agh/mwo/invoice/product/FuelCanister.java b/src/main/java/pl/edu/agh/mwo/invoice/product/FuelCanister.java new file mode 100644 index 000000000..7b24b312b --- /dev/null +++ b/src/main/java/pl/edu/agh/mwo/invoice/product/FuelCanister.java @@ -0,0 +1,18 @@ +package pl.edu.agh.mwo.invoice.product; + +import java.math.BigDecimal; + +public class FuelCanister extends TaxFreeProduct { + + private static final BigDecimal EXCISE_DUTY = + new BigDecimal("5.56"); + + public FuelCanister(String name, BigDecimal price) { + super(name, price); + } + + @Override + public BigDecimal getPriceWithTax() { + return super.getPriceWithTax().add(EXCISE_DUTY); + } +} \ 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 1b68b87f0..f15ad2c48 100644 --- a/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java +++ b/src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java @@ -12,6 +12,8 @@ import pl.edu.agh.mwo.invoice.product.OtherProduct; import pl.edu.agh.mwo.invoice.product.Product; import pl.edu.agh.mwo.invoice.product.TaxFreeProduct; +import pl.edu.agh.mwo.invoice.product.BottleOfWine; +import pl.edu.agh.mwo.invoice.product.FuelCanister; public class InvoiceTest { private Invoice invoice; @@ -181,4 +183,24 @@ public void testAddingEquivalentProductsIncreasesQuantity() { Assert.assertEquals(expected, invoice.getPrintout()); } + + @Test + public void testBottleOfWineIncludesVatAndExciseDuty() { + invoice.addProduct( + new BottleOfWine("Wino", new BigDecimal("10"))); + + Assert.assertThat( + new BigDecimal("7.86"), + Matchers.comparesEqualTo(invoice.getTaxTotal())); + } + + @Test + public void testFuelCanisterIncludesOnlyExciseDuty() { + invoice.addProduct( + new FuelCanister("Paliwo", new BigDecimal("10"))); + + Assert.assertThat( + new BigDecimal("5.56"), + Matchers.comparesEqualTo(invoice.getTaxTotal())); + } }