From 90004b08e316bbf24595cff460ffdcaf4c0052e2 Mon Sep 17 00:00:00 2001 From: andriikonoh Date: Tue, 5 Mar 2019 11:04:30 +0200 Subject: [PATCH 1/8] Move implementations to specific classes --- .idea/misc.xml | 2 +- src/checkout/AnyGoodsOffer.java | 3 ++- src/checkout/CheckoutService.java | 11 ----------- src/checkout/FactorByCategoryOffer.java | 3 ++- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index c9209a5..c08f7b9 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/src/checkout/AnyGoodsOffer.java b/src/checkout/AnyGoodsOffer.java index 8b11348..345995d 100644 --- a/src/checkout/AnyGoodsOffer.java +++ b/src/checkout/AnyGoodsOffer.java @@ -11,6 +11,7 @@ public AnyGoodsOffer(int totalCost, int points) { @Override public void apply(Check check) { - + if (this.totalCost <= check.getTotalCost()) + check.addPoints(this.points); } } diff --git a/src/checkout/CheckoutService.java b/src/checkout/CheckoutService.java index 3ac7cbb..72e9a53 100644 --- a/src/checkout/CheckoutService.java +++ b/src/checkout/CheckoutService.java @@ -23,16 +23,5 @@ public Check closeCheck() { 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); - } - } } } diff --git a/src/checkout/FactorByCategoryOffer.java b/src/checkout/FactorByCategoryOffer.java index fee57f0..0f90070 100644 --- a/src/checkout/FactorByCategoryOffer.java +++ b/src/checkout/FactorByCategoryOffer.java @@ -11,6 +11,7 @@ public FactorByCategoryOffer(Category category, int factor) { @Override public void apply(Check check) { - + int points = check.getCostByCategory(this.category); + check.addPoints(points * (this.factor - 1)); } } From 10ade4f22202d3dde702d6af98dd11a6f6323ca6 Mon Sep 17 00:00:00 2001 From: andriikonoh Date: Tue, 5 Mar 2019 11:05:09 +0200 Subject: [PATCH 2/8] Implement the ability to use offers before closing a check --- src/checkout/Check.java | 5 +++++ test/CheckoutServiceTest.java | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/checkout/Check.java b/src/checkout/Check.java index 31436e5..925fbc9 100644 --- a/src/checkout/Check.java +++ b/src/checkout/Check.java @@ -15,6 +15,11 @@ public int getTotalCost() { return totalCost; } + public int getTotalCostWithDiscount(){ + + return getTotalCost() - getTotalPoints()/10; + } + void addProduct(Product product) { products.add(product); } diff --git a/test/CheckoutServiceTest.java b/test/CheckoutServiceTest.java index a34315e..2649825 100644 --- a/test/CheckoutServiceTest.java +++ b/test/CheckoutServiceTest.java @@ -88,5 +88,19 @@ void useOffer__factorByCategory() { Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(31)); + assertThat(check.getTotalCost(), is(17)); + assertThat(check.getTotalCostWithDiscount(), is(14)); } + + @Test + void useOffer_beforeCheckClose(){ + checkoutService.addProduct(milk_7); + checkoutService.addProduct(milk_7); + checkoutService.addProduct((bred_3)); + checkoutService.useOffer(new AnyGoodsOffer(6,2)); + checkoutService.useOffer(new FactorByCategoryOffer(Category.MILK, 2)); + Check check = checkoutService.closeCheck(); + assertThat(check.getTotalPoints(), is(33)); + } + } From b5f70e279bfe1134c64ba42444b8f96e4089e30a Mon Sep 17 00:00:00 2001 From: andriikonoh Date: Tue, 5 Mar 2019 11:19:44 +0200 Subject: [PATCH 3/8] Implement the ability to use offers before closing a check --- src/checkout/CheckoutService.java | 7 +++++++ test/CheckoutServiceTest.java | 13 +++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/checkout/CheckoutService.java b/src/checkout/CheckoutService.java index 72e9a53..c1fdd5e 100644 --- a/src/checkout/CheckoutService.java +++ b/src/checkout/CheckoutService.java @@ -21,6 +21,13 @@ public Check closeCheck() { return closedCheck; } + public Check closeCheckAndUseOffer(){ + useOffer(new AnyGoodsOffer(6,2)); + useOffer(new FactorByCategoryOffer(Category.MILK, 2)); + Check closedCheck = closeCheck(); + return closedCheck; + } + public void useOffer(Offer offer) { offer.apply(check); } diff --git a/test/CheckoutServiceTest.java b/test/CheckoutServiceTest.java index 2649825..0d5165d 100644 --- a/test/CheckoutServiceTest.java +++ b/test/CheckoutServiceTest.java @@ -88,8 +88,6 @@ void useOffer__factorByCategory() { Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(31)); - assertThat(check.getTotalCost(), is(17)); - assertThat(check.getTotalCostWithDiscount(), is(14)); } @Test @@ -101,6 +99,17 @@ void useOffer_beforeCheckClose(){ checkoutService.useOffer(new FactorByCategoryOffer(Category.MILK, 2)); Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(33)); + assertThat(check.getTotalCost(), is(17)); + assertThat(check.getTotalCostWithDiscount(), is(14)); + } + + @Test + void useOffer_whenCheckClose(){ + checkoutService.addProduct(milk_7); + checkoutService.addProduct(milk_7); + checkoutService.addProduct((bred_3)); + Check check = checkoutService.closeCheckAndUseOffer(); + assertThat(check.getTotalCostWithDiscount(), is(14)); } } From 379f99ce31d6d52b801b01c857cc0ffe59666ffa Mon Sep 17 00:00:00 2001 From: andriikonoh Date: Tue, 5 Mar 2019 12:08:05 +0200 Subject: [PATCH 4/8] Implement expiration date cheker --- src/checkout/AnyGoodsOffer.java | 11 +++++++++++ src/checkout/FactorByCategoryOffer.java | 11 +++++++++++ src/checkout/Offer.java | 5 +++++ test/CheckoutServiceTest.java | 18 ++++++++++++++++++ 4 files changed, 45 insertions(+) diff --git a/src/checkout/AnyGoodsOffer.java b/src/checkout/AnyGoodsOffer.java index 345995d..c960a09 100644 --- a/src/checkout/AnyGoodsOffer.java +++ b/src/checkout/AnyGoodsOffer.java @@ -1,5 +1,7 @@ package checkout; +import java.time.LocalDate; + public class AnyGoodsOffer extends Offer { public final int totalCost; public final int points; @@ -7,6 +9,7 @@ public class AnyGoodsOffer extends Offer { public AnyGoodsOffer(int totalCost, int points) { this.totalCost = totalCost; this.points = points; + this.expirationDate = LocalDate.of(2020, 1,1); } @Override @@ -14,4 +17,12 @@ public void apply(Check check) { if (this.totalCost <= check.getTotalCost()) check.addPoints(this.points); } + + + @Override + public boolean isOfferavAilable(){ + if (this.expirationDate.isAfter(todayDate)) + return true; + else return false; + } } diff --git a/src/checkout/FactorByCategoryOffer.java b/src/checkout/FactorByCategoryOffer.java index 0f90070..68dcea1 100644 --- a/src/checkout/FactorByCategoryOffer.java +++ b/src/checkout/FactorByCategoryOffer.java @@ -1,5 +1,7 @@ package checkout; +import java.time.LocalDate; + public class FactorByCategoryOffer extends Offer { final Category category; final int factor; @@ -7,6 +9,7 @@ public class FactorByCategoryOffer extends Offer { public FactorByCategoryOffer(Category category, int factor) { this.category = category; this.factor = factor; + this.expirationDate = LocalDate.of(2018, 1,1); } @Override @@ -14,4 +17,12 @@ public void apply(Check check) { int points = check.getCostByCategory(this.category); check.addPoints(points * (this.factor - 1)); } + + @Override + public boolean isOfferavAilable() { + if (this.expirationDate.isAfter(todayDate)) + return true; + else return false; + } + } diff --git a/src/checkout/Offer.java b/src/checkout/Offer.java index f2c67fe..27e86de 100644 --- a/src/checkout/Offer.java +++ b/src/checkout/Offer.java @@ -1,5 +1,10 @@ package checkout; +import java.time.LocalDate; + public abstract class Offer { + public final LocalDate todayDate = LocalDate.now(); + public LocalDate expirationDate; public abstract void apply(Check check); + public abstract boolean isOfferavAilable(); } diff --git a/test/CheckoutServiceTest.java b/test/CheckoutServiceTest.java index 0d5165d..01db2ca 100644 --- a/test/CheckoutServiceTest.java +++ b/test/CheckoutServiceTest.java @@ -112,4 +112,22 @@ void useOffer_whenCheckClose(){ assertThat(check.getTotalCostWithDiscount(), is(14)); } + @Test + void isFactorByCategoryOfferAilable(){ + checkoutService.addProduct(milk_7); + checkoutService.addProduct(milk_7); + checkoutService.addProduct((bred_3)); + Offer offer = new FactorByCategoryOffer(Category.MILK, 2); + assertThat(offer.isOfferavAilable(), is(false)); + } + + @Test + void isAnyGoodsOfferAvaliable(){ + checkoutService.addProduct(milk_7); + checkoutService.addProduct(milk_7); + checkoutService.addProduct((bred_3)); + Offer offer = new AnyGoodsOffer(6,2); + assertThat(offer.isOfferavAilable(), is(true)); + } + } From cdf13b4ae6ba716016bb28ed82f76177c5abb9aa Mon Sep 17 00:00:00 2001 From: andriikonoh Date: Tue, 5 Mar 2019 18:25:30 +0200 Subject: [PATCH 5/8] Implement StrategyRealisation --- src/checkout/Brand.java | 5 +++ src/checkout/ByBrand.java | 12 +++++++ src/checkout/ByCategory.java | 12 +++++++ src/checkout/Check.java | 23 +++++++++++-- src/checkout/CheckoutService.java | 5 +++ src/checkout/Condition.java | 35 ++++++++++++++++++++ src/checkout/Discount.java | 9 ++++++ src/checkout/Factor.java | 8 +++++ src/checkout/Flat.java | 8 +++++ src/checkout/OfferWithStrategy.java | 16 ++++++++++ src/checkout/Product.java | 8 ++++- src/checkout/Reward.java | 27 ++++++++++++++++ src/checkout/SpecificBrandOffer.java | 27 ++++++++++++++++ src/checkout/TotalCost.java | 8 +++++ test/CheckoutServiceTest.java | 48 ++++++++++++++++++++++++++-- 15 files changed, 246 insertions(+), 5 deletions(-) create mode 100644 src/checkout/Brand.java create mode 100644 src/checkout/ByBrand.java create mode 100644 src/checkout/ByCategory.java create mode 100644 src/checkout/Condition.java create mode 100644 src/checkout/Discount.java create mode 100644 src/checkout/Factor.java create mode 100644 src/checkout/Flat.java create mode 100644 src/checkout/OfferWithStrategy.java create mode 100644 src/checkout/Reward.java create mode 100644 src/checkout/SpecificBrandOffer.java create mode 100644 src/checkout/TotalCost.java diff --git a/src/checkout/Brand.java b/src/checkout/Brand.java new file mode 100644 index 0000000..323e73c --- /dev/null +++ b/src/checkout/Brand.java @@ -0,0 +1,5 @@ +package checkout; + +public enum Brand { + VOLOSHKOVE_POLE +} diff --git a/src/checkout/ByBrand.java b/src/checkout/ByBrand.java new file mode 100644 index 0000000..69eba4b --- /dev/null +++ b/src/checkout/ByBrand.java @@ -0,0 +1,12 @@ +package checkout; + +public class ByBrand implements Condition { + @Override + public boolean checkCondition(Check check) { + boolean marker = false; + for (Product p : check.getProducts()) { + if (p.brand == Brand.VOLOSHKOVE_POLE) marker = true; + } + return marker; + } +} diff --git a/src/checkout/ByCategory.java b/src/checkout/ByCategory.java new file mode 100644 index 0000000..6ad1118 --- /dev/null +++ b/src/checkout/ByCategory.java @@ -0,0 +1,12 @@ +package checkout; + +public class ByCategory implements Condition{ + @Override + public boolean checkCondition(Check check){ + boolean marker = false; + for(Product p : check.getProducts()){ + if (p.category == Category.MILK) marker = true; + } + return marker; + } +} diff --git a/src/checkout/Check.java b/src/checkout/Check.java index 925fbc9..c659639 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; @@ -16,8 +17,7 @@ public int getTotalCost() { } public int getTotalCostWithDiscount(){ - - return getTotalCost() - getTotalPoints()/10; + return getTotalCost() - discount/10; } void addProduct(Product product) { @@ -38,4 +38,23 @@ int getCostByCategory(Category category) { .mapToInt(p -> p.price) .reduce(0, (a, b) -> a + b); } + + public int getPointsForBrand(Brand brand) { + return products.stream() + .filter(p -> p.brand == brand) + .mapToInt(p -> p.price) + .reduce(0, (a,b)-> a+b); + } + + public void addDiscount(int discount) { + this.discount = discount; + } + + public int getDiscount(){ + return discount; + } + + public List getProducts() { + return products; + } } diff --git a/src/checkout/CheckoutService.java b/src/checkout/CheckoutService.java index c1fdd5e..3598fb2 100644 --- a/src/checkout/CheckoutService.java +++ b/src/checkout/CheckoutService.java @@ -24,6 +24,7 @@ public Check closeCheck() { public Check closeCheckAndUseOffer(){ useOffer(new AnyGoodsOffer(6,2)); useOffer(new FactorByCategoryOffer(Category.MILK, 2)); + useOffer(new SpecificBrandOffer(Brand.VOLOSHKOVE_POLE, 50)); Check closedCheck = closeCheck(); return closedCheck; } @@ -31,4 +32,8 @@ public Check closeCheckAndUseOffer(){ public void useOffer(Offer offer) { offer.apply(check); } + + public void useOfferWithStrategy(OfferWithStrategy offer){ + offer.applyStrategy(check); + } } diff --git a/src/checkout/Condition.java b/src/checkout/Condition.java new file mode 100644 index 0000000..1ff80bd --- /dev/null +++ b/src/checkout/Condition.java @@ -0,0 +1,35 @@ +package checkout; + +public interface Condition { + boolean checkCondition(Check check); +} +/* + +class TotalCost implements Condition { + @Override + public boolean checkCondition(Check check) { + return (10 <= check.getTotalCost()); + } +} + +class ByCategory implements Condition{ + @Override + public boolean checkCondition(Check check){ + boolean marker = false; + for(Product p : check.getProducts()){ + if (p.category == Category.MILK) marker = true; + } + return marker; + } +} + +class ByBrand implements Condition{ + @Override + public boolean checkCondition(Check check){ + boolean marker = false; + for(Product p : check.getProducts()){ + if (p.brand == Brand.VOLOSHKOVE_POLE) marker = true; + } + return marker; + } +}*/ diff --git a/src/checkout/Discount.java b/src/checkout/Discount.java new file mode 100644 index 0000000..772fbba --- /dev/null +++ b/src/checkout/Discount.java @@ -0,0 +1,9 @@ +package checkout; + +public class Discount implements Reward { + @Override + public void apply(Check check){ + Double points = check.getPointsForBrand(Brand.VOLOSHKOVE_POLE)*0.5*10; + check.addDiscount(points.intValue()); + } +} diff --git a/src/checkout/Factor.java b/src/checkout/Factor.java new file mode 100644 index 0000000..86c5799 --- /dev/null +++ b/src/checkout/Factor.java @@ -0,0 +1,8 @@ +package checkout; + +public class Factor implements Reward { + @Override + public void apply(Check check){ + int points = check.getCostByCategory(Category.MILK); + check.addPoints(points*1); + }} diff --git a/src/checkout/Flat.java b/src/checkout/Flat.java new file mode 100644 index 0000000..5f8f765 --- /dev/null +++ b/src/checkout/Flat.java @@ -0,0 +1,8 @@ +package checkout; + +public class Flat implements Reward { + @Override + public void apply(Check check) { + check.addPoints(20); + } +} \ No newline at end of file diff --git a/src/checkout/OfferWithStrategy.java b/src/checkout/OfferWithStrategy.java new file mode 100644 index 0000000..a0999d3 --- /dev/null +++ b/src/checkout/OfferWithStrategy.java @@ -0,0 +1,16 @@ +package checkout; + +public class OfferWithStrategy { + Reward reward; + Condition condition; + public OfferWithStrategy(Reward reward , Condition condition){ + this.condition = condition; + this.reward = reward; + } + + + public void applyStrategy(Check check){ + if(condition.checkCondition(check)) reward.apply(check); + } + +} diff --git a/src/checkout/Product.java b/src/checkout/Product.java index f03a6e8..fbfc6e1 100644 --- a/src/checkout/Product.java +++ b/src/checkout/Product.java @@ -4,11 +4,17 @@ public class Product { final int price; final String name; Category category; + Brand brand; - public Product(int price, String name, Category category) { + public Product(int price, String name, Category category, Brand brand) { this.price = price; this.name = name; this.category = category; + this.brand = brand; + } + + public Product(int price, String name, Category category) { + this(price, name, category, null); } public Product(int price, String name) { diff --git a/src/checkout/Reward.java b/src/checkout/Reward.java new file mode 100644 index 0000000..ff15cd5 --- /dev/null +++ b/src/checkout/Reward.java @@ -0,0 +1,27 @@ +package checkout; + +public interface Reward { + void apply(Check check); +} + +/*public class Flat implements Reward { + @Override + public void apply(Check check) { + check.addPoints(20); + } +} + +public class Factor implements Reward { + @Override + public void apply(Check check){ + int points = check.getCostByCategory(Category.MILK); + check.addPoints(points*2); + }} +public class Discount implements Reward { + @Override + public void apply(Check check){ + Double points = check.getPointsForBrand(Brand.VOLOSHKOVE_POLE)*0.5*10; + check.addDiscount(points.intValue()); + } + }*/ + diff --git a/src/checkout/SpecificBrandOffer.java b/src/checkout/SpecificBrandOffer.java new file mode 100644 index 0000000..0507427 --- /dev/null +++ b/src/checkout/SpecificBrandOffer.java @@ -0,0 +1,27 @@ +package checkout; + +import java.time.LocalDate; + +public class SpecificBrandOffer extends Offer { + final Brand brand; + final double discount; + + public SpecificBrandOffer(Brand milk, int i) { + this.brand = milk; + this.discount = i/100.0; + this.expirationDate = LocalDate.of(2020, 1,1); + } + + @Override + public void apply(Check check){ + Double points = check.getPointsForBrand(this.brand)*discount*10; + check.addDiscount(points.intValue()); + } + + @Override + public boolean isOfferavAilable() { + if (this.expirationDate.isAfter(todayDate)) + return true; + else return false; + } +} diff --git a/src/checkout/TotalCost.java b/src/checkout/TotalCost.java new file mode 100644 index 0000000..82a17a4 --- /dev/null +++ b/src/checkout/TotalCost.java @@ -0,0 +1,8 @@ +package checkout; + +public class TotalCost implements Condition { + @Override + public boolean checkCondition(Check check) { + return (10 <= check.getTotalCost()); + } +} \ No newline at end of file diff --git a/test/CheckoutServiceTest.java b/test/CheckoutServiceTest.java index 01db2ca..5a28964 100644 --- a/test/CheckoutServiceTest.java +++ b/test/CheckoutServiceTest.java @@ -10,6 +10,7 @@ public class CheckoutServiceTest { private Product milk_7; private CheckoutService checkoutService; private Product bred_3; + private Product milk_WithBrand; @BeforeEach void setUp() { @@ -18,6 +19,7 @@ void setUp() { milk_7 = new Product(7, "Milk", Category.MILK); bred_3 = new Product(3, "Bred"); + milk_WithBrand = new Product(7, "Milk", Category.MILK, Brand.VOLOSHKOVE_POLE); } @Test @@ -100,7 +102,7 @@ void useOffer_beforeCheckClose(){ Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(33)); assertThat(check.getTotalCost(), is(17)); - assertThat(check.getTotalCostWithDiscount(), is(14)); + assertThat(check.getTotalCostWithDiscount(), is(17)); } @Test @@ -109,7 +111,7 @@ void useOffer_whenCheckClose(){ checkoutService.addProduct(milk_7); checkoutService.addProduct((bred_3)); Check check = checkoutService.closeCheckAndUseOffer(); - assertThat(check.getTotalCostWithDiscount(), is(14)); + assertThat(check.getTotalCostWithDiscount(), is(17)); } @Test @@ -130,4 +132,46 @@ void isAnyGoodsOfferAvaliable(){ assertThat(offer.isOfferavAilable(), is(true)); } + @Test + void useOffer_SpecificBrandOffer(){ + checkoutService.addProduct(milk_WithBrand); + checkoutService.addProduct(milk_WithBrand); + checkoutService.useOffer(new SpecificBrandOffer(Brand.VOLOSHKOVE_POLE, 50)); + Check check = checkoutService.closeCheck(); + assertThat(check.getTotalCostWithDiscount(), is(7)); + } + + @Test + void useOffer_Strategy_TotalCost(){ + checkoutService.addProduct(milk_WithBrand); + checkoutService.addProduct(milk_WithBrand); + OfferWithStrategy offer = new OfferWithStrategy(new Flat(), new TotalCost()); + checkoutService.useOfferWithStrategy(offer); + Check check = checkoutService.closeCheck(); + + assertThat(check.getTotalPoints(), is(34)); + } + + @Test + void useOffer_Strategy_ByCategory(){ + checkoutService.addProduct(milk_WithBrand); + checkoutService.addProduct(milk_WithBrand); + OfferWithStrategy offer = new OfferWithStrategy(new Factor(), new ByCategory()); + checkoutService.useOfferWithStrategy(offer); + Check check = checkoutService.closeCheck(); + + assertThat(check.getTotalPoints(), is(28)); + } + + @Test + void useOffer_Strategy_ByBrand(){ + checkoutService.addProduct(milk_WithBrand); + checkoutService.addProduct(milk_WithBrand); + OfferWithStrategy offer = new OfferWithStrategy(new Discount(), new ByBrand()); + checkoutService.useOfferWithStrategy(offer); + Check check = checkoutService.closeCheck(); + + + assertThat(check.getTotalCostWithDiscount(), is(7)); + } } From b463e1ca960acda7a4de82483469ff9b41cff85a Mon Sep 17 00:00:00 2001 From: andriikonoh Date: Wed, 6 Mar 2019 14:08:42 +0200 Subject: [PATCH 6/8] refactor --- .idea/uiDesigner.xml | 124 +++++++++++++++++++++ src/checkout/AnyGoodsOffer.java | 28 ----- src/checkout/ByBrand.java | 11 +- src/checkout/ByCategory.java | 11 +- src/checkout/Check.java | 11 +- src/checkout/CheckoutService.java | 28 +++-- src/checkout/Condition.java | 29 ----- src/checkout/Discount.java | 9 -- src/checkout/DiscountByBrand.java | 24 +++++ src/checkout/Factor.java | 8 -- src/checkout/FactorByCategoryOffer.java | 28 ----- src/checkout/FactorRewardByCategory.java | 24 +++++ src/checkout/Flat.java | 8 -- src/checkout/FlatReward.java | 17 +++ src/checkout/Offer.java | 29 ++++- src/checkout/OfferWithStrategy.java | 16 --- src/checkout/Reward.java | 25 +---- src/checkout/SpecificBrandOffer.java | 27 ----- src/checkout/TotalCost.java | 13 ++- test/CheckoutServiceTest.java | 130 +++++++++-------------- 20 files changed, 320 insertions(+), 280 deletions(-) create mode 100644 .idea/uiDesigner.xml delete mode 100644 src/checkout/AnyGoodsOffer.java delete mode 100644 src/checkout/Discount.java create mode 100644 src/checkout/DiscountByBrand.java delete mode 100644 src/checkout/Factor.java delete mode 100644 src/checkout/FactorByCategoryOffer.java create mode 100644 src/checkout/FactorRewardByCategory.java delete mode 100644 src/checkout/Flat.java create mode 100644 src/checkout/FlatReward.java delete mode 100644 src/checkout/OfferWithStrategy.java delete mode 100644 src/checkout/SpecificBrandOffer.java 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/src/checkout/AnyGoodsOffer.java b/src/checkout/AnyGoodsOffer.java deleted file mode 100644 index c960a09..0000000 --- a/src/checkout/AnyGoodsOffer.java +++ /dev/null @@ -1,28 +0,0 @@ -package checkout; - -import java.time.LocalDate; - -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; - this.expirationDate = LocalDate.of(2020, 1,1); - } - - @Override - public void apply(Check check) { - if (this.totalCost <= check.getTotalCost()) - check.addPoints(this.points); - } - - - @Override - public boolean isOfferavAilable(){ - if (this.expirationDate.isAfter(todayDate)) - return true; - else return false; - } -} diff --git a/src/checkout/ByBrand.java b/src/checkout/ByBrand.java index 69eba4b..09b9536 100644 --- a/src/checkout/ByBrand.java +++ b/src/checkout/ByBrand.java @@ -1,12 +1,21 @@ package checkout; public class ByBrand implements Condition { + Brand brand; + + public ByBrand(Brand brand){ + setBrand(brand); + } @Override public boolean checkCondition(Check check) { boolean marker = false; for (Product p : check.getProducts()) { - if (p.brand == Brand.VOLOSHKOVE_POLE) marker = true; + if (p.brand == brand) marker = true; } return marker; } + + public void setBrand(Brand brand) { + this.brand = brand; + } } diff --git a/src/checkout/ByCategory.java b/src/checkout/ByCategory.java index 6ad1118..9d09499 100644 --- a/src/checkout/ByCategory.java +++ b/src/checkout/ByCategory.java @@ -1,12 +1,21 @@ package checkout; public class ByCategory implements Condition{ + Category category; + + public ByCategory(Category category){ + setCategory(category); + } @Override public boolean checkCondition(Check check){ boolean marker = false; for(Product p : check.getProducts()){ - if (p.category == Category.MILK) marker = true; + if (p.category == category) marker = true; } return marker; } + + public void setCategory(Category category) { + this.category = category; + } } diff --git a/src/checkout/Check.java b/src/checkout/Check.java index c659639..3baf4bd 100644 --- a/src/checkout/Check.java +++ b/src/checkout/Check.java @@ -1,5 +1,7 @@ package checkout; +import java.time.LocalDate; +import java.time.chrono.ChronoLocalDate; import java.util.ArrayList; import java.util.List; @@ -7,6 +9,7 @@ public class Check { private List products = new ArrayList<>(); private int points = 0; private int discount = 0; + private LocalDate todayDate = LocalDate.of(2019, 3, 1); public int getTotalCost() { int totalCost = 0; @@ -50,11 +53,11 @@ public void addDiscount(int discount) { this.discount = discount; } - public int getDiscount(){ - return discount; - } - public List getProducts() { return products; } + + public LocalDate getTodayDate() { + return todayDate; + } } diff --git a/src/checkout/CheckoutService.java b/src/checkout/CheckoutService.java index 3598fb2..e01887b 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 List offers = new ArrayList<>(); public void openCheck() { check = new Check(); @@ -16,24 +20,26 @@ public void addProduct(Product product) { } public Check closeCheck() { + useAllOffer(); Check closedCheck = check; check = null; return closedCheck; } - public Check closeCheckAndUseOffer(){ - useOffer(new AnyGoodsOffer(6,2)); - useOffer(new FactorByCategoryOffer(Category.MILK, 2)); - useOffer(new SpecificBrandOffer(Brand.VOLOSHKOVE_POLE, 50)); - Check closedCheck = closeCheck(); - return closedCheck; + private void useAllOffer(){ + if(this.offers.size()!=0) this.offers.forEach(offer ->{ + if(isOfferavAilable(offer)) offer.apply(check); + }); } - public void useOffer(Offer offer) { - offer.apply(check); - } + public void useOffer(Offer offer){ + if(check != null) + this.offers.add(offer); - public void useOfferWithStrategy(OfferWithStrategy offer){ - offer.applyStrategy(check); + } + public boolean isOfferavAilable(Offer ofer){ + if (ofer.getExpirationDate().isAfter(check.getTodayDate())) + return true; + else return false; } } diff --git a/src/checkout/Condition.java b/src/checkout/Condition.java index 1ff80bd..93ba05e 100644 --- a/src/checkout/Condition.java +++ b/src/checkout/Condition.java @@ -3,33 +3,4 @@ public interface Condition { boolean checkCondition(Check check); } -/* -class TotalCost implements Condition { - @Override - public boolean checkCondition(Check check) { - return (10 <= check.getTotalCost()); - } -} - -class ByCategory implements Condition{ - @Override - public boolean checkCondition(Check check){ - boolean marker = false; - for(Product p : check.getProducts()){ - if (p.category == Category.MILK) marker = true; - } - return marker; - } -} - -class ByBrand implements Condition{ - @Override - public boolean checkCondition(Check check){ - boolean marker = false; - for(Product p : check.getProducts()){ - if (p.brand == Brand.VOLOSHKOVE_POLE) marker = true; - } - return marker; - } -}*/ diff --git a/src/checkout/Discount.java b/src/checkout/Discount.java deleted file mode 100644 index 772fbba..0000000 --- a/src/checkout/Discount.java +++ /dev/null @@ -1,9 +0,0 @@ -package checkout; - -public class Discount implements Reward { - @Override - public void apply(Check check){ - Double points = check.getPointsForBrand(Brand.VOLOSHKOVE_POLE)*0.5*10; - check.addDiscount(points.intValue()); - } -} diff --git a/src/checkout/DiscountByBrand.java b/src/checkout/DiscountByBrand.java new file mode 100644 index 0000000..5926dff --- /dev/null +++ b/src/checkout/DiscountByBrand.java @@ -0,0 +1,24 @@ +package checkout; + +public class DiscountByBrand implements Reward { + private double discount; + private Brand brand; + + public DiscountByBrand(double discount, Brand brand){ + setBrand(brand); + setDiscount(discount); + } + @Override + public void apply(Check check){ + Double points = check.getPointsForBrand(brand) * discount * 10; + check.addDiscount(points.intValue()); + } + + public void setBrand(Brand brand) { + this.brand = brand; + } + + public void setDiscount(double discount) { + this.discount = discount; + } +} diff --git a/src/checkout/Factor.java b/src/checkout/Factor.java deleted file mode 100644 index 86c5799..0000000 --- a/src/checkout/Factor.java +++ /dev/null @@ -1,8 +0,0 @@ -package checkout; - -public class Factor implements Reward { - @Override - public void apply(Check check){ - int points = check.getCostByCategory(Category.MILK); - check.addPoints(points*1); - }} diff --git a/src/checkout/FactorByCategoryOffer.java b/src/checkout/FactorByCategoryOffer.java deleted file mode 100644 index 68dcea1..0000000 --- a/src/checkout/FactorByCategoryOffer.java +++ /dev/null @@ -1,28 +0,0 @@ -package checkout; - -import java.time.LocalDate; - -public class FactorByCategoryOffer extends Offer { - final Category category; - final int factor; - - public FactorByCategoryOffer(Category category, int factor) { - this.category = category; - this.factor = factor; - this.expirationDate = LocalDate.of(2018, 1,1); - } - - @Override - public void apply(Check check) { - int points = check.getCostByCategory(this.category); - check.addPoints(points * (this.factor - 1)); - } - - @Override - public boolean isOfferavAilable() { - if (this.expirationDate.isAfter(todayDate)) - return true; - else return false; - } - -} diff --git a/src/checkout/FactorRewardByCategory.java b/src/checkout/FactorRewardByCategory.java new file mode 100644 index 0000000..9d7ceec --- /dev/null +++ b/src/checkout/FactorRewardByCategory.java @@ -0,0 +1,24 @@ +package checkout; + +public class FactorRewardByCategory implements Reward { + private int factor; + Category category; + + public FactorRewardByCategory(int factor, Category category){ + setCategory(category); + setFactor(factor); + } + @Override + public void apply(Check check){ + int points = check.getCostByCategory(category); + check.addPoints(points*(factor-1)); + } + + public void setFactor(int factor){ + this.factor = factor; + } + + public void setCategory(Category category) { + this.category = category; + } +} diff --git a/src/checkout/Flat.java b/src/checkout/Flat.java deleted file mode 100644 index 5f8f765..0000000 --- a/src/checkout/Flat.java +++ /dev/null @@ -1,8 +0,0 @@ -package checkout; - -public class Flat implements Reward { - @Override - public void apply(Check check) { - check.addPoints(20); - } -} \ No newline at end of file diff --git a/src/checkout/FlatReward.java b/src/checkout/FlatReward.java new file mode 100644 index 0000000..0448e6e --- /dev/null +++ b/src/checkout/FlatReward.java @@ -0,0 +1,17 @@ +package checkout; + +public class FlatReward implements Reward { + private int reward; + + public FlatReward (int reward){ + setReward(reward); + } + @Override + public void apply(Check check) { + check.addPoints(reward); + } + + public void setReward(int reward) { + this.reward = reward; + } +} \ No newline at end of file diff --git a/src/checkout/Offer.java b/src/checkout/Offer.java index 27e86de..6707fdc 100644 --- a/src/checkout/Offer.java +++ b/src/checkout/Offer.java @@ -2,9 +2,28 @@ import java.time.LocalDate; -public abstract class Offer { - public final LocalDate todayDate = LocalDate.now(); - public LocalDate expirationDate; - public abstract void apply(Check check); - public abstract boolean isOfferavAilable(); +public class Offer { + Reward reward; + Condition condition; + private LocalDate expirationDate; + + public Offer(Reward reward , Condition condition, LocalDate expirationDate){ + this.condition = condition; + this.reward = reward; + this.expirationDate = expirationDate; + } + + public Offer(Reward reward , Condition condition){ + this.condition = condition; + this.reward = reward; + this.expirationDate = LocalDate.of(2019, 3, 7); + } + + public void apply(Check check){ + if(condition.checkCondition(check)) reward.apply(check); + } + + public LocalDate getExpirationDate() { + return expirationDate; + } } diff --git a/src/checkout/OfferWithStrategy.java b/src/checkout/OfferWithStrategy.java deleted file mode 100644 index a0999d3..0000000 --- a/src/checkout/OfferWithStrategy.java +++ /dev/null @@ -1,16 +0,0 @@ -package checkout; - -public class OfferWithStrategy { - Reward reward; - Condition condition; - public OfferWithStrategy(Reward reward , Condition condition){ - this.condition = condition; - this.reward = reward; - } - - - public void applyStrategy(Check check){ - if(condition.checkCondition(check)) reward.apply(check); - } - -} diff --git a/src/checkout/Reward.java b/src/checkout/Reward.java index ff15cd5..75e696d 100644 --- a/src/checkout/Reward.java +++ b/src/checkout/Reward.java @@ -1,27 +1,6 @@ package checkout; public interface Reward { - void apply(Check check); -} - -/*public class Flat implements Reward { - @Override - public void apply(Check check) { - check.addPoints(20); - } -} - -public class Factor implements Reward { - @Override - public void apply(Check check){ - int points = check.getCostByCategory(Category.MILK); - check.addPoints(points*2); - }} -public class Discount implements Reward { - @Override - public void apply(Check check){ - Double points = check.getPointsForBrand(Brand.VOLOSHKOVE_POLE)*0.5*10; - check.addDiscount(points.intValue()); - } - }*/ + void apply(Check check); +} \ No newline at end of file diff --git a/src/checkout/SpecificBrandOffer.java b/src/checkout/SpecificBrandOffer.java deleted file mode 100644 index 0507427..0000000 --- a/src/checkout/SpecificBrandOffer.java +++ /dev/null @@ -1,27 +0,0 @@ -package checkout; - -import java.time.LocalDate; - -public class SpecificBrandOffer extends Offer { - final Brand brand; - final double discount; - - public SpecificBrandOffer(Brand milk, int i) { - this.brand = milk; - this.discount = i/100.0; - this.expirationDate = LocalDate.of(2020, 1,1); - } - - @Override - public void apply(Check check){ - Double points = check.getPointsForBrand(this.brand)*discount*10; - check.addDiscount(points.intValue()); - } - - @Override - public boolean isOfferavAilable() { - if (this.expirationDate.isAfter(todayDate)) - return true; - else return false; - } -} diff --git a/src/checkout/TotalCost.java b/src/checkout/TotalCost.java index 82a17a4..769b28e 100644 --- a/src/checkout/TotalCost.java +++ b/src/checkout/TotalCost.java @@ -1,8 +1,17 @@ package checkout; -public class TotalCost implements Condition { +public class TotalCost implements Condition { + int totalCost; + + public TotalCost(int totalCost){ + setTotalCost(totalCost); + } @Override public boolean checkCondition(Check check) { - return (10 <= check.getTotalCost()); + return (totalCost <= check.getTotalCost()); + } + + public void setTotalCost(int totalCost) { + this.totalCost = totalCost; } } \ No newline at end of file diff --git a/test/CheckoutServiceTest.java b/test/CheckoutServiceTest.java index 5a28964..861bd79 100644 --- a/test/CheckoutServiceTest.java +++ b/test/CheckoutServiceTest.java @@ -2,6 +2,10 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -44,7 +48,6 @@ void addProduct__whenCheckIsClosed__opensNewCheck() { checkoutService.addProduct(milk_7); Check milkCheck = checkoutService.closeCheck(); assertThat(milkCheck.getTotalCost(), is(7)); - checkoutService.addProduct(bred_3); Check bredCheck = checkoutService.closeCheck(); assertThat(bredCheck.getTotalCost(), is(3)); @@ -55,123 +58,90 @@ void closeCheck__calcTotalPoints() { checkoutService.addProduct(milk_7); checkoutService.addProduct(bred_3); Check check = checkoutService.closeCheck(); - assertThat(check.getTotalPoints(), is(10)); } - @Test - void useOffer__addOfferPoints() { - checkoutService.addProduct(milk_7); - checkoutService.addProduct(bred_3); - - checkoutService.useOffer(new AnyGoodsOffer(6, 2)); - Check check = checkoutService.closeCheck(); - - assertThat(check.getTotalPoints(), is(12)); - } - - @Test - void useOffer__whenCostLessThanRequired__doNothing() { - checkoutService.addProduct(bred_3); - - checkoutService.useOffer(new AnyGoodsOffer(6, 2)); - Check check = checkoutService.closeCheck(); - - assertThat(check.getTotalPoints(), is(3)); - } - - @Test - void useOffer__factorByCategory() { - checkoutService.addProduct(milk_7); - checkoutService.addProduct(milk_7); - checkoutService.addProduct(bred_3); - - checkoutService.useOffer(new FactorByCategoryOffer(Category.MILK, 2)); - Check check = checkoutService.closeCheck(); - - assertThat(check.getTotalPoints(), is(31)); - } - - @Test - void useOffer_beforeCheckClose(){ - checkoutService.addProduct(milk_7); - checkoutService.addProduct(milk_7); - checkoutService.addProduct((bred_3)); - checkoutService.useOffer(new AnyGoodsOffer(6,2)); - checkoutService.useOffer(new FactorByCategoryOffer(Category.MILK, 2)); - Check check = checkoutService.closeCheck(); - assertThat(check.getTotalPoints(), is(33)); - assertThat(check.getTotalCost(), is(17)); - assertThat(check.getTotalCostWithDiscount(), is(17)); - } - - @Test + @Test void useOffer_whenCheckClose(){ - checkoutService.addProduct(milk_7); + checkoutService.useOffer(new Offer(new FlatReward(20), new TotalCost(10))); + checkoutService.useOffer(new Offer(new FactorRewardByCategory(2, Category.MILK), new ByCategory(Category.MILK))); checkoutService.addProduct(milk_7); checkoutService.addProduct((bred_3)); - Check check = checkoutService.closeCheckAndUseOffer(); - assertThat(check.getTotalCostWithDiscount(), is(17)); - } - - @Test - void isFactorByCategoryOfferAilable(){ - checkoutService.addProduct(milk_7); checkoutService.addProduct(milk_7); - checkoutService.addProduct((bred_3)); - Offer offer = new FactorByCategoryOffer(Category.MILK, 2); - assertThat(offer.isOfferavAilable(), is(false)); + Check check = checkoutService.closeCheck(); + assertThat(check.getTotalPoints(), is(51)); } + @Test - void isAnyGoodsOfferAvaliable(){ + void isOfferAvaliable(){ checkoutService.addProduct(milk_7); checkoutService.addProduct(milk_7); checkoutService.addProduct((bred_3)); - Offer offer = new AnyGoodsOffer(6,2); - assertThat(offer.isOfferavAilable(), is(true)); - } - - @Test - void useOffer_SpecificBrandOffer(){ - checkoutService.addProduct(milk_WithBrand); - checkoutService.addProduct(milk_WithBrand); - checkoutService.useOffer(new SpecificBrandOffer(Brand.VOLOSHKOVE_POLE, 50)); + Offer offer = new Offer(new FlatReward(20), new TotalCost(10), LocalDate.of(2018, 2, 3)); + checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); - assertThat(check.getTotalCostWithDiscount(), is(7)); + assertThat(check.getTotalPoints(), is(17)); } @Test void useOffer_Strategy_TotalCost(){ checkoutService.addProduct(milk_WithBrand); checkoutService.addProduct(milk_WithBrand); - OfferWithStrategy offer = new OfferWithStrategy(new Flat(), new TotalCost()); - checkoutService.useOfferWithStrategy(offer); + Offer offer = new Offer(new FlatReward(20), new TotalCost(10)); + checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); - assertThat(check.getTotalPoints(), is(34)); } + @Test + void useOffer_Strategy_TotalCost_Whan_Cost_Less_10(){ + checkoutService.addProduct(bred_3); + checkoutService.addProduct(bred_3); + checkoutService.addProduct(bred_3); + Offer offer = new Offer(new FlatReward(20), new TotalCost(10)); + checkoutService.useOffer(offer); + Check check = checkoutService.closeCheck(); + assertThat(check.getTotalPoints(), is(9)); + } @Test void useOffer_Strategy_ByCategory(){ checkoutService.addProduct(milk_WithBrand); checkoutService.addProduct(milk_WithBrand); - OfferWithStrategy offer = new OfferWithStrategy(new Factor(), new ByCategory()); - checkoutService.useOfferWithStrategy(offer); + Offer offer = new Offer(new FactorRewardByCategory(2, Category.MILK), new ByCategory(Category.MILK)); + checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); - assertThat(check.getTotalPoints(), is(28)); } + @Test + void useOffer_Strategy_ByCategory_Whan_Category_Else(){ + checkoutService.addProduct(bred_3); + checkoutService.addProduct(bred_3); + Offer offer = new Offer(new FactorRewardByCategory(2, Category.MILK), new ByCategory(Category.MILK)); + checkoutService.useOffer(offer); + Check check = checkoutService.closeCheck(); + assertThat(check.getTotalPoints(), is(6)); + } + @Test void useOffer_Strategy_ByBrand(){ checkoutService.addProduct(milk_WithBrand); checkoutService.addProduct(milk_WithBrand); - OfferWithStrategy offer = new OfferWithStrategy(new Discount(), new ByBrand()); - checkoutService.useOfferWithStrategy(offer); + Offer offer = new Offer(new DiscountByBrand(0.5, Brand.VOLOSHKOVE_POLE), new ByBrand(Brand.VOLOSHKOVE_POLE)); + checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); + assertThat(check.getTotalCostWithDiscount(), is(7)); + } + @Test + void useOffer_Strategy_When_No_Brand(){ + checkoutService.addProduct(bred_3); + checkoutService.addProduct(milk_7); + Offer offer = new Offer(new DiscountByBrand(0.5, Brand.VOLOSHKOVE_POLE), new ByBrand(Brand.VOLOSHKOVE_POLE)); + checkoutService.useOffer(offer); + Check check = checkoutService.closeCheck(); + assertThat(check.getTotalCostWithDiscount(), is(10)); - assertThat(check.getTotalCostWithDiscount(), is(7)); } } From cd75158f8e236e6798ba4210e0d146625ab42a59 Mon Sep 17 00:00:00 2001 From: andriikonoh Date: Wed, 6 Mar 2019 18:11:48 +0200 Subject: [PATCH 7/8] refactor --- src/checkout/FactorRewardByCategory.java | 2 +- src/checkout/Offer.java | 4 +--- test/CheckoutServiceTest.java | 4 ---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/checkout/FactorRewardByCategory.java b/src/checkout/FactorRewardByCategory.java index 9d7ceec..b6580a3 100644 --- a/src/checkout/FactorRewardByCategory.java +++ b/src/checkout/FactorRewardByCategory.java @@ -11,7 +11,7 @@ public FactorRewardByCategory(int factor, Category category){ @Override public void apply(Check check){ int points = check.getCostByCategory(category); - check.addPoints(points*(factor-1)); + check.addPoints(points * (factor-1)); } public void setFactor(int factor){ diff --git a/src/checkout/Offer.java b/src/checkout/Offer.java index 6707fdc..43b9c19 100644 --- a/src/checkout/Offer.java +++ b/src/checkout/Offer.java @@ -14,9 +14,7 @@ public Offer(Reward reward , Condition condition, LocalDate expirationDate){ } public Offer(Reward reward , Condition condition){ - this.condition = condition; - this.reward = reward; - this.expirationDate = LocalDate.of(2019, 3, 7); + this(reward, condition, LocalDate.of(2019, 3, 7)); } public void apply(Check check){ diff --git a/test/CheckoutServiceTest.java b/test/CheckoutServiceTest.java index 861bd79..69dd1fa 100644 --- a/test/CheckoutServiceTest.java +++ b/test/CheckoutServiceTest.java @@ -1,11 +1,7 @@ import checkout.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; From 8d3712e9c504a901f1bfb171142593294cd58774 Mon Sep 17 00:00:00 2001 From: andriikonoh Date: Thu, 7 Mar 2019 10:22:34 +0200 Subject: [PATCH 8/8] refactor(all project and test) fix code formatting fix spelling make test names more descriptive cleanup production code from hard-coded dates --- src/checkout/ByBrand.java | 3 +- src/checkout/ByCategory.java | 9 ++-- src/checkout/Check.java | 7 ++- src/checkout/CheckoutService.java | 16 ++----- src/checkout/Condition.java | 1 - src/checkout/DiscountByBrand.java | 5 +- src/checkout/FactorRewardByCategory.java | 7 +-- src/checkout/FlatReward.java | 5 +- src/checkout/Offer.java | 14 ++---- src/checkout/Reward.java | 2 +- src/checkout/TotalCost.java | 3 +- test/CheckoutServiceTest.java | 61 +++++++++++++----------- 12 files changed, 67 insertions(+), 66 deletions(-) diff --git a/src/checkout/ByBrand.java b/src/checkout/ByBrand.java index 09b9536..3a5bb52 100644 --- a/src/checkout/ByBrand.java +++ b/src/checkout/ByBrand.java @@ -3,9 +3,10 @@ public class ByBrand implements Condition { Brand brand; - public ByBrand(Brand brand){ + public ByBrand(Brand brand) { setBrand(brand); } + @Override public boolean checkCondition(Check check) { boolean marker = false; diff --git a/src/checkout/ByCategory.java b/src/checkout/ByCategory.java index 9d09499..c773fa7 100644 --- a/src/checkout/ByCategory.java +++ b/src/checkout/ByCategory.java @@ -1,15 +1,16 @@ package checkout; -public class ByCategory implements Condition{ +public class ByCategory implements Condition { Category category; - public ByCategory(Category category){ + public ByCategory(Category category) { setCategory(category); } + @Override - public boolean checkCondition(Check check){ + public boolean checkCondition(Check check) { boolean marker = false; - for(Product p : check.getProducts()){ + for(Product p : check.getProducts()) { if (p.category == category) marker = true; } return marker; diff --git a/src/checkout/Check.java b/src/checkout/Check.java index 3baf4bd..b6990b7 100644 --- a/src/checkout/Check.java +++ b/src/checkout/Check.java @@ -1,7 +1,6 @@ package checkout; import java.time.LocalDate; -import java.time.chrono.ChronoLocalDate; import java.util.ArrayList; import java.util.List; @@ -9,7 +8,7 @@ public class Check { private List products = new ArrayList<>(); private int points = 0; private int discount = 0; - private LocalDate todayDate = LocalDate.of(2019, 3, 1); + private static LocalDate todayDate = LocalDate.now(); public int getTotalCost() { int totalCost = 0; @@ -19,7 +18,7 @@ public int getTotalCost() { return totalCost; } - public int getTotalCostWithDiscount(){ + public int getTotalCostWithDiscount() { return getTotalCost() - discount/10; } @@ -57,7 +56,7 @@ public List getProducts() { return products; } - public LocalDate getTodayDate() { + public static LocalDate getTodayDate() { return todayDate; } } diff --git a/src/checkout/CheckoutService.java b/src/checkout/CheckoutService.java index e01887b..c525a22 100644 --- a/src/checkout/CheckoutService.java +++ b/src/checkout/CheckoutService.java @@ -9,6 +9,7 @@ public class CheckoutService { private List offers = new ArrayList<>(); public void openCheck() { + offers = new ArrayList<>(); check = new Check(); } @@ -26,20 +27,13 @@ public Check closeCheck() { return closedCheck; } - private void useAllOffer(){ - if(this.offers.size()!=0) this.offers.forEach(offer ->{ - if(isOfferavAilable(offer)) offer.apply(check); - }); + private void useAllOffer() { + if(this.offers.size()!=0) this.offers.forEach(offer -> + offer.apply(check)); } - public void useOffer(Offer offer){ + public void useOffer(Offer offer) { if(check != null) this.offers.add(offer); - - } - public boolean isOfferavAilable(Offer ofer){ - if (ofer.getExpirationDate().isAfter(check.getTodayDate())) - return true; - else return false; } } diff --git a/src/checkout/Condition.java b/src/checkout/Condition.java index 93ba05e..a47c266 100644 --- a/src/checkout/Condition.java +++ b/src/checkout/Condition.java @@ -3,4 +3,3 @@ public interface Condition { boolean checkCondition(Check check); } - diff --git a/src/checkout/DiscountByBrand.java b/src/checkout/DiscountByBrand.java index 5926dff..d6a686a 100644 --- a/src/checkout/DiscountByBrand.java +++ b/src/checkout/DiscountByBrand.java @@ -4,12 +4,13 @@ public class DiscountByBrand implements Reward { private double discount; private Brand brand; - public DiscountByBrand(double discount, Brand brand){ + public DiscountByBrand(double discount, Brand brand) { setBrand(brand); setDiscount(discount); } + @Override - public void apply(Check check){ + public void apply(Check check) { Double points = check.getPointsForBrand(brand) * discount * 10; check.addDiscount(points.intValue()); } diff --git a/src/checkout/FactorRewardByCategory.java b/src/checkout/FactorRewardByCategory.java index b6580a3..7a5b91e 100644 --- a/src/checkout/FactorRewardByCategory.java +++ b/src/checkout/FactorRewardByCategory.java @@ -4,17 +4,18 @@ public class FactorRewardByCategory implements Reward { private int factor; Category category; - public FactorRewardByCategory(int factor, Category category){ + public FactorRewardByCategory(int factor, Category category) { setCategory(category); setFactor(factor); } + @Override - public void apply(Check check){ + public void apply(Check check) { int points = check.getCostByCategory(category); check.addPoints(points * (factor-1)); } - public void setFactor(int factor){ + public void setFactor(int factor) { this.factor = factor; } diff --git a/src/checkout/FlatReward.java b/src/checkout/FlatReward.java index 0448e6e..617facf 100644 --- a/src/checkout/FlatReward.java +++ b/src/checkout/FlatReward.java @@ -3,9 +3,10 @@ public class FlatReward implements Reward { private int reward; - public FlatReward (int reward){ + public FlatReward (int reward) { setReward(reward); } + @Override public void apply(Check check) { check.addPoints(reward); @@ -14,4 +15,4 @@ public void apply(Check check) { public void setReward(int reward) { this.reward = reward; } -} \ No newline at end of file +} diff --git a/src/checkout/Offer.java b/src/checkout/Offer.java index 43b9c19..506dbdf 100644 --- a/src/checkout/Offer.java +++ b/src/checkout/Offer.java @@ -7,21 +7,17 @@ public class Offer { Condition condition; private LocalDate expirationDate; - public Offer(Reward reward , Condition condition, LocalDate expirationDate){ + public Offer(Reward reward , Condition condition, LocalDate expirationDate) { this.condition = condition; this.reward = reward; this.expirationDate = expirationDate; } - public Offer(Reward reward , Condition condition){ - this(reward, condition, LocalDate.of(2019, 3, 7)); + public void apply(Check check) { + if(condition.checkCondition(check) && isOfferAvailable(check.getTodayDate())) reward.apply(check); } - public void apply(Check check){ - if(condition.checkCondition(check)) reward.apply(check); - } - - public LocalDate getExpirationDate() { - return expirationDate; + public boolean isOfferAvailable(LocalDate todayDate) { + return (expirationDate.isAfter(todayDate)); } } diff --git a/src/checkout/Reward.java b/src/checkout/Reward.java index 75e696d..2e885a0 100644 --- a/src/checkout/Reward.java +++ b/src/checkout/Reward.java @@ -3,4 +3,4 @@ public interface Reward { void apply(Check check); -} \ No newline at end of file +} diff --git a/src/checkout/TotalCost.java b/src/checkout/TotalCost.java index 769b28e..659eed5 100644 --- a/src/checkout/TotalCost.java +++ b/src/checkout/TotalCost.java @@ -6,6 +6,7 @@ public class TotalCost implements Condition { public TotalCost(int totalCost){ setTotalCost(totalCost); } + @Override public boolean checkCondition(Check check) { return (totalCost <= check.getTotalCost()); @@ -14,4 +15,4 @@ public boolean checkCondition(Check check) { public void setTotalCost(int totalCost) { this.totalCost = totalCost; } -} \ No newline at end of file +} diff --git a/test/CheckoutServiceTest.java b/test/CheckoutServiceTest.java index 69dd1fa..d343b01 100644 --- a/test/CheckoutServiceTest.java +++ b/test/CheckoutServiceTest.java @@ -10,7 +10,7 @@ public class CheckoutServiceTest { private Product milk_7; private CheckoutService checkoutService; private Product bred_3; - private Product milk_WithBrand; + private Product milk_7_WithBrand; @BeforeEach void setUp() { @@ -19,7 +19,7 @@ void setUp() { milk_7 = new Product(7, "Milk", Category.MILK); bred_3 = new Product(3, "Bred"); - milk_WithBrand = new Product(7, "Milk", Category.MILK, Brand.VOLOSHKOVE_POLE); + milk_7_WithBrand = new Product(7, "Milk", Category.MILK, Brand.VOLOSHKOVE_POLE); } @Test @@ -57,10 +57,11 @@ void closeCheck__calcTotalPoints() { assertThat(check.getTotalPoints(), is(10)); } - @Test - void useOffer_whenCheckClose(){ - checkoutService.useOffer(new Offer(new FlatReward(20), new TotalCost(10))); - checkoutService.useOffer(new Offer(new FactorRewardByCategory(2, Category.MILK), new ByCategory(Category.MILK))); + @Test + void useOffer__whenCheckClose() { + checkoutService.useOffer(new Offer(new FlatReward(20), new TotalCost(10), LocalDate.now().plusDays(1))); + checkoutService.useOffer(new Offer(new FactorRewardByCategory(2, Category.MILK), + new ByCategory(Category.MILK), LocalDate.now().plusDays(1))); checkoutService.addProduct(milk_7); checkoutService.addProduct((bred_3)); checkoutService.addProduct(milk_7); @@ -68,73 +69,79 @@ void useOffer_whenCheckClose(){ assertThat(check.getTotalPoints(), is(51)); } - @Test - void isOfferAvaliable(){ + void isOfferAvailable__ifTimeForOffersEnded__doNothing() { checkoutService.addProduct(milk_7); checkoutService.addProduct(milk_7); checkoutService.addProduct((bred_3)); - Offer offer = new Offer(new FlatReward(20), new TotalCost(10), LocalDate.of(2018, 2, 3)); + Offer offer = new Offer(new FlatReward(20), new TotalCost(10), + LocalDate.now().minusDays(1)); checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(17)); } @Test - void useOffer_Strategy_TotalCost(){ - checkoutService.addProduct(milk_WithBrand); - checkoutService.addProduct(milk_WithBrand); - Offer offer = new Offer(new FlatReward(20), new TotalCost(10)); + void useOffer__addOfferPoints() { + checkoutService.addProduct(milk_7_WithBrand); + checkoutService.addProduct(milk_7_WithBrand); + Offer offer = new Offer(new FlatReward(20), new TotalCost(10), + LocalDate.now().plusDays(1)); checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(34)); } @Test - void useOffer_Strategy_TotalCost_Whan_Cost_Less_10(){ + void useOffer__whenCostLessThanRequired__doNothing() { checkoutService.addProduct(bred_3); checkoutService.addProduct(bred_3); checkoutService.addProduct(bred_3); - Offer offer = new Offer(new FlatReward(20), new TotalCost(10)); + Offer offer = new Offer(new FlatReward(20), new TotalCost(10), + LocalDate.now().plusDays(1)); checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(9)); } @Test - void useOffer_Strategy_ByCategory(){ - checkoutService.addProduct(milk_WithBrand); - checkoutService.addProduct(milk_WithBrand); - Offer offer = new Offer(new FactorRewardByCategory(2, Category.MILK), new ByCategory(Category.MILK)); + void useOffer__factorByCategory() { + checkoutService.addProduct(milk_7_WithBrand); + checkoutService.addProduct(milk_7_WithBrand); + Offer offer = new Offer(new FactorRewardByCategory(2, Category.MILK), + new ByCategory(Category.MILK), LocalDate.now().plusDays(1)); checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(28)); } @Test - void useOffer_Strategy_ByCategory_Whan_Category_Else(){ + void useOffer__whenCategoryAbsent__doNothing() { checkoutService.addProduct(bred_3); checkoutService.addProduct(bred_3); - Offer offer = new Offer(new FactorRewardByCategory(2, Category.MILK), new ByCategory(Category.MILK)); + Offer offer = new Offer(new FactorRewardByCategory(2, Category.MILK), + new ByCategory(Category.MILK), LocalDate.now().plusDays(1)); checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); assertThat(check.getTotalPoints(), is(6)); } @Test - void useOffer_Strategy_ByBrand(){ - checkoutService.addProduct(milk_WithBrand); - checkoutService.addProduct(milk_WithBrand); - Offer offer = new Offer(new DiscountByBrand(0.5, Brand.VOLOSHKOVE_POLE), new ByBrand(Brand.VOLOSHKOVE_POLE)); + void useOffer__discountByBrand() { + checkoutService.addProduct(milk_7_WithBrand); + checkoutService.addProduct(milk_7_WithBrand); + Offer offer = new Offer(new DiscountByBrand(0.5, Brand.VOLOSHKOVE_POLE), + new ByBrand(Brand.VOLOSHKOVE_POLE), LocalDate.now().plusDays(1)); checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); assertThat(check.getTotalCostWithDiscount(), is(7)); } @Test - void useOffer_Strategy_When_No_Brand(){ + void useOffer__whenBrandAbsent__doNothing() { checkoutService.addProduct(bred_3); checkoutService.addProduct(milk_7); - Offer offer = new Offer(new DiscountByBrand(0.5, Brand.VOLOSHKOVE_POLE), new ByBrand(Brand.VOLOSHKOVE_POLE)); + Offer offer = new Offer(new DiscountByBrand(0.5, Brand.VOLOSHKOVE_POLE), + new ByBrand(Brand.VOLOSHKOVE_POLE), LocalDate.now().plusDays(1)); checkoutService.useOffer(offer); Check check = checkoutService.closeCheck(); assertThat(check.getTotalCostWithDiscount(), is(10));