summaryrefslogtreecommitdiff
path: root/oop
diff options
context:
space:
mode:
Diffstat (limited to 'oop')
-rw-r--r--oop/11-point-of-sale/.gitignore1
-rw-r--r--oop/11-point-of-sale/.mvn/jvm.config0
-rw-r--r--oop/11-point-of-sale/.mvn/maven.config0
-rw-r--r--oop/11-point-of-sale/.vscode/settings.json3
-rw-r--r--oop/11-point-of-sale/README11
-rw-r--r--oop/11-point-of-sale/docs/01-requirements.txt7
-rw-r--r--oop/11-point-of-sale/docs/02-domain-model.uxf16
-rw-r--r--oop/11-point-of-sale/docs/03-design.uxf71
-rw-r--r--oop/11-point-of-sale/pom.xml103
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/App.java24
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/BillManager.java16
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/BillManagerImpl.java52
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ItemManager.java12
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ItemManagerImpl.java47
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/PointOfSale.java15
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/PointOfSaleImpl.java49
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Bill.java79
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Cashier.java31
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Item.java43
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/LineItem.java53
-rw-r--r--oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ui/TextUI.java102
-rw-r--r--oop/11-point-of-sale/src/test/java/lk/ac/pdn/ceit/pos/AppTest.java19
22 files changed, 754 insertions, 0 deletions
diff --git a/oop/11-point-of-sale/.gitignore b/oop/11-point-of-sale/.gitignore
new file mode 100644
index 0000000..eb5a316
--- /dev/null
+++ b/oop/11-point-of-sale/.gitignore
@@ -0,0 +1 @@
+target
diff --git a/oop/11-point-of-sale/.mvn/jvm.config b/oop/11-point-of-sale/.mvn/jvm.config
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/oop/11-point-of-sale/.mvn/jvm.config
diff --git a/oop/11-point-of-sale/.mvn/maven.config b/oop/11-point-of-sale/.mvn/maven.config
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/oop/11-point-of-sale/.mvn/maven.config
diff --git a/oop/11-point-of-sale/.vscode/settings.json b/oop/11-point-of-sale/.vscode/settings.json
new file mode 100644
index 0000000..c5f3f6b
--- /dev/null
+++ b/oop/11-point-of-sale/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "interactive"
+} \ No newline at end of file
diff --git a/oop/11-point-of-sale/README b/oop/11-point-of-sale/README
new file mode 100644
index 0000000..1fd7424
--- /dev/null
+++ b/oop/11-point-of-sale/README
@@ -0,0 +1,11 @@
+This sample Maven project shows how object oriented software is developed.
+
+The docs directory contains .uxf files that can be opened with UMLet diagram editor. UMLet is available as a Visual Studio Code extension. It is also available as a standalone application.
+
+To build the project, run:
+
+ mvn clean package
+
+To run the application packaged earlier, execute:
+
+ java -jar target/point-of-sale-1.0-SNAPSHOT.jar \ No newline at end of file
diff --git a/oop/11-point-of-sale/docs/01-requirements.txt b/oop/11-point-of-sale/docs/01-requirements.txt
new file mode 100644
index 0000000..4f99432
--- /dev/null
+++ b/oop/11-point-of-sale/docs/01-requirements.txt
@@ -0,0 +1,7 @@
+A POS system needs to be created. A customer comes to the cashier and the
+cashier takes items from the cart and enters the item ids into the system. For
+each item type, the system asks the number of items to be purchased. The
+system creates a bill and adds line items to it. At the end, the total is
+calculated and the tax should be added. The system should ask to enter the
+amount of money the customer would give. The system should print the entire
+bill with the balance to be given back to the customer.
diff --git a/oop/11-point-of-sale/docs/02-domain-model.uxf b/oop/11-point-of-sale/docs/02-domain-model.uxf
new file mode 100644
index 0000000..04dae9e
--- /dev/null
+++ b/oop/11-point-of-sale/docs/02-domain-model.uxf
@@ -0,0 +1,16 @@
+<diagram program="umletino" version="15.1"><zoom_level>10</zoom_level><element><id>UMLClass</id><coordinates><x>450</x><y>200</y><w>100</w><h>30</h></coordinates><panel_attributes>Customer</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>310</x><y>100</y><w>100</w><h>30</h></coordinates><panel_attributes>Cashier</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>50</x><y>520</y><w>100</w><h>80</h></coordinates><panel_attributes>Item
+--
+id: String
+name: String
+unitPrice</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>50</x><y>330</y><w>100</w><h>30</h></coordinates><panel_attributes>Cart</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>80</x><y>350</y><w>40</w><h>190</h></coordinates><panel_attributes>lt=&lt;&lt;&lt;&lt;-
+m2=*</panel_attributes><additional_attributes>10;10;10;170</additional_attributes></element><element><id>UMLClass</id><coordinates><x>270</x><y>340</y><w>180</w><h>100</h></coordinates><panel_attributes>Bill
+--
+id
+total
+tax
+cashByCustomer
+balance</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>310</x><y>530</y><w>100</w><h>40</h></coordinates><panel_attributes>LineItem
+--
+quantity: int</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>350</x><y>430</y><w>40</w><h>120</h></coordinates><panel_attributes>lt=&lt;&lt;&lt;&lt;&lt;-
+m2=*</panel_attributes><additional_attributes>10;10;10;100</additional_attributes></element><element><id>UMLClass</id><coordinates><x>60</x><y>100</y><w>120</w><h>30</h></coordinates><panel_attributes>PointOfSaleSystem</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>140</x><y>540</y><w>190</w><h>40</h></coordinates><panel_attributes>lt=&lt;-
+m1=1</panel_attributes><additional_attributes>10;10;170;10</additional_attributes></element></diagram> \ No newline at end of file
diff --git a/oop/11-point-of-sale/docs/03-design.uxf b/oop/11-point-of-sale/docs/03-design.uxf
new file mode 100644
index 0000000..8eaee19
--- /dev/null
+++ b/oop/11-point-of-sale/docs/03-design.uxf
@@ -0,0 +1,71 @@
+<diagram program="umletino" version="15.1"><zoom_level>10</zoom_level><help_text>Space for diagram notes</help_text><element><id>UMLClass</id><coordinates><x>880</x><y>470</y><w>130</w><h>70</h></coordinates><panel_attributes>Item
+--
+-id: String
+-name: String
+-unitPrice: BigDecimal</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>880</x><y>340</y><w>130</w><h>100</h></coordinates><panel_attributes>LineItem
+--
+itemId: String
+itemName: String
+quantity: int
+unitPrice: BigDecimal
+</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>940</x><y>250</y><w>40</w><h>110</h></coordinates><panel_attributes>lt=&lt;&lt;&lt;&lt;&lt;-
+m2=*</panel_attributes><additional_attributes>10;10;10;90</additional_attributes></element><element><id>UMLClass</id><coordinates><x>860</x><y>140</y><w>180</w><h>120</h></coordinates><panel_attributes>Bill
+--
+id: int
+total: BigDecimal
+tax: BigDecimal
+cashByCustomer: BigDecimal
+balance: BigDecimal
+--
+addLineItem(lineItem: LineItem)</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>900</x><y>0</y><w>100</w><h>60</h></coordinates><panel_attributes>Cashier
+--
+name: String
+id: String</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>940</x><y>50</y><w>30</w><h>110</h></coordinates><panel_attributes>lt=&lt;-</panel_attributes><additional_attributes>10;10;10;90</additional_attributes></element><element><id>UMLClass</id><coordinates><x>270</x><y>20</y><w>100</w><h>60</h></coordinates><panel_attributes>TextUI
+--
+--
+-printBill()
++start()</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>480</x><y>20</y><w>250</w><h>140</h></coordinates><panel_attributes>&lt;&lt;interface&gt;&gt;
+PointOfSale
+--
+--
+createNewBill(): Bill
+addLineItem(itemId: String, quantity: int)
+cashByCustomer(amount: String)
+searchItems(q: String): ListsavBill()
+saveBill()
+finishBillSession()</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>360</x><y>30</y><w>140</w><h>30</h></coordinates><panel_attributes>lt=&lt;-</panel_attributes><additional_attributes>120;10;10;10</additional_attributes></element><element><id>UMLClass</id><coordinates><x>490</x><y>420</y><w>240</w><h>120</h></coordinates><panel_attributes>&lt;&lt;interface&gt;&gt;
+BillManager
+--
+--
+createNewBill():Bill
+addLineItem(itemId: String, quantity: int)
+cashByCustomer(amount: String)
+saveBill()
+finishBillSession()</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>600</x><y>320</y><w>30</w><h>120</h></coordinates><panel_attributes>lt=&lt;-</panel_attributes><additional_attributes>10;100;10;10</additional_attributes></element><element><id>UMLClass</id><coordinates><x>890</x><y>640</y><w>100</w><h>30</h></coordinates><panel_attributes>TaxCalculator</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>0</x><y>370</y><w>370</w><h>100</h></coordinates><panel_attributes>&lt;&lt;interface&gt;&gt;
+ItemManager
+--
+--
+createItem(id: String, name: String, unitPrice: BigDecimal): Item
+findById(id: String): Item
+searchItems(q: String): List</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>180</x><y>250</y><w>320</w><h>140</h></coordinates><panel_attributes>lt=&lt;-</panel_attributes><additional_attributes>10;120;10;10;300;10</additional_attributes></element><element><id>UMLClass</id><coordinates><x>480</x><y>210</y><w>250</w><h>120</h></coordinates><panel_attributes>PointOfSaleImpl
+--
+--
+createNewBill(): Bill
+addLineItem(itemId: String, quantity: int)
+cashByCustomer(amount: String)
+searchItems(q: String): List
+saveBill()
+finishBillSession()</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>600</x><y>150</y><w>30</w><h>80</h></coordinates><panel_attributes>lt=&lt;&lt;.</panel_attributes><additional_attributes>10;10;10;60</additional_attributes></element><element><id>UMLClass</id><coordinates><x>490</x><y>600</y><w>240</w><h>120</h></coordinates><panel_attributes>BillManagerImpl
+--
+- currentBill:Bill
+--
+createNewBill():Bill
+addLineItem(itemId: String, quantity: int)
+cashByCustomer(amount: String)
+saveBill()
+finishBillSession()</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>600</x><y>530</y><w>30</w><h>90</h></coordinates><panel_attributes>lt=&lt;&lt;.</panel_attributes><additional_attributes>10;10;10;70</additional_attributes></element><element><id>UMLClass</id><coordinates><x>0</x><y>500</y><w>370</w><h>80</h></coordinates><panel_attributes>ItemManagerImpl
+--
+--
+createItem(id: String, name: String, unitPrice: BigDecimal)
+findById(id: String): Item
+searchItems(q: String): List</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>180</x><y>460</y><w>30</w><h>60</h></coordinates><panel_attributes>lt=&lt;&lt;.</panel_attributes><additional_attributes>10;10;10;40</additional_attributes></element><element><id>Relation</id><coordinates><x>364</x><y>380</y><w>190</w><h>60</h></coordinates><panel_attributes>lt=&lt;-</panel_attributes><additional_attributes>10;10;170;10;170;40</additional_attributes></element></diagram> \ No newline at end of file
diff --git a/oop/11-point-of-sale/pom.xml b/oop/11-point-of-sale/pom.xml
new file mode 100644
index 0000000..65094ab
--- /dev/null
+++ b/oop/11-point-of-sale/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>lk.ac.pdn.ceit.pos</groupId>
+ <artifactId>point-of-sale</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>point-of-sale</name>
+ <!-- FIXME change it to the project's website -->
+ <url>http://www.example.com</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.release>25</maven.compiler.release>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.junit</groupId>
+ <artifactId>junit-bom</artifactId>
+ <version>5.11.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <!-- Optionally: parameterized tests support -->
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to
+ parent pom) -->
+ <plugins>
+ <!-- clean lifecycle, see
+ https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>3.4.0</version>
+ </plugin>
+ <!-- default lifecycle, jar packaging: see
+ https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.3.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.13.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>3.3.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.4.2</version>
+ <configuration>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <mainClass>lk.ac.pdn.ceit.pos.App</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>3.1.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>3.1.2</version>
+ </plugin>
+ <!-- site lifecycle, see
+ https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
+ <plugin>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.12.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>3.6.1</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project> \ No newline at end of file
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/App.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/App.java
new file mode 100644
index 0000000..c646f5e
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/App.java
@@ -0,0 +1,24 @@
+package lk.ac.pdn.ceit.pos;
+
+import lk.ac.pdn.ceit.pos.ui.TextUI;
+
+/**
+ * Hello world!
+ */
+public class App {
+ public static void main(String[] args) {
+ // Create an ItemManager
+ ItemManager itemManager = new ItemManagerImpl();
+
+ // Create a BillManager
+ BillManager billManager = new BillManagerImpl(itemManager);
+
+ // Create a POS
+ PointOfSale pos = new PointOfSaleImpl(itemManager, billManager);
+
+ TextUI ui = new TextUI();
+ ui.setPos(pos);
+
+ ui.start();
+ }
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/BillManager.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/BillManager.java
new file mode 100644
index 0000000..7ac0e53
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/BillManager.java
@@ -0,0 +1,16 @@
+package lk.ac.pdn.ceit.pos;
+
+import lk.ac.pdn.ceit.pos.entities.Bill;
+
+public interface BillManager {
+ public Bill createNewBill();
+
+ /**
+ * End the current bill.
+ */
+ public void saveBill();
+
+ public void addLineItem(String itemId, int quantity);
+
+ public void finishBillSession();
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/BillManagerImpl.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/BillManagerImpl.java
new file mode 100644
index 0000000..11f7889
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/BillManagerImpl.java
@@ -0,0 +1,52 @@
+package lk.ac.pdn.ceit.pos;
+
+import lk.ac.pdn.ceit.pos.entities.Bill;
+import lk.ac.pdn.ceit.pos.entities.Item;
+import lk.ac.pdn.ceit.pos.entities.LineItem;
+
+public class BillManagerImpl implements BillManager {
+ private ItemManager itemManager;
+
+ private Bill currentBill;
+
+ // Just for demo purpose. In real world, a database call may be used for this purpose.
+ private int lastBillId = 0;
+
+ public BillManagerImpl(ItemManager itemManager) {
+ this.itemManager = itemManager;
+ }
+
+ @Override
+ public Bill createNewBill() {
+ currentBill = new Bill();
+
+ lastBillId++;
+ currentBill.setId(lastBillId);
+
+ return currentBill;
+ }
+
+ @Override
+ public void addLineItem(String itemId, int quantity) {
+ if (currentBill == null) {
+ throw new IllegalStateException("A bill has not been created so far. Neither a checked exception is thrown.");
+ }
+
+ Item item = itemManager.findById(itemId);
+
+ if (item != null) {
+ LineItem lineItem = new LineItem(item.getId(), item.getName(), quantity, item.getUnitPrice());
+ currentBill.addLineItem(lineItem);
+ }
+ }
+
+ @Override
+ public void saveBill() {
+ // TODO: Save the currentBill in DB.
+ }
+
+ @Override
+ public void finishBillSession() {
+ currentBill = null;
+ }
+} \ No newline at end of file
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ItemManager.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ItemManager.java
new file mode 100644
index 0000000..3e31fdc
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ItemManager.java
@@ -0,0 +1,12 @@
+package lk.ac.pdn.ceit.pos;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import lk.ac.pdn.ceit.pos.entities.Item;
+
+public interface ItemManager {
+ public Item createItem(String id, String name, BigDecimal unitPrice);
+ public Item findById(String id);
+ public List<Item> searchItems(String q);
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ItemManagerImpl.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ItemManagerImpl.java
new file mode 100644
index 0000000..ae325cd
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ItemManagerImpl.java
@@ -0,0 +1,47 @@
+package lk.ac.pdn.ceit.pos;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import lk.ac.pdn.ceit.pos.entities.Item;
+
+public class ItemManagerImpl implements ItemManager {
+
+ // For this demo. let's hold Items in memory.
+ private Map<String, Item> items = new HashMap<>();
+
+ public ItemManagerImpl() {
+ // For demo purposes, let's create some items (to be availalbe in system db)
+ createItem("F001", "Red Lentil (Dhal)", new BigDecimal("250.00"));
+ createItem("F002", "Sugar", new BigDecimal("270.00"));
+ createItem("S001", "Beauty Soap", new BigDecimal("165.00"));
+ }
+
+ @Override
+ public Item createItem(String id, String name, BigDecimal unitPrice) {
+ Item item = new Item(id, name, unitPrice);
+ items.put(id, item);
+ return item;
+ }
+
+ @Override
+ public Item findById(String id) {
+ return items.get(id);
+ }
+
+ @Override
+ public List<Item> searchItems(String q) {
+ List<Item> results = new ArrayList<>();
+
+ for (Item item : items.values()) {
+ if (item.getName().toLowerCase().contains(q.toLowerCase())) {
+ results.add(item);
+ }
+ }
+
+ return results;
+ }
+} \ No newline at end of file
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/PointOfSale.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/PointOfSale.java
new file mode 100644
index 0000000..d318af0
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/PointOfSale.java
@@ -0,0 +1,15 @@
+package lk.ac.pdn.ceit.pos;
+
+import java.util.List;
+
+import lk.ac.pdn.ceit.pos.entities.Bill;
+import lk.ac.pdn.ceit.pos.entities.Item;
+
+public interface PointOfSale {
+ public Bill createNewBill();
+ public void addLineItem(String itemId, int quantity);
+ public void cashByCustomer(String amount);
+ public List<Item> searchItems(String q);
+ public void saveBill();
+ public void finishBillSession();
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/PointOfSaleImpl.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/PointOfSaleImpl.java
new file mode 100644
index 0000000..b4d697d
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/PointOfSaleImpl.java
@@ -0,0 +1,49 @@
+package lk.ac.pdn.ceit.pos;
+
+import java.util.List;
+
+import lk.ac.pdn.ceit.pos.entities.Bill;
+import lk.ac.pdn.ceit.pos.entities.Item;
+
+public class PointOfSaleImpl implements PointOfSale {
+
+ private ItemManager itemManager;
+ private BillManager billManager;
+
+ public PointOfSaleImpl(ItemManager itemManager, BillManager billManager) {
+ this.itemManager = itemManager;
+ this.billManager = billManager;
+ }
+
+ @Override
+ public Bill createNewBill() {
+ return billManager.createNewBill();
+ }
+
+ @Override
+ public void addLineItem(String itemId, int quantity) {
+ billManager.addLineItem(itemId, quantity);
+ }
+
+ @Override
+ public void cashByCustomer(String amount) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException("Unimplemented method 'cashByCustomer'");
+ }
+
+ @Override
+ public List<Item> searchItems(String q) {
+ return itemManager.searchItems(q);
+ }
+
+ @Override
+ public void saveBill() {
+ billManager.saveBill();
+ }
+
+ @Override
+ public void finishBillSession() {
+ billManager.finishBillSession();
+ }
+
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Bill.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Bill.java
new file mode 100644
index 0000000..c78f88b
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Bill.java
@@ -0,0 +1,79 @@
+package lk.ac.pdn.ceit.pos.entities;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Bill {
+
+ private List<LineItem> lineItems = new ArrayList<>();
+ private Cashier cashier;
+
+ private int id;
+ private BigDecimal total = new BigDecimal("0.00");
+ private BigDecimal tax;
+ private BigDecimal cashByCustomer;
+ private BigDecimal balance;
+
+ public Bill() {
+ }
+
+ public Cashier getCashier() {
+ return cashier;
+ }
+
+ public void setCashier(Cashier cashier) {
+ this.cashier = cashier;
+ }
+
+ public int getId() {
+ return id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public BigDecimal getTotal() {
+ return total;
+ }
+
+ public BigDecimal getTax() {
+ return tax;
+ }
+
+ public void setTax(BigDecimal tax) {
+ this.tax = tax;
+ }
+
+ public BigDecimal getCashByCustomer() {
+ return cashByCustomer;
+ }
+ public void setCashByCustomer(BigDecimal cashByCustomer) {
+ this.cashByCustomer = cashByCustomer;
+ }
+
+ public BigDecimal getBalance() {
+ return balance;
+ }
+
+ @Override
+ public String toString() {
+ return "Bill [id=" + id + ", total=" + total + ", tax=" + tax + ", cashByCustomer=" + cashByCustomer
+ + ", balance=" + balance + "]";
+ }
+
+ public void addLineItem(LineItem lineItem) {
+ lineItems.add(lineItem);
+
+ // Update total
+ for (LineItem _lineItem : lineItems) {
+ total = total.add(_lineItem.getUnitPrice().multiply(BigDecimal.valueOf(_lineItem.getQuantity())));
+ }
+ }
+
+ public List<LineItem> getLineItems() {
+ // TODO: Do a deep copy and return to avoid external modification of line items.
+ // We return an immutable copy to avoid external world adding LineItems.
+ return List.copyOf(lineItems);
+ }
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Cashier.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Cashier.java
new file mode 100644
index 0000000..f951a9c
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Cashier.java
@@ -0,0 +1,31 @@
+package lk.ac.pdn.ceit.pos.entities;
+
+public class Cashier {
+ private String id;
+ private String name;
+
+ public Cashier() {
+ }
+
+ public Cashier(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Item.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Item.java
new file mode 100644
index 0000000..ecf6bea
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/Item.java
@@ -0,0 +1,43 @@
+package lk.ac.pdn.ceit.pos.entities;
+
+import java.math.BigDecimal;
+
+public class Item {
+ private String id;
+ private String name;
+ private BigDecimal unitPrice;
+
+ public Item() {
+ }
+
+ public Item(String id, String name, BigDecimal unitPrice) {
+ this.id = id;
+ this.name = name;
+ this.unitPrice = unitPrice;
+ }
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public BigDecimal getUnitPrice() {
+ return unitPrice;
+ }
+ public void setUnitPrice(BigDecimal unitPrice) {
+ this.unitPrice = unitPrice;
+ }
+
+ @Override
+ public String toString() {
+ return "Item [id=" + id + ", name=" + name + ", unitPrice=" + unitPrice + "]";
+ }
+
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/LineItem.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/LineItem.java
new file mode 100644
index 0000000..8c53ec4
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/entities/LineItem.java
@@ -0,0 +1,53 @@
+package lk.ac.pdn.ceit.pos.entities;
+
+import java.math.BigDecimal;
+
+public class LineItem {
+
+ private String itemId;
+ private String itemName;
+ private int quantity;
+ private BigDecimal unitPrice;
+
+ public LineItem() {
+ }
+
+ public LineItem(String itemId, String itemName, int quantity, BigDecimal unitPrice) {
+ this.itemId = itemId;
+ this.itemName = itemName;
+ this.quantity = quantity;
+ this.unitPrice = unitPrice;
+ }
+
+ public String getItemId() {
+ return itemId;
+ }
+ public void setItemId(String itemId) {
+ this.itemId = itemId;
+ }
+ public String getItemName() {
+ return itemName;
+ }
+ public void setItemName(String itemName) {
+ this.itemName = itemName;
+ }
+ public int getQuantity() {
+ return quantity;
+ }
+ public void setQuantity(int quantity) {
+ this.quantity = quantity;
+ }
+ public BigDecimal getUnitPrice() {
+ return unitPrice;
+ }
+ public void setUnitPrice(BigDecimal unitPrice) {
+ this.unitPrice = unitPrice;
+ }
+
+ @Override
+ public String toString() {
+ return "LineItem [itemId=" + itemId + ", itemName=" + itemName + ", quantity=" + quantity + ", unitPrice="
+ + unitPrice + "]";
+ }
+
+}
diff --git a/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ui/TextUI.java b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ui/TextUI.java
new file mode 100644
index 0000000..874c074
--- /dev/null
+++ b/oop/11-point-of-sale/src/main/java/lk/ac/pdn/ceit/pos/ui/TextUI.java
@@ -0,0 +1,102 @@
+package lk.ac.pdn.ceit.pos.ui;
+
+import java.util.List;
+
+import lk.ac.pdn.ceit.pos.PointOfSale;
+import lk.ac.pdn.ceit.pos.entities.Bill;
+import lk.ac.pdn.ceit.pos.entities.Item;
+import lk.ac.pdn.ceit.pos.entities.LineItem;
+
+public class TextUI {
+ private PointOfSale pos;
+ private Bill bill; // Current bill
+
+ private void printBill() {
+ // Print top part of the bill
+ IO.println(bill); // TODO: Only print suitable parts for the top of the bill.
+
+ // Print line items
+ for (LineItem lineItem : bill.getLineItems()) {
+ IO.println(lineItem);
+ }
+
+ // TODO: Print total, cash given, balance, etc.
+ }
+
+ public void setPos(PointOfSale pos) {
+ this.pos = pos;
+ }
+
+ public void start() {
+ IO.println("POS Starting...");
+ printHelp();
+
+ while (true) {
+ String response = IO.readln("POS> ");
+
+ switch (response.trim().toLowerCase()) {
+ case "q":
+ case "quit":
+ IO.println("Bye bye!");
+ System.exit(0);
+
+ case "help":
+ printHelp();
+ break;
+
+ case "create":
+ bill = pos.createNewBill();
+ IO.println("New bill created. Bill id: " + bill.getId());
+ break;
+
+ case "search":
+ String q = IO.readln("Enter search query (item name): ");
+ List<Item> items = pos.searchItems(q);
+
+ IO.println("Search results: ");
+
+ for (Item item : items) {
+ IO.println(item);
+ }
+ break;
+
+ case "item":
+ String itemId = IO.readln("Enter item Id: ");
+ String quantity = IO.readln("Enter quantity: ");
+ pos.addLineItem(itemId, Integer.parseInt(quantity));
+ break;
+
+ case "save":
+ pos.saveBill();
+ IO.println("Bill saved.");
+ break;
+
+ case "finish":
+ pos.finishBillSession();
+ this.bill = null;
+ IO.println("Bill session finished.");
+ break;
+
+ case "print":
+ printBill();
+ break;
+
+ default:
+ IO.println("Command not understood.");
+ break;
+ }
+
+ }
+ }
+
+ private void printHelp() {
+ IO.println("Commands available:");
+ IO.println(" q or quit - Quit the program.");
+ IO.println(" help - Prints this help.");
+ IO.println(" create - Create a new bill.");
+ IO.println(" item - Enter new item details to be purchased.");
+ IO.println(" save - Save the current bill in the system.");
+ IO.println(" print - Print the bill.");
+ IO.println(" finish - Finish current bill session.");
+ }
+} \ No newline at end of file
diff --git a/oop/11-point-of-sale/src/test/java/lk/ac/pdn/ceit/pos/AppTest.java b/oop/11-point-of-sale/src/test/java/lk/ac/pdn/ceit/pos/AppTest.java
new file mode 100644
index 0000000..2fb51b5
--- /dev/null
+++ b/oop/11-point-of-sale/src/test/java/lk/ac/pdn/ceit/pos/AppTest.java
@@ -0,0 +1,19 @@
+package lk.ac.pdn.ceit.pos;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest {
+
+ /**
+ * Rigorous Test :-)
+ */
+ @Test
+ public void shouldAnswerWithTrue() {
+ assertTrue(true);
+ }
+}