diff --git a/.gitignore b/.gitignore
index 32858aa..e14e670 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,7 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+
+# intelliJ stuff
+*.iml
+.idea/
diff --git a/pom.xml b/pom.xml
new file mode 100755
index 0000000..317ed20
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ de.dj_steam.backtothecheckout
+ supermarket
+ 1.0-SNAPSHOT
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.2
+
+ 1.7
+ 1.7
+
+
+
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/dj_steam/CheckOut.java b/src/main/java/de/dj_steam/CheckOut.java
new file mode 100755
index 0000000..f32f428
--- /dev/null
+++ b/src/main/java/de/dj_steam/CheckOut.java
@@ -0,0 +1,55 @@
+package de.dj_steam;
+
+import de.dj_steam.strategy.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by steam on 24.02.15.
+ */
+public class CheckOut {
+
+ private String bucket = "";
+ private List strategies;
+
+ public CheckOut(){
+ initPriceStrategies();
+ }
+
+ /**
+ * use this method for extend pricing strategy rules
+ */
+ private void initPriceStrategies() {
+ strategies = new ArrayList<>();
+ strategies.add(new AStrategy());
+ strategies.add(new BStrategy());
+ strategies.add(new CStrategy());
+ strategies.add(new DStrategy());
+ }
+
+ public int scan(char product){
+ putIntoBucket(product);
+ return updateTotalPrice();
+ }
+
+ public int calculatePriceForBucket(String products){
+ int total = 0;
+ this.bucket = products;
+ PriceContext context = new PriceContext();
+
+ for(PricingStrategy strategy : strategies){
+ context.setStrategy(strategy, bucket);
+ total += context.calculatePriceForProduct();
+ }
+ return total;
+ }
+
+ private void putIntoBucket(char product){
+ bucket += product;
+ }
+
+ private int updateTotalPrice(){
+ return calculatePriceForBucket(bucket);
+ }
+}
diff --git a/src/main/java/de/dj_steam/PriceContext.java b/src/main/java/de/dj_steam/PriceContext.java
new file mode 100755
index 0000000..d115a56
--- /dev/null
+++ b/src/main/java/de/dj_steam/PriceContext.java
@@ -0,0 +1,23 @@
+package de.dj_steam;
+
+import de.dj_steam.strategy.PricingStrategy;
+
+/**
+ * Created by steam on 24.02.15.
+ */
+public class PriceContext {
+ private PricingStrategy strategy = null;
+ private String bucket = "";
+
+ public void setStrategy(final PricingStrategy strategy, String bucket){
+ this.strategy = strategy;
+ this.bucket = bucket;
+ }
+
+ public int calculatePriceForProduct() {
+ if (strategy != null){
+ return strategy.calculatePrice(bucket);
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/de/dj_steam/strategy/AStrategy.java b/src/main/java/de/dj_steam/strategy/AStrategy.java
new file mode 100755
index 0000000..d50f2ed
--- /dev/null
+++ b/src/main/java/de/dj_steam/strategy/AStrategy.java
@@ -0,0 +1,21 @@
+package de.dj_steam.strategy;
+
+/**
+ * Created by steam on 24.02.15.
+ */
+public class AStrategy extends AbstractPricingStrategy implements PricingStrategy {
+
+ private static final char PRODUCT_ID = 'A';
+ private static final int PRICE = 50;
+ private static final int PRICE_THRESHOLD = 3;
+ private static final int DISCOUNT = 130;
+
+
+ @Override
+ public int calculatePrice(String products) {
+ int productsNumber = calculateNumberOfProductsForType(products, PRODUCT_ID);
+ return calculatePriceForAllProducts(productsNumber, PRICE, PRICE_THRESHOLD, DISCOUNT);
+ }
+}
+
+
diff --git a/src/main/java/de/dj_steam/strategy/AbstractPricingStrategy.java b/src/main/java/de/dj_steam/strategy/AbstractPricingStrategy.java
new file mode 100755
index 0000000..af2e59c
--- /dev/null
+++ b/src/main/java/de/dj_steam/strategy/AbstractPricingStrategy.java
@@ -0,0 +1,27 @@
+package de.dj_steam.strategy;
+
+/**
+ * Created by steam on 24.02.15.
+ */
+public class AbstractPricingStrategy {
+
+ protected int calculateNumberOfProductsForType(String products, char product) {
+ int numberOfProducts = 0;
+ for (int i = 0; i < products.length(); i++) {
+ if (products.charAt(i) == product) {
+ numberOfProducts++;
+ }
+ }
+ return numberOfProducts;
+ }
+
+ protected int calculatePriceForAllProducts(int numberOfProducts, int price, int priceThreshold, int discount) {
+ if (priceThreshold > 0) {
+ int remainder = numberOfProducts % priceThreshold;
+ int triples = numberOfProducts / priceThreshold;
+ return (triples * discount) + (remainder * price);
+ } else {
+ return numberOfProducts * price;
+ }
+ }
+}
diff --git a/src/main/java/de/dj_steam/strategy/BStrategy.java b/src/main/java/de/dj_steam/strategy/BStrategy.java
new file mode 100755
index 0000000..7cfd0bc
--- /dev/null
+++ b/src/main/java/de/dj_steam/strategy/BStrategy.java
@@ -0,0 +1,18 @@
+package de.dj_steam.strategy;
+
+/**
+ * Created by steam on 24.02.15.
+ */
+public class BStrategy extends AbstractPricingStrategy implements PricingStrategy {
+
+ private static final char PRODUCT_ID = 'B';
+ private static final int PRICE = 30;
+ private static final int PRICE_THRESHOLD = 2;
+ private static final int DISCOUNT = 45;
+
+ @Override
+ public int calculatePrice(String products) {
+ int productsNumber = calculateNumberOfProductsForType(products, PRODUCT_ID);
+ return calculatePriceForAllProducts(productsNumber, PRICE, PRICE_THRESHOLD, DISCOUNT);
+ }
+}
diff --git a/src/main/java/de/dj_steam/strategy/CStrategy.java b/src/main/java/de/dj_steam/strategy/CStrategy.java
new file mode 100755
index 0000000..a602eeb
--- /dev/null
+++ b/src/main/java/de/dj_steam/strategy/CStrategy.java
@@ -0,0 +1,19 @@
+package de.dj_steam.strategy;
+
+/**
+ * Created by steam on 24.02.15.
+ */
+public class CStrategy extends AbstractPricingStrategy implements PricingStrategy {
+
+ private static final char PRODUCT_ID = 'C';
+ private static final int PRICE = 20;
+ private static final int PRICE_THRESHOLD = 0;
+ private static final int DISCOUNT = 0;
+
+
+ @Override
+ public int calculatePrice(String products) {
+ int productsNumber = calculateNumberOfProductsForType(products, PRODUCT_ID);
+ return calculatePriceForAllProducts(productsNumber, PRICE, PRICE_THRESHOLD, DISCOUNT);
+ }
+}
diff --git a/src/main/java/de/dj_steam/strategy/DStrategy.java b/src/main/java/de/dj_steam/strategy/DStrategy.java
new file mode 100755
index 0000000..a7cb558
--- /dev/null
+++ b/src/main/java/de/dj_steam/strategy/DStrategy.java
@@ -0,0 +1,18 @@
+package de.dj_steam.strategy;
+
+/**
+ * Created by steam on 24.02.15.
+ */
+public class DStrategy extends AbstractPricingStrategy implements PricingStrategy {
+
+ private static final char PRODUCT_ID = 'D';
+ private static final int PRICE = 15;
+ private static final int PRICE_THRESHOLD = 0;
+ private static final int DISCOUNT = 0;
+
+ @Override
+ public int calculatePrice(String products) {
+ int productsNumber = calculateNumberOfProductsForType(products, PRODUCT_ID);
+ return calculatePriceForAllProducts(productsNumber, PRICE, PRICE_THRESHOLD, DISCOUNT);
+ }
+}
diff --git a/src/main/java/de/dj_steam/strategy/PricingStrategy.java b/src/main/java/de/dj_steam/strategy/PricingStrategy.java
new file mode 100755
index 0000000..a8848ca
--- /dev/null
+++ b/src/main/java/de/dj_steam/strategy/PricingStrategy.java
@@ -0,0 +1,8 @@
+package de.dj_steam.strategy;
+
+/**
+ * Created by steam on 24.02.15.
+ */
+public interface PricingStrategy {
+ public int calculatePrice(String products);
+}
diff --git a/src/test/java/de/dj_steam/CheckOutTest.java b/src/test/java/de/dj_steam/CheckOutTest.java
new file mode 100755
index 0000000..3d93376
--- /dev/null
+++ b/src/test/java/de/dj_steam/CheckOutTest.java
@@ -0,0 +1,39 @@
+package de.dj_steam;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class CheckOutTest {
+
+ @Test
+ public void testScan() throws Exception {
+ CheckOut testPrice = new CheckOut();
+ assertEquals(50, testPrice.scan('A'));
+ assertEquals(80, testPrice.scan('B'));
+ assertEquals(130, testPrice.scan('A'));
+ assertEquals(160, testPrice.scan('A'));
+ assertEquals(175, testPrice.scan('B'));
+ }
+
+ @Test
+ public void testTotals() {
+ CheckOut testPrice = new CheckOut();
+ assertEquals(0, testPrice.calculatePriceForBucket("") );
+ assertEquals(50, testPrice.calculatePriceForBucket("A"));
+ assertEquals(80, testPrice.calculatePriceForBucket("AB"));
+ assertEquals(115, testPrice.calculatePriceForBucket("CDBA"));
+
+ assertEquals(100, testPrice.calculatePriceForBucket("AA"));
+ assertEquals(130, testPrice.calculatePriceForBucket("AAA"));
+ assertEquals(180, testPrice.calculatePriceForBucket("AAAA"));
+ assertEquals(230, testPrice.calculatePriceForBucket("AAAAA"));
+ assertEquals(260, testPrice.calculatePriceForBucket("AAAAAA"));
+
+ assertEquals(160, testPrice.calculatePriceForBucket("AAAB"));
+ assertEquals(175, testPrice.calculatePriceForBucket("AAABB"));
+ assertEquals(190, testPrice.calculatePriceForBucket("AAABBD"));
+ assertEquals(190, testPrice.calculatePriceForBucket("DABABA"));
+ }
+}
\ No newline at end of file