diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/oop-workshop.iml b/oop-workshop.iml
index f6a7637..678d355 100644
--- a/oop-workshop.iml
+++ b/oop-workshop.iml
@@ -21,5 +21,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/checkout/AnyGoodsOffer.java b/src/checkout/AnyGoodsOffer.java
deleted file mode 100644
index 8b11348..0000000
--- a/src/checkout/AnyGoodsOffer.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package checkout;
-
-public class AnyGoodsOffer extends Offer {
- public final int totalCost;
- public final int points;
-
- public AnyGoodsOffer(int totalCost, int points) {
- this.totalCost = totalCost;
- this.points = points;
- }
-
- @Override
- public void apply(Check check) {
-
- }
-}
diff --git a/src/checkout/ByCategory.java b/src/checkout/ByCategory.java
new file mode 100644
index 0000000..625c131
--- /dev/null
+++ b/src/checkout/ByCategory.java
@@ -0,0 +1,19 @@
+package checkout;
+
+public class ByCategory implements Condition {
+ private Category category;
+
+ public ByCategory(Category category) {
+ this.category = category;
+ }
+
+ @Override
+ public boolean inCondition(Check check) {
+ return check.getCostByCategory(category) > 0;
+ }
+
+ @Override
+ public int getPointsByCondition(Check check) {
+ return check.getCostByCategory(category);
+ }
+}
diff --git a/src/checkout/ByTrademark.java b/src/checkout/ByTrademark.java
new file mode 100644
index 0000000..dab1ca3
--- /dev/null
+++ b/src/checkout/ByTrademark.java
@@ -0,0 +1,19 @@
+package checkout;
+
+public class ByTrademark implements Condition {
+ private Trademark trademark;
+
+ public ByTrademark(Trademark trademark) {
+ this.trademark = trademark;
+ }
+
+ @Override
+ public boolean inCondition(Check check) {
+ return check.getCostByTrademark(trademark) > 0;
+ }
+
+ @Override
+ public int getPointsByCondition(Check check) {
+ return check.getCostByTrademark(trademark);
+ }
+}
diff --git a/src/checkout/Category.java b/src/checkout/Category.java
index 0f1dff7..3bedbba 100644
--- a/src/checkout/Category.java
+++ b/src/checkout/Category.java
@@ -1,5 +1,6 @@
package checkout;
public enum Category {
- MILK
+ MILK,
+ MEAT
}
diff --git a/src/checkout/Check.java b/src/checkout/Check.java
index 31436e5..15a814a 100644
--- a/src/checkout/Check.java
+++ b/src/checkout/Check.java
@@ -6,6 +6,7 @@
public class Check {
private List products = new ArrayList<>();
private int points = 0;
+ private int discount = 0;
public int getTotalCost() {
int totalCost = 0;
@@ -33,4 +34,19 @@ int getCostByCategory(Category category) {
.mapToInt(p -> p.price)
.reduce(0, (a, b) -> a + b);
}
+
+ int getCostByTrademark(Trademark trademark) {
+ return products.stream()
+ .filter(p -> p.trademark == trademark)
+ .mapToInt(p -> p.price)
+ .reduce(0, (a, b) -> a + b);
+ }
+
+ void addDiscount(int discount) {
+ this.discount += discount;
+ }
+
+ public int getDiscount() {
+ return discount;
+ }
}
diff --git a/src/checkout/CheckoutService.java b/src/checkout/CheckoutService.java
index 3ac7cbb..b1cecba 100644
--- a/src/checkout/CheckoutService.java
+++ b/src/checkout/CheckoutService.java
@@ -1,8 +1,12 @@
package checkout;
+import java.util.ArrayList;
+import java.util.List;
+
public class CheckoutService {
- private Check check;
+ private Check check = new Check();
+ private List offers = new ArrayList<>();
public void openCheck() {
check = new Check();
@@ -16,23 +20,15 @@ public void addProduct(Product product) {
}
public Check closeCheck() {
+ for (Offer of : offers) {
+ of.apply(check);
+ }
Check closedCheck = check;
check = null;
return closedCheck;
}
public void useOffer(Offer offer) {
- offer.apply(check);
- if (offer instanceof FactorByCategoryOffer) {
- FactorByCategoryOffer fbOffer = (FactorByCategoryOffer) offer;
- int points = check.getCostByCategory(fbOffer.category);
- check.addPoints(points * (fbOffer.factor - 1));
- } else {
- if (offer instanceof AnyGoodsOffer) {
- AnyGoodsOffer agOffer = (AnyGoodsOffer) offer;
- if (agOffer.totalCost <= check.getTotalCost())
- check.addPoints(agOffer.points);
- }
- }
+ offers.add(offer);
}
}
diff --git a/src/checkout/Condition.java b/src/checkout/Condition.java
new file mode 100644
index 0000000..41943e8
--- /dev/null
+++ b/src/checkout/Condition.java
@@ -0,0 +1,7 @@
+package checkout;
+
+public interface Condition {
+ boolean inCondition(Check check);
+
+ int getPointsByCondition(Check check);
+}
diff --git a/src/checkout/Discount.java b/src/checkout/Discount.java
new file mode 100644
index 0000000..ede0be3
--- /dev/null
+++ b/src/checkout/Discount.java
@@ -0,0 +1,15 @@
+package checkout;
+
+public class Discount implements Reward {
+ private int discont;
+
+ public Discount(int discont) {
+ this.discont = discont;
+ }
+
+ @Override
+ public void useReward(Check check, Condition condition) {
+ int points = condition.getPointsByCondition(check);
+ check.addDiscount((int) Math.round(points * (discont / 100d)));
+ }
+}
diff --git a/src/checkout/Factor.java b/src/checkout/Factor.java
new file mode 100644
index 0000000..148e3ec
--- /dev/null
+++ b/src/checkout/Factor.java
@@ -0,0 +1,15 @@
+package checkout;
+
+public class Factor implements Reward {
+ private int factor;
+
+ public Factor(int factor) {
+ this.factor = factor;
+ }
+
+ @Override
+ public void useReward(Check check, Condition condition) {
+ int points = condition.getPointsByCondition(check);
+ check.addPoints(points * (factor - 1));
+ }
+}
diff --git a/src/checkout/FactorByCategoryOffer.java b/src/checkout/FactorByCategoryOffer.java
deleted file mode 100644
index fee57f0..0000000
--- a/src/checkout/FactorByCategoryOffer.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package checkout;
-
-public class FactorByCategoryOffer extends Offer {
- final Category category;
- final int factor;
-
- public FactorByCategoryOffer(Category category, int factor) {
- this.category = category;
- this.factor = factor;
- }
-
- @Override
- public void apply(Check check) {
-
- }
-}
diff --git a/src/checkout/Flat.java b/src/checkout/Flat.java
new file mode 100644
index 0000000..4257e9e
--- /dev/null
+++ b/src/checkout/Flat.java
@@ -0,0 +1,14 @@
+package checkout;
+
+public class Flat implements Reward {
+ private int points;
+
+ public Flat(int points) {
+ this.points = points;
+ }
+
+ @Override
+ public void useReward(Check check, Condition condition) {
+ check.addPoints(points);
+ }
+}
diff --git a/src/checkout/Offer.java b/src/checkout/Offer.java
index f2c67fe..7f23953 100644
--- a/src/checkout/Offer.java
+++ b/src/checkout/Offer.java
@@ -1,5 +1,10 @@
package checkout;
+import java.util.Date;
+
public abstract class Offer {
public abstract void apply(Check check);
+ public boolean isValid(Date expirationDate) {
+ return expirationDate.after(new Date());
+ };
}
diff --git a/src/checkout/Product.java b/src/checkout/Product.java
index f03a6e8..d8b8570 100644
--- a/src/checkout/Product.java
+++ b/src/checkout/Product.java
@@ -4,6 +4,7 @@ public class Product {
final int price;
final String name;
Category category;
+ Trademark trademark;
public Product(int price, String name, Category category) {
this.price = price;
@@ -11,7 +12,15 @@ public Product(int price, String name, Category category) {
this.category = category;
}
+ public Product(int price, String name, Category category, Trademark trademark) {
+ this.price = price;
+ this.name = name;
+ this.category = category;
+ this.trademark = trademark;
+ }
+
+
public Product(int price, String name) {
- this(price, name, null);
+ this(price, name, null, null);
}
}
diff --git a/src/checkout/Reward.java b/src/checkout/Reward.java
new file mode 100644
index 0000000..3a683ca
--- /dev/null
+++ b/src/checkout/Reward.java
@@ -0,0 +1,5 @@
+package checkout;
+
+public interface Reward {
+ void useReward(Check check, Condition condition);
+}
diff --git a/src/checkout/SuperOffer.java b/src/checkout/SuperOffer.java
new file mode 100644
index 0000000..14f2cfe
--- /dev/null
+++ b/src/checkout/SuperOffer.java
@@ -0,0 +1,25 @@
+package checkout;
+
+import java.util.Date;
+
+public class SuperOffer extends Offer {
+
+ final Condition condition;
+ final Reward reward;
+ private final Date expirationDate;
+
+
+ public SuperOffer(Condition condition, Reward reward, Date expirationDate) {
+ this.condition = condition;
+ this.reward = reward;
+ this.expirationDate = new Date(expirationDate.getYear() - 1900, expirationDate.getMonth(), expirationDate.getDate());
+ }
+
+ @Override
+ public void apply(Check check) {
+ if (isValid(expirationDate) && condition.inCondition(check)) {
+ reward.useReward(check, condition);
+ }
+ }
+
+}
diff --git a/src/checkout/TotalCost.java b/src/checkout/TotalCost.java
new file mode 100644
index 0000000..38e4c1f
--- /dev/null
+++ b/src/checkout/TotalCost.java
@@ -0,0 +1,19 @@
+package checkout;
+
+public class TotalCost implements Condition {
+ private int amount;
+
+ public TotalCost(int amount) {
+ this.amount = amount;
+ }
+
+ @Override
+ public boolean inCondition(Check check) {
+ return check.getTotalCost() >= amount;
+ }
+
+ @Override
+ public int getPointsByCondition(Check check) {
+ return check.getTotalCost();
+ }
+}
diff --git a/src/checkout/Trademark.java b/src/checkout/Trademark.java
new file mode 100644
index 0000000..3704f82
--- /dev/null
+++ b/src/checkout/Trademark.java
@@ -0,0 +1,7 @@
+package checkout;
+
+public enum Trademark {
+ COLA,
+ FANTA,
+ SPRITE
+}
diff --git a/test/CheckoutServiceTest.java b/test/CheckoutServiceTest.java
index a34315e..10e8d1a 100644
--- a/test/CheckoutServiceTest.java
+++ b/test/CheckoutServiceTest.java
@@ -2,6 +2,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import java.util.Date;
+
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@@ -10,13 +12,15 @@ public class CheckoutServiceTest {
private Product milk_7;
private CheckoutService checkoutService;
private Product bred_3;
+ private Product meat_10;
@BeforeEach
void setUp() {
checkoutService = new CheckoutService();
checkoutService.openCheck();
- milk_7 = new Product(7, "Milk", Category.MILK);
+ milk_7 = new Product(7, "Milk", Category.MILK, Trademark.COLA);
+ meat_10 = new Product(10, "Meat", Category.MEAT);
bred_3 = new Product(3, "Bred");
}
@@ -57,36 +61,66 @@ void closeCheck__calcTotalPoints() {
assertThat(check.getTotalPoints(), is(10));
}
+
@Test
- void useOffer__addOfferPoints() {
+ void useSuperOffer_TotalCost_Flat() {
+ checkoutService.addProduct(milk_7);
checkoutService.addProduct(milk_7);
checkoutService.addProduct(bred_3);
- checkoutService.useOffer(new AnyGoodsOffer(6, 2));
+ checkoutService.useOffer(new SuperOffer(new TotalCost(10), new Flat(10), new Date(2019, 5, 10)));
Check check = checkoutService.closeCheck();
- assertThat(check.getTotalPoints(), is(12));
+ assertThat(check.getTotalPoints(), is(27));
}
- @Test
- void useOffer__whenCostLessThanRequired__doNothing() {
+ void useSuperOffer_ByCategory_Discount() {
+ checkoutService.useOffer(new SuperOffer(new ByCategory(Category.MILK), new Discount(60), new Date(2019, 5, 10)));
+ checkoutService.addProduct(milk_7);
+ checkoutService.addProduct(milk_7);
checkoutService.addProduct(bred_3);
+ Check check = checkoutService.closeCheck();
- checkoutService.useOffer(new AnyGoodsOffer(6, 2));
+ assertThat(check.getDiscount(), is(8));
+ }
+
+ void useSuperOffer_ByTrademark_Factor() {
+ checkoutService.useOffer(new SuperOffer(new ByTrademark(Trademark.COLA), new Factor(2), new Date(2019, 5, 10)));
+ checkoutService.addProduct(milk_7);
+ checkoutService.addProduct(milk_7);
+ checkoutService.addProduct(bred_3);
Check check = checkoutService.closeCheck();
- assertThat(check.getTotalPoints(), is(3));
+ assertThat(check.getTotalPoints(), is(31));
}
- @Test
- void useOffer__factorByCategory() {
+ void useSuperOffer_ByTrademark_Factor_InvalidTrademark() {
+ checkoutService.useOffer(new SuperOffer(new ByTrademark(Trademark.FANTA), new Factor(2), new Date(2019, 5, 10)));
checkoutService.addProduct(milk_7);
checkoutService.addProduct(milk_7);
checkoutService.addProduct(bred_3);
+ Check check = checkoutService.closeCheck();
+
+ assertThat(check.getTotalPoints(), is(17));
+ }
- checkoutService.useOffer(new FactorByCategoryOffer(Category.MILK, 2));
+ void useSuperOffer_AfterExtensionTime() {
+ checkoutService.useOffer(new SuperOffer(new ByTrademark(Trademark.COLA), new Factor(2), new Date(2019, 1, 10)));
+ checkoutService.addProduct(milk_7);
+ checkoutService.addProduct(milk_7);
+ checkoutService.addProduct(bred_3);
Check check = checkoutService.closeCheck();
- assertThat(check.getTotalPoints(), is(31));
+ assertThat(check.getTotalPoints(), is(17));
+ }
+
+ void useSuperOffer_ByCategory_Discount_InvalidCategory() {
+ checkoutService.useOffer(new SuperOffer(new ByCategory(Category.MEAT), new Discount(60), new Date(2019, 5, 10)));
+ checkoutService.addProduct(milk_7);
+ checkoutService.addProduct(milk_7);
+ checkoutService.addProduct(bred_3);
+ Check check = checkoutService.closeCheck();
+
+ assertThat(check.getDiscount(), is(0));
}
}