Skip to content
60 changes: 53 additions & 7 deletions src/main/java/pl/edu/agh/mwo/invoice/Invoice.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,76 @@
package pl.edu.agh.mwo.invoice;

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<Product> products;

public Invoice() {
this.products = new ArrayList<>();
}


public void addProduct(Product product) {
// TODO: implement
this.addProduct(product,1);
}


public void addProduct(Product product, Integer quantity) {
// TODO: implement
if(product == null) {
throw new IllegalArgumentException("Product cannot be null");

} if (quantity <= 0) {
throw new IllegalArgumentException("Quantity must be greater than 0");
}

this.productsMap.put(product,quantity);
}

public BigDecimal getSubtotal() {
return null;

private Map<Product,Integer> productsMap = new HashMap<>();

public BigDecimal getNetValue() {


BigDecimal netValue = BigDecimal.ZERO;

for (Product product : this.productsMap.keySet()) {
Integer quantity = this.productsMap.get(product);
BigDecimal price = product.getPrice();
price = price.multiply(BigDecimal.valueOf(quantity));
netValue = netValue.add(price);

}return netValue;


}


public BigDecimal getTax() {
return null;
return getGrossValue().subtract(getNetValue());
}

public BigDecimal getTotal() {
return null;

public BigDecimal getGrossValue() {
BigDecimal netValue = BigDecimal.ZERO;

for (Product product : this.productsMap.keySet()) {
Integer quantity = this.productsMap.get(product);
BigDecimal price = product.getPriceWithTax();
price = price.multiply(BigDecimal.valueOf(quantity));
netValue = netValue.add(price);

}
return netValue;

}


}

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.math.BigDecimal;

public class OtherProduct extends Product {

public OtherProduct(String name, BigDecimal price) {
super(name, price, new BigDecimal("0.23"));
}
Expand Down
24 changes: 20 additions & 4 deletions src/main/java/pl/edu/agh/mwo/invoice/product/Product.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,41 @@ 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");
}
this.name = name;

if(price == null) {
throw new IllegalArgumentException("Price cannot be null");
}
this.price = price;

if(tax == null|| price.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Tax percent cannot be null");
}
this.taxPercent = tax;
}


public String getName() {
return null;
return this.name;
}

public BigDecimal getPrice() {
return null;
return this.price;
}

public BigDecimal getTaxPercent() {
return null;
return this.taxPercent;
}

public BigDecimal getPriceWithTax() {
return null;
BigDecimal result = this.price.multiply(this.taxPercent);
return (BigDecimal)price.add(result);

}
}
128 changes: 128 additions & 0 deletions src/test/java/pl/edu/agh/mwo/invoice/InvoiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package pl.edu.agh.mwo.invoice;

import java.math.BigDecimal;

import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import pl.edu.agh.mwo.invoice.product.DairyProduct;
import pl.edu.agh.mwo.invoice.product.OtherProduct;
import pl.edu.agh.mwo.invoice.product.Product;
import pl.edu.agh.mwo.invoice.product.TaxFreeProduct;

public class InvoiceTest {
private Invoice invoice;

@Before
public void createEmptyInvoiceForTheTest() {
invoice = new Invoice();
}


@Test
public void testEmptyInvoiceHasEmptySubtotal() {
Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getNetValue()));
}

@Test
public void testEmptyInvoiceHasEmptyTaxAmount() {
Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getTax()));
}

@Test
public void testEmptyInvoiceHasEmptyTotal() {
Assert.assertThat(BigDecimal.ZERO, Matchers.comparesEqualTo(invoice.getGrossValue()));
}

@Test
public void testInvoiceNetValueWithTwoDifferentProducts() {
Product onions = new TaxFreeProduct("WarzywaWazrywa", new BigDecimal("10"));
Product apples = new TaxFreeProduct("Owoce", new BigDecimal("10"));
invoice.addProduct(onions);
invoice.addProduct(apples);
Assert.assertThat(new BigDecimal("20"), Matchers.comparesEqualTo(invoice.getNetValue()));
}

@Test
public void testInvoiceSNetValueWithManySameProducts() {
Product onions = new TaxFreeProduct("Warzywa", BigDecimal.valueOf(10));
invoice.addProduct(onions, 100);
Assert.assertThat(new BigDecimal("1000"), Matchers.comparesEqualTo(invoice.getNetValue()));
}

@Test
public void testInvoiceHasTheSameSubtotalAndTotalIfTaxIsZero() {
Product taxFreeProduct = new TaxFreeProduct("Warzywa", new BigDecimal("199.99"));
invoice.addProduct(taxFreeProduct);
Assert.assertThat(invoice.getGrossValue(), Matchers.comparesEqualTo(invoice.getNetValue()));
}

@Test
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.getNetValue()));
}

@Test
public void testInvoiceHasProperTaxValueForManyProduct() {
// tax: 0
invoice.addProduct(new TaxFreeProduct("Pampersy", new BigDecimal("200")));
// tax: 8
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()));
}

@Test
public void testInvoiceHasProperTotalValueForManyProduct() {
// price with tax: 200
invoice.addProduct(new TaxFreeProduct("Maskotki", new BigDecimal("200")));
// price with tax: 108
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.getGrossValue()));
}

@Test
public void testInvoiceHasPropoerSubtotalWithQuantityMoreThanOne() {
// 2x kubek - price: 10
invoice.addProduct(new TaxFreeProduct("Kubek", new BigDecimal("5")), 2);
// 3x kozi serek - price: 30
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.getNetValue()));
}

@Test
public void testInvoiceHasPropoerTotalWithQuantityMoreThanOne() {
// 2x chleb - price with tax: 10
invoice.addProduct(new TaxFreeProduct("Chleb", new BigDecimal("5")), 2);
// 3x chedar - price with tax: 32.40
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.getGrossValue()));
}

@Test(expected = IllegalArgumentException.class)
public void testInvoiceWithZeroQuantity() {
invoice.addProduct(new TaxFreeProduct("Tablet", new BigDecimal("1678")), 0);
}

@Test(expected = IllegalArgumentException.class)
public void testInvoiceWithNegativeQuantity() {
invoice.addProduct(new DairyProduct("Zsiadle mleko", new BigDecimal("5.55")), -1);
}

@Test(expected = IllegalArgumentException.class)
public void testAddingNullProduct() {
invoice.addProduct(null);
}
}
57 changes: 57 additions & 0 deletions src/test/java/pl/edu/agh/mwo/invoice/product/ProductTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package pl.edu.agh.mwo.invoice.product;

import java.math.BigDecimal;

import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;

import pl.edu.agh.mwo.invoice.product.Product;

public class ProductTest {
@Test
public void testProductNameIsCorrect() {
Product product = new OtherProduct("buty", new BigDecimal("100.0"));
Assert.assertEquals("buty", product.getName());
}

@Test
public void testProductPriceAndTaxWithDefaultTax() {
Product product = new OtherProduct("Ogorki", new BigDecimal("100.0"));
Assert.assertThat(new BigDecimal("100"), Matchers.comparesEqualTo(product.getPrice()));
Assert.assertThat(new BigDecimal("0.23"), Matchers.comparesEqualTo(product.getTaxPercent()));
}

@Test
public void testProductPriceAndTaxWithDairyProduct() {
Product product = new DairyProduct("Szarlotka", new BigDecimal("100.0"));
Assert.assertThat(new BigDecimal("100"), Matchers.comparesEqualTo(product.getPrice()));
Assert.assertThat(new BigDecimal("0.08"), Matchers.comparesEqualTo(product.getTaxPercent()));
}

@Test
public void testPriceWithTax() {
Product product = new DairyProduct("Oscypek", new BigDecimal("100.0"));
Assert.assertThat(new BigDecimal("108"), Matchers.comparesEqualTo(product.getPriceWithTax()));
}

@Test(expected = IllegalArgumentException.class)
public void testProductWithNullName() {
new OtherProduct(null, new BigDecimal("100.0"));
}

@Test(expected = IllegalArgumentException.class)
public void testProductWithEmptyName() {
new TaxFreeProduct("", new BigDecimal("100.0"));
}

@Test(expected = IllegalArgumentException.class)
public void testProductWithNullPrice() {
new DairyProduct("Banany", null);
}

@Test(expected = IllegalArgumentException.class)
public void testProductWithNegativePrice() {
new TaxFreeProduct("Mandarynki", new BigDecimal("-1.00"));
}
}