From 38393a36ce5cf745c61f8cfed4e9fe133ae72a07 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Sun, 15 Feb 2026 21:25:13 +0100 Subject: [PATCH 01/15] =?UTF-8?q?Product:=20implementacja=20getter=C3=B3w?= =?UTF-8?q?=20i=20priceWithTax=20=E2=80=93=204=20testy=20przechodz=C4=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pl/edu/agh/mwo/invoice/product/Product.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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..ed232d636 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 @@ -16,18 +16,18 @@ protected Product(String name, BigDecimal price, BigDecimal 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(price.multiply(taxPercent)); } } From 81c7a81ec609fd5c034dd4e67655e481f812a66e Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Sun, 15 Feb 2026 21:52:26 +0100 Subject: [PATCH 02/15] =?UTF-8?q?Product:=20pe=C5=82na=20implementacja=20z?= =?UTF-8?q?godna=20z=20ProductTest=20=E2=80=93=20wszystkie=20testy=20przec?= =?UTF-8?q?hodz=C4=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/pl/edu/agh/mwo/invoice/product/Product.java | 9 +++++++++ 1 file changed, 9 insertions(+) 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 ed232d636..ee782a311 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,6 +10,15 @@ public abstract class Product { private final BigDecimal taxPercent; protected Product(String name, BigDecimal price, BigDecimal tax) { + + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("Product name cannot be null or blank"); + } + + if (price == null || price.compareTo(BigDecimal.ZERO) < 0) { + throw new IllegalArgumentException("Product price cannot be null or negative"); + } + this.name = name; this.price = price; this.taxPercent = tax; From 36b97c5c286ef72179fd784528293a9dc8cc246e Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 00:47:39 +0100 Subject: [PATCH 03/15] =?UTF-8?q?Invoice:=20obs=C5=82uga=20pustej=20faktur?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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..053c99cf2 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -17,11 +17,11 @@ public void addProduct(Product product, Integer quantity) { } public BigDecimal getSubtotal() { - return null; + return BigDecimal.ZERO; } public BigDecimal getTax() { - return null; + return BigDecimal.ZERO; } public BigDecimal getTotal() { From b59e320e8421f9e48082dc5a6f5bbaedee7b9213 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 00:59:04 +0100 Subject: [PATCH 04/15] =?UTF-8?q?Invoice:=20implementacja=20addProduct()?= =?UTF-8?q?=20i=20subtotal=20dla=20pojedynczych=20produkt=C3=B3w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 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 053c99cf2..85f5b3288 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -1,15 +1,16 @@ package pl.edu.agh.mwo.invoice; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Collection; import pl.edu.agh.mwo.invoice.product.Product; public class Invoice { - private Collection products; + private Collection products = new ArrayList<>(); public void addProduct(Product product) { - // TODO: implement + products.add(product); } public void addProduct(Product product, Integer quantity) { @@ -17,7 +18,13 @@ public void addProduct(Product product, Integer quantity) { } public BigDecimal getSubtotal() { - return BigDecimal.ZERO; + + BigDecimal subtotal = BigDecimal.ZERO; + + for (Product product : products) { + subtotal = subtotal.add(product.getPrice()); + } + return subtotal; } public BigDecimal getTax() { @@ -25,6 +32,6 @@ public BigDecimal getTax() { } public BigDecimal getTotal() { - return null; + return BigDecimal.ZERO; } } From d7ee446fa3c93ffff7ad3312e48de103e0f79615 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 18:32:37 +0100 Subject: [PATCH 05/15] =?UTF-8?q?Invoice:=20obs=C5=82uga=20quantity=20w=20?= =?UTF-8?q?subtotal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/pl/edu/agh/mwo/invoice/Invoice.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 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 85f5b3288..08ec3b4d7 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -3,26 +3,32 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import pl.edu.agh.mwo.invoice.product.Product; public class Invoice { - private Collection products = new ArrayList<>(); + private Map products = new HashMap<>(); public void addProduct(Product product) { - products.add(product); + products.put(product, 1); } public void addProduct(Product product, Integer quantity) { - // TODO: implement + products.put(product, quantity); } public BigDecimal getSubtotal() { BigDecimal subtotal = BigDecimal.ZERO; - for (Product product : products) { - subtotal = subtotal.add(product.getPrice()); + for (Map.Entry entry : products.entrySet()) { + Product product = entry.getKey(); + Integer quantity = entry.getValue(); + + subtotal = subtotal.add( + product.getPrice().multiply(BigDecimal.valueOf(quantity))); } return subtotal; } From 390eaab134f11b732566e0ae6ca38ae778abc645 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 18:46:09 +0100 Subject: [PATCH 06/15] Invoice: implementacja getTotal() jako subtotal + tax --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 2 +- 1 file changed, 1 insertion(+), 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 08ec3b4d7..e59b48fac 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -38,6 +38,6 @@ public BigDecimal getTax() { } public BigDecimal getTotal() { - return BigDecimal.ZERO; + return getSubtotal().add(getTax()); } } From 1356fce522be6ef422c6e1ad61013f9c5e0d1316 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Mon, 16 Feb 2026 18:53:51 +0100 Subject: [PATCH 07/15] =?UTF-8?q?Invoice:=20implementacja=20getTax()=20dla?= =?UTF-8?q?=20wielu=20produkt=C3=B3w=20i=20quantity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 13 ++++++++++++- 1 file changed, 12 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 e59b48fac..0eee191f5 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -34,7 +34,18 @@ public BigDecimal getSubtotal() { } public BigDecimal getTax() { - return BigDecimal.ZERO; + BigDecimal tax = BigDecimal.ZERO; + for (Map.Entry entry : products.entrySet()) { + Product product = entry.getKey(); + Integer quantity = entry.getValue(); + + BigDecimal productTax = + product.getPrice() + .multiply(product.getTaxPercent()) + .multiply(BigDecimal.valueOf(quantity)); + tax = tax.add(productTax); + } + return tax; } public BigDecimal getTotal() { From 4516585aa0895424c7f223f6355e3a4500cec875 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Wed, 18 Feb 2026 08:35:17 +0100 Subject: [PATCH 08/15] Invoice: implementacja zgodna z InvoiceTest --- src/main/java/pl/edu/agh/mwo/invoice/Invoice.java | 10 +++++++++- 1 file changed, 9 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 0eee191f5..3fd0def7a 100644 --- a/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java +++ b/src/main/java/pl/edu/agh/mwo/invoice/Invoice.java @@ -12,10 +12,18 @@ public class Invoice { private Map products = new HashMap<>(); public void addProduct(Product product) { - products.put(product, 1); + addProduct(product, 1); } public void addProduct(Product product, Integer quantity) { + + if (product == null) { + throw new IllegalArgumentException("Product cannot be null"); + } + + if (quantity == null || quantity <= 0) { + throw new IllegalArgumentException("Quantity must be positive"); + } products.put(product, quantity); } From bb14e3621b1308a923c4c96738aad81e67082cc3 Mon Sep 17 00:00:00 2001 From: Aleksandra Date: Sun, 14 Jun 2026 20:16:45 +0200 Subject: [PATCH 09/15] 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 10/15] 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 11/15] 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 12/15] 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 13/15] 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 14/15] =?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 15/15] 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())); + } }