Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>22</source>
<target>22</target>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
Expand Down
27 changes: 27 additions & 0 deletions java/src/main/java/dojo/supermarket/BaseReceiptPrinter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dojo.supermarket;

import dojo.supermarket.model.*;

import java.util.Locale;

public abstract class BaseReceiptPrinter {

public abstract String printReceipt(Receipt receipt);

protected abstract String formatReceiptItem(ReceiptItem item);

protected abstract String formatDiscount(Discount discount);

protected abstract String formatTotal(Receipt receipt);

// Shared data formatting methods - keep these identical across implementations
protected static String presentPrice(double price) {
return String.format(Locale.UK, "%.2f", price);
}

protected static String presentQuantity(ReceiptItem item) {
return ProductUnit.EACH.equals(item.getProduct().getUnit())
? String.format("%d", (int)item.getQuantity())
: String.format(Locale.UK, "%.3f", item.getQuantity());
}
}
53 changes: 53 additions & 0 deletions java/src/main/java/dojo/supermarket/HtmlReceiptDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package dojo.supermarket;

import dojo.supermarket.model.*;

import java.io.FileWriter;
import java.io.IOException;

public class HtmlReceiptDemo {
public static void main(String[] args) throws IOException {
// Set up sample data with multiple items and discounts
SupermarketCatalog catalog = new ReceiptDemo.FakeCatalog();

Product apples = new Product("apples", ProductUnit.KILO);
Product toothbrush = new Product("toothbrush", ProductUnit.EACH);
Product toothpaste = new Product("toothpaste", ProductUnit.EACH);
Product cherryTomatoes = new Product("cherry tomatoes", ProductUnit.EACH);

catalog.addProduct(apples, 1.99);
catalog.addProduct(toothbrush, 0.99);
catalog.addProduct(toothpaste, 1.79);
catalog.addProduct(cherryTomatoes, 0.69);

Teller teller = new Teller(catalog);
teller.addSpecialOffer(SpecialOfferType.TEN_PERCENT_DISCOUNT, toothbrush, 10.0);
teller.addSpecialOffer(SpecialOfferType.TWO_FOR_AMOUNT, cherryTomatoes, 0.99);

ShoppingCart cart = new ShoppingCart();
cart.addItemQuantity(apples, 2.5);
cart.addItemQuantity(toothbrush, 3);
cart.addItemQuantity(toothpaste, 2);
cart.addItemQuantity(cherryTomatoes, 2); // Buy 2 for 0.99 deal

Receipt receipt = teller.checksOutArticlesFrom(cart);

// Generate HTML receipt
HtmlReceiptPrinter htmlPrinter = new HtmlReceiptPrinter();
String htmlReceipt = htmlPrinter.printReceipt(receipt);

// Write to file
try (FileWriter writer = new FileWriter("/tmp/sample_receipt.html")) {
writer.write(htmlReceipt);
System.out.println("HTML receipt written to /tmp/sample_receipt.html");
}

// Also show comparison
ReceiptPrinter textPrinter = new ReceiptPrinter();
System.out.println("\n=== TEXT RECEIPT ===");
System.out.println(textPrinter.printReceipt(receipt));

System.out.println("\n=== HTML RECEIPT ===");
System.out.println(htmlReceipt);
}
}
82 changes: 82 additions & 0 deletions java/src/main/java/dojo/supermarket/HtmlReceiptPrinter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package dojo.supermarket;

import dojo.supermarket.model.*;

public class HtmlReceiptPrinter extends BaseReceiptPrinter {

@Override
public String printReceipt(Receipt receipt) {
StringBuilder result = new StringBuilder();

result.append("<html>\n");
result.append("<body>\n");
result.append("<h1>Receipt</h1>\n");
result.append("<table>\n");

for (ReceiptItem item : receipt.getItems()) {
result.append(formatReceiptItem(item));
}

for (Discount discount : receipt.getDiscounts()) {
result.append(formatDiscount(discount));
}

result.append(formatTotal(receipt));
result.append("</table>\n");
result.append("</body>\n");
result.append("</html>\n");

return result.toString();
}

@Override
protected String formatReceiptItem(ReceiptItem item) {
StringBuilder result = new StringBuilder();
String totalPricePresentation = presentPrice(item.getTotalPrice());
String name = item.getProduct().getName();

result.append("<tr>");
result.append("<td>").append(name).append("</td>");
result.append("<td>").append(totalPricePresentation).append("</td>");
result.append("</tr>\n");

if (item.getQuantity() != 1) {
result.append("<tr>");
result.append("<td colspan='2'>");
result.append(" ").append(presentPrice(item.getPrice()));
result.append(" * ").append(presentQuantity(item));
result.append("</td>");
result.append("</tr>\n");
}

return result.toString();
}

@Override
protected String formatDiscount(Discount discount) {
String name = discount.getDescription() + "(" + discount.getProduct().getName() + ")";
String value = presentPrice(discount.getDiscountAmount());

StringBuilder result = new StringBuilder();
result.append("<tr>");
result.append("<td>").append(name).append("</td>");
result.append("<td>").append(value).append("</td>");
result.append("</tr>\n");

return result.toString();
}

@Override
protected String formatTotal(Receipt receipt) {
String name = "Total: ";
String value = presentPrice(receipt.getTotalPrice());

StringBuilder result = new StringBuilder();
result.append("<tr>");
result.append("<td><strong>").append(name).append("</strong></td>");
result.append("<td><strong>").append(value).append("</strong></td>");
result.append("</tr>\n");

return result.toString();
}
}
54 changes: 54 additions & 0 deletions java/src/main/java/dojo/supermarket/ReceiptDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package dojo.supermarket;

import dojo.supermarket.model.*;

public class ReceiptDemo {

static class FakeCatalog implements SupermarketCatalog {
private java.util.Map<String, Product> products = new java.util.HashMap<>();
private java.util.Map<String, Double> prices = new java.util.HashMap<>();

@Override
public void addProduct(Product product, double price) {
this.products.put(product.getName(), product);
this.prices.put(product.getName(), price);
}

@Override
public double getUnitPrice(Product p) {
return this.prices.get(p.getName());
}
}

public static void main(String[] args) {
// Set up sample data
SupermarketCatalog catalog = new FakeCatalog();
Product apples = new Product("apples", ProductUnit.KILO);
Product toothbrush = new Product("toothbrush", ProductUnit.EACH);
Product toothpaste = new Product("toothpaste", ProductUnit.EACH);

catalog.addProduct(apples, 1.99);
catalog.addProduct(toothbrush, 0.99);
catalog.addProduct(toothpaste, 1.79);

Teller teller = new Teller(catalog);
teller.addSpecialOffer(SpecialOfferType.TEN_PERCENT_DISCOUNT, toothbrush, 10.0);

ShoppingCart cart = new ShoppingCart();
cart.addItemQuantity(apples, 2.5);
cart.addItemQuantity(toothbrush, 2);
cart.addItemQuantity(toothpaste, 1);

Receipt receipt = teller.checksOutArticlesFrom(cart);

// Print text receipt
ReceiptPrinter textPrinter = new ReceiptPrinter();
System.out.println("=== TEXT RECEIPT ===");
System.out.println(textPrinter.printReceipt(receipt));

// Print HTML receipt
HtmlReceiptPrinter htmlPrinter = new HtmlReceiptPrinter();
System.out.println("\n=== HTML RECEIPT ===");
System.out.println(htmlPrinter.printReceipt(receipt));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import java.util.Locale;

public class ReceiptPrinter {
public class ReceiptPrinter extends BaseReceiptPrinter {

private final int columns;

Expand All @@ -16,22 +16,38 @@ public ReceiptPrinter(int columns) {
this.columns = columns;
}

@Override
public String printReceipt(Receipt receipt) {
StringBuilder result = new StringBuilder();
for (ReceiptItem item : receipt.getItems()) {
String receiptItem = presentReceiptItem(item);
String receiptItem = formatReceiptItem(item);
result.append(receiptItem);
}
for (Discount discount : receipt.getDiscounts()) {
String discountPresentation = presentDiscount(discount);
String discountPresentation = formatDiscount(discount);
result.append(discountPresentation);
}

result.append("\n");
result.append(presentTotal(receipt));
result.append(formatTotal(receipt));
return result.toString();
}

@Override
protected String formatReceiptItem(ReceiptItem item) {
return presentReceiptItem(item);
}

@Override
protected String formatDiscount(Discount discount) {
return presentDiscount(discount);
}

@Override
protected String formatTotal(Receipt receipt) {
return presentTotal(receipt);
}

private String presentReceiptItem(ReceiptItem item) {
String totalPricePresentation = presentPrice(item.getTotalPrice());
String name = item.getProduct().getName();
Expand Down Expand Up @@ -69,13 +85,11 @@ private String formatLineWithWhitespace(String name, String value) {
return line.toString();
}

private static String presentPrice(double price) {
return String.format(Locale.UK, "%.2f", price);
protected static String presentPrice(double price) {
return BaseReceiptPrinter.presentPrice(price);
}

private static String presentQuantity(ReceiptItem item) {
return ProductUnit.EACH.equals(item.getProduct().getUnit())
? String.format("%d", (int)item.getQuantity())
: String.format(Locale.UK, "%.3f", item.getQuantity());
protected static String presentQuantity(ReceiptItem item) {
return BaseReceiptPrinter.presentQuantity(item);
}
}
Loading