From 8b2aec4791dfe5498f9fff0fc63b55a08ec73340 Mon Sep 17 00:00:00 2001
From: Roland Haeder <roland@mxchange.org>
Date: Fri, 14 Aug 2015 15:39:12 +0200
Subject: [PATCH] =?utf8?q?Continued=20with=20project:=20-=20added=20instal?=
 =?utf8?q?l.sql=20-=20Renamed=20method=20getProducts()=20to=20getAvailable?=
 =?utf8?q?Products()=20-=20Added=20method=20getAllProducts()=20-=20Renamed?=
 =?utf8?q?=20parseLineToCategory()=20and=20parseLineToProduct()=20to=20par?=
 =?utf8?q?seLine()=20-=20All=20products=20are=20now=20comparable=20+=20com?=
 =?utf8?q?pareTo()=20implemented=20in=20BaseProduct=20-=20Added=20column?=
 =?utf8?q?=20"id"=20for=20product=20database=20-=20Implemented=20getPrinta?=
 =?utf8?q?bleProduktAvailability()=20very=20rudely=20-=20Ids=20must=20be?=
 =?utf8?q?=20parsed=20as=20Long,=20not=20Integer,=20as=20the=20BASE64-enco?=
 =?utf8?q?ded=20database=20backend=20does=20parse=20it=20so=20-=20Added=20?=
 =?utf8?q?"available"=20to=20HTML=20form=20and=20all=20relevant=20methods?=
 =?utf8?q?=20-=20Added=20method=20decodedTitle()=20to=20have=20a=20UTF8-de?=
 =?utf8?q?coded=20title=20-=20Constructor=20PizzaProduct=20(id,=20title,?=
 =?utf8?q?=20price)=20is=20now=20deprecated=20-=20Some=20other=20cleanups?=
 =?utf8?q?=20Signed-off-by:Roland=20H=C3=A4der=20<roland@mxchange.org>?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

---
 install/install.sql                           | 68 +++++++++++++++
 .../application/PizzaApplication.java         | 12 ++-
 .../application/PizzaServiceApplication.java  | 82 +++++++++++++----
 .../category/BaseCategory.java                | 28 +++---
 .../PizzaCategoryDatabaseFrontend.java        |  4 +-
 .../product/PizzaProductDatabaseFrontend.java | 61 +++++++++++--
 .../frontend/product/ProductFrontend.java     | 15 +++-
 .../PizzaProductDatabaseConstants.java        |  5 ++
 .../product/PizzaProduct.java                 | 87 ++++++++++++++++++-
 .../pizzaapplication/product/Product.java     | 29 ++++++-
 web/admin/product.jsp                         | 23 ++++-
 web/finished.jsp                              |  2 +-
 web/form_handler/do_preview.jsp               |  2 +-
 web/index.jsp                                 |  2 +-
 web/preview.jsp                               |  2 +-
 15 files changed, 362 insertions(+), 60 deletions(-)
 create mode 100644 install/install.sql

diff --git a/install/install.sql b/install/install.sql
new file mode 100644
index 00000000..04fb29be
--- /dev/null
+++ b/install/install.sql
@@ -0,0 +1,68 @@
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+DROP TABLE IF EXISTS `category`;
+CREATE TABLE IF NOT EXISTS `category` (
+`id` bigint(20) unsigned NOT NULL COMMENT 'Primary key',
+  `title` varchar(255) NOT NULL COMMENT 'Category title',
+  `parent` bigint(20) unsigned DEFAULT NULL COMMENT 'Parent category'
+) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='Categories' AUTO_INCREMENT=3 ;
+
+DROP TABLE IF EXISTS `contacts`;
+CREATE TABLE IF NOT EXISTS `contacts` (
+`id` bigint(20) unsigned NOT NULL COMMENT 'Primary key',
+  `own_contact` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Whether own contact',
+  `gender` varchar(10) NOT NULL DEFAULT 'UNKNOWN' COMMENT 'Gender',
+  `surname` varchar(100) NOT NULL COMMENT 'Surname',
+  `family_name` varchar(100) NOT NULL COMMENT 'Family name',
+  `company_name` varchar(255) DEFAULT NULL COMMENT 'Company name',
+  `street` varchar(255) DEFAULT NULL COMMENT 'Street name',
+  `house_number` smallint(5) unsigned DEFAULT NULL COMMENT 'House number',
+  `city` varchar(100) DEFAULT NULL COMMENT 'City name',
+  `zip_code` smallint(5) unsigned DEFAULT NULL COMMENT 'ZIP code',
+  `country_code` char(2) DEFAULT NULL COMMENT 'Country code',
+  `phone_number` varchar(100) DEFAULT NULL COMMENT 'Phone number',
+  `cellphone_number` varchar(100) DEFAULT NULL COMMENT 'Cellphone number',
+  `fax_number` varchar(100) DEFAULT NULL COMMENT 'Fax number',
+  `email_address` varchar(100) DEFAULT NULL COMMENT 'Email addres',
+  `birthday` date DEFAULT NULL COMMENT 'Birth day',
+  `comment` tinytext NOT NULL COMMENT 'Comment',
+  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Entry created',
+  `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Contacts data' AUTO_INCREMENT=1 ;
+
+DROP TABLE IF EXISTS `products`;
+CREATE TABLE IF NOT EXISTS `products` (
+`id` bigint(20) unsigned NOT NULL COMMENT 'Primary key',
+  `category` bigint(20) unsigned DEFAULT NULL COMMENT 'Category id',
+  `title` varchar(255) NOT NULL COMMENT 'Title of product',
+  `price` decimal(20,2) unsigned NOT NULL COMMENT 'Product price',
+  `available` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Whether product is available'
+) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='Products' AUTO_INCREMENT=2 ;
+
+
+ALTER TABLE `category`
+ ADD PRIMARY KEY (`id`), ADD KEY `parent` (`parent`);
+
+ALTER TABLE `contacts`
+ ADD PRIMARY KEY (`id`);
+
+ALTER TABLE `products`
+ ADD PRIMARY KEY (`id`), ADD KEY `category` (`category`);
+
+
+ALTER TABLE `category`
+MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary key',AUTO_INCREMENT=3;
+ALTER TABLE `contacts`
+MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary key';
+ALTER TABLE `products`
+MODIFY `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primary key',AUTO_INCREMENT=2;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
diff --git a/src/java/org/mxchange/pizzaapplication/application/PizzaApplication.java b/src/java/org/mxchange/pizzaapplication/application/PizzaApplication.java
index eac4882f..dc0140bb 100644
--- a/src/java/org/mxchange/pizzaapplication/application/PizzaApplication.java
+++ b/src/java/org/mxchange/pizzaapplication/application/PizzaApplication.java
@@ -201,12 +201,20 @@ public interface PizzaApplication extends Application {
 	public void setValueInSession (final HttpSession session, final String key, final Object value);
 
 	/**
-	 * Some "getter" for a an array of all products
+	 * Some "getter" for a an array of only available products
 	 * 
+	 * @return Only available products
+	 * @throws javax.servlet.ServletException If anything went wrong
+	 */
+	public Iterator<Product> getAvailableProducts () throws ServletException;
+
+	/**
+	 * Some "getter" for a an array of all products
+	 *
 	 * @return All products
 	 * @throws javax.servlet.ServletException If anything went wrong
 	 */
-	public Iterator<Product> getProducts () throws ServletException;
+	public Iterator<Product> getAllProducts () throws ServletException;
 
 	/**
 	 * Some "getter" for a an array of all categories
diff --git a/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java b/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java
index 914711b9..e32f4556 100644
--- a/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java
+++ b/src/java/org/mxchange/pizzaapplication/application/PizzaServiceApplication.java
@@ -168,7 +168,7 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 
 		// Init/declare total price and iterator
 		int totalAmount = 0;
-		Iterator<Product> iterator = this.getProducts();
+		Iterator<Product> iterator = this.getAvailableProducts();
 
 		// "Walk" over all products
 		while (iterator.hasNext()) {
@@ -222,7 +222,7 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 		float totalPrice = 0.00f;
 
 		// Get iterator
-		Iterator<Product> iterator = this.getProducts();
+		Iterator<Product> iterator = this.getAvailableProducts();
 
 		// "Walk" over all products
 		while (iterator.hasNext()) {
@@ -481,7 +481,23 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 	 */
 	@Override
 	public String getPrintableProduktAvailability (final Product product) {
-		throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: product={0}", product)); //NOI18N
+		// Trace message
+		this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product));
+
+		// Is it null?
+		if (product == null) {
+			// Should not be null
+			throw new NullPointerException("product is null");
+		}
+
+		// Get availability
+		if (product.getAvailable() == true) {
+			// Is available
+			return "Ja";
+		} else {
+			// Not, not for public
+			return "Nein";
+		}
 	}
 
 	/**
@@ -518,16 +534,31 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 		return this.convertNullToEmpty(value);
 	}
 
+	/**
+	 * Some "getter" for a an array of only available products
+	 *
+	 * @return All products
+	 */
+	@Override
+	public Iterator<Product> getAvailableProducts () throws ServletException {
+		try {
+			// Ask frontend for a list of products
+			return this.productFrontend.getAvailableProducts();
+		} catch (final IOException | BadTokenException | SQLException ex) {
+			throw new ServletException(ex);
+		}
+	}
+
 	/**
 	 * Some "getter" for a an array of all products
 	 *
 	 * @return All products
 	 */
 	@Override
-	public Iterator<Product> getProducts () throws ServletException {
+	public Iterator<Product> getAllProducts () throws ServletException {
 		try {
 			// Ask frontend for a list of products
-			return this.productFrontend.getProducts();
+			return this.productFrontend.getAllProducts();
 		} catch (final IOException | BadTokenException | SQLException ex) {
 			throw new ServletException(ex);
 		}
@@ -756,7 +787,7 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 		this.getLogger().trace(MessageFormat.format("request={0},session={1} - CALLED!", request, session)); //NOI18N
 
 		// Init iterator
-		Iterator<Product> iterator = this.getProducts();
+		Iterator<Product> iterator = this.getAvailableProducts();
 
 		// "Walk" over all products
 		while (iterator.hasNext()) {
@@ -1135,7 +1166,7 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 
 		try {
 			// Get iterator
-			iterator = this.getProducts();
+			iterator = this.getAvailableProducts();
 		} catch (final ServletException ex) {
 			this.abortProgramWithException(ex);
 		}
@@ -1259,8 +1290,11 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 		String title = request.getParameter(PizzaProductDatabaseConstants.COLUMN_TITLE);
 		String price = request.getParameter(PizzaProductDatabaseConstants.COLUMN_PRICE);
 		String category = request.getParameter(PizzaProductDatabaseConstants.COLUMN_CATEGORY);
-		Integer id = null;
+		String available = request.getParameter(PizzaProductDatabaseConstants.COLUMN_AVAILABLE);
+
+		Long id = null;
 		Float p = null;
+		Boolean a = null;
 
 		// Check all fields
 		if (title == null) {
@@ -1281,17 +1315,29 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 		} else if (category.isEmpty()) {
 			// Is left empty
 			throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_CATEGORY));
-		} else {
-			// "parent" is set, so check it
-			try {
-				id = Integer.parseInt(category);
-				p = Float.parseFloat(price);
-			} catch (final NumberFormatException e) {
-				// Not valid number
-				throw new IllegalArgumentException(e);
-			}
+		} else if (available == null) {
+			// "title" not set
+			throw new IllegalArgumentException(MessageFormat.format("{0} is not set.", PizzaProductDatabaseConstants.COLUMN_AVAILABLE));
+		} else if (available.isEmpty()) {
+			// Is left empty
+			throw new IllegalArgumentException(MessageFormat.format("{0} is empty.", PizzaProductDatabaseConstants.COLUMN_AVAILABLE));
+		} else if ((!"true".equals(available)) && (!"false".equals(available))) {
+			// Invalid value
+			throw new IllegalArgumentException(MessageFormat.format("{0} is invalid: {1}", PizzaProductDatabaseConstants.COLUMN_AVAILABLE, available));
 		}
 
+		// Parse numbers
+		try {
+			id = Long.parseLong(category);
+			p = Float.parseFloat(price);
+		} catch (final NumberFormatException e) {
+			// Not valid number
+			throw new IllegalArgumentException(e);
+		}
+
+		// Parse boolean
+		a = Boolean.parseBoolean(available);
+
 		// Test on product title
 		try {
 			// Try to check if title is used already
@@ -1305,7 +1351,7 @@ public class PizzaServiceApplication extends BasePizzaServiceSystem implements P
 
 		try {
 			// The product is not found, so add it to database
-			this.productFrontend.addProduct(title, p, id);
+			this.productFrontend.addProduct(title, p, id, a);
 		} catch (final SQLException ex) {
 			// Continue to throw it
 			throw new ServletException(ex);
diff --git a/src/java/org/mxchange/pizzaapplication/category/BaseCategory.java b/src/java/org/mxchange/pizzaapplication/category/BaseCategory.java
index 5043b940..04b78b71 100644
--- a/src/java/org/mxchange/pizzaapplication/category/BaseCategory.java
+++ b/src/java/org/mxchange/pizzaapplication/category/BaseCategory.java
@@ -87,6 +87,20 @@ public class BaseCategory extends BaseFrameworkSystem implements Category {
 		return 1;
 	}
 
+	/**
+	 * Decodes the UTF8-encoded title
+	 *
+	 * @return Decoded title
+	 */
+	@Override
+	public final String decodedTitle () throws UnsupportedEncodingException {
+		// Get title
+		byte[] t = this.getTitle().getBytes();
+		
+		// Decode it
+		return new String(t, "UTF-8");
+	}
+
 	/**
 	 * Id number of category
 	 * @return the id
@@ -140,18 +154,4 @@ public class BaseCategory extends BaseFrameworkSystem implements Category {
 	public final void setTitle (final String title) {
 		this.title = title;
 	}
-
-	/**
-	 * Decodes the UTF8-encoded title
-	 *
-	 * @return Decoded title
-	 */
-	@Override
-	public final String decodedTitle () throws UnsupportedEncodingException {
-		// Get title
-		byte[] t = this.getTitle().getBytes();
-
-		// Decode it
-		return new String(t, "UTF-8");
-	}
 }
diff --git a/src/java/org/mxchange/pizzaapplication/database/frontend/category/PizzaCategoryDatabaseFrontend.java b/src/java/org/mxchange/pizzaapplication/database/frontend/category/PizzaCategoryDatabaseFrontend.java
index d491d031..e9e76f4c 100644
--- a/src/java/org/mxchange/pizzaapplication/database/frontend/category/PizzaCategoryDatabaseFrontend.java
+++ b/src/java/org/mxchange/pizzaapplication/database/frontend/category/PizzaCategoryDatabaseFrontend.java
@@ -257,7 +257,7 @@ public class PizzaCategoryDatabaseFrontend extends BaseDatabaseFrontend implemen
 		this.getLogger().trace(MessageFormat.format("line={0} - CALLED!", line)); //NOI18N
 
 		// Call inner method
-		Category category = this.parseLineToCategory(line);
+		Category category = this.parseLine(line);
 
 		// Debug message
 		this.getLogger().trace(MessageFormat.format("category={0} - EXIT!", category)); //NOI18N
@@ -272,7 +272,7 @@ public class PizzaCategoryDatabaseFrontend extends BaseDatabaseFrontend implemen
 	 * @param line Raw, decoded line from a file-based backend
 	 * @return A Category instance from given line
 	 */
-	private Category parseLineToCategory (final String line) {
+	private Category parseLine (final String line) {
 		throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: line={0}", line)); //NOI18N
 	}
 }
diff --git a/src/java/org/mxchange/pizzaapplication/database/frontend/product/PizzaProductDatabaseFrontend.java b/src/java/org/mxchange/pizzaapplication/database/frontend/product/PizzaProductDatabaseFrontend.java
index 633e44a4..321e3097 100644
--- a/src/java/org/mxchange/pizzaapplication/database/frontend/product/PizzaProductDatabaseFrontend.java
+++ b/src/java/org/mxchange/pizzaapplication/database/frontend/product/PizzaProductDatabaseFrontend.java
@@ -30,6 +30,7 @@ import org.mxchange.jcore.database.storage.Storeable;
 import org.mxchange.jcore.exceptions.BadTokenException;
 import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
 import org.mxchange.pizzaapplication.database.product.PizzaProductDatabaseConstants;
+import org.mxchange.pizzaapplication.product.PizzaProduct;
 import org.mxchange.pizzaapplication.product.Product;
 
 /**
@@ -104,7 +105,7 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement
 
 	@Override
 	@SuppressWarnings ("unchecked")
-	public Iterator<Product> getProducts () throws IOException, BadTokenException, SQLException {
+	public Iterator<Product> getAvailableProducts () throws IOException, BadTokenException, SQLException {
 		// Trace message
 		this.getLogger().trace("CALLED!"); //NOI18N
 
@@ -130,6 +131,39 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement
 		return (Iterator<Product>) iterator;
 	}
 
+	/**
+	 * An iterator on all products
+	 *
+	 * @return Iterator on all products
+	 * @throws java.io.IOException If any IO error occurs
+	 * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-)
+	 * @throws java.sql.SQLException If any SQL errors occur
+	 */
+	@Override
+	@SuppressWarnings ("unchecked")
+	public Iterator<Product> getAllProducts () throws IOException, BadTokenException, SQLException {
+		// Trace message
+		this.getLogger().trace("CALLED!"); //NOI18N
+
+		// Instance search criteria
+		SearchableCritera critera = new SearchCriteria();
+
+		// Run the query
+		Result<? extends Storeable> result = this.getBackend().doSelectByCriteria(critera);
+
+		// Debug message
+		this.getLogger().debug(MessageFormat.format("result={0}", result)); //NOI18N
+
+		// Get iterator
+		Iterator<?> iterator = result.iterator();
+
+		// Trace message
+		this.getLogger().trace(MessageFormat.format("iterator={0} - EXIT!", iterator)); //NOI18N
+
+		// Get iterator and return it
+		return (Iterator<Product>) iterator;
+	}
+
 	/**
 	 * Gets a Result back from given ResultSet instance
 	 *
@@ -150,8 +184,18 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement
 
 		// "Walk" through all entries
 		while (resultSet.next()) {
-			// Unwrap whole object
-			Product product = resultSet.unwrap(Product.class);
+			// Get id, title and parent id
+			Long id = resultSet.getLong(PizzaProductDatabaseConstants.COLUMN_ID);
+			String title = resultSet.getString(PizzaProductDatabaseConstants.COLUMN_TITLE);
+			Float price = resultSet.getFloat(PizzaProductDatabaseConstants.COLUMN_PRICE);
+			Long category = resultSet.getLong(PizzaProductDatabaseConstants.COLUMN_CATEGORY);
+			Boolean available = resultSet.getBoolean(PizzaProductDatabaseConstants.COLUMN_AVAILABLE);
+
+			// Debug message
+			this.getLogger().debug(MessageFormat.format("id={0},title={1},category={2},available={3}", id, title, category, available));
+
+			// Instance new object
+			Product product = new PizzaProduct(id, title, price, category, available);
 
 			// Debug log
 			this.getLogger().debug(MessageFormat.format("product={0}", product));
@@ -219,7 +263,7 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement
 		this.getLogger().trace(MessageFormat.format("line={0} - CALLED!", line)); //NOI18N
 
 		// Call inner method
-		Product product = this.parseLineToProduct(line);
+		Product product = this.parseLine(line);
 
 		// Debug message
 		this.getLogger().trace(MessageFormat.format("product={0} - EXIT!", product)); //NOI18N
@@ -234,7 +278,7 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement
 	 * @param line
 	 * @return A Product instance from given line
 	 */
-	private Product parseLineToProduct (final String line) {
+	private Product parseLine (final String line) {
 		throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: line={0}", line)); //NOI18N
 	}
 
@@ -243,10 +287,11 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement
 	 * @param title Product title
 	 * @param price Product price
 	 * @param category Product category id
+	 * @param available Availability of product (selectable by customer)
 	 * @throws java.sql.SQLException If any SQL errors occur
 	 */
 	@Override
-	public void addProduct (final String title, final Float price, final Integer category) throws SQLException {
+	public void addProduct (final String title, final Float price, final Long category, final Boolean available) throws SQLException {
 		// Trace message
 		this.getLogger().trace(MessageFormat.format("title={0},price={1},category={2} - CALLED!", title, price, category));
 
@@ -260,6 +305,9 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement
 		} else if (category == null) {
 			// Abort here
 			throw new NullPointerException("category is null");
+		} else if (available == null) {
+			// Abort here
+			throw new NullPointerException("available is null");
 		}
 
 		// Clear dataset from previous usage
@@ -269,6 +317,7 @@ public class PizzaProductDatabaseFrontend extends BaseDatabaseFrontend implement
 		this.addToDataSet(PizzaProductDatabaseConstants.COLUMN_TITLE, title);
 		this.addToDataSet(PizzaProductDatabaseConstants.COLUMN_PRICE, price);
 		this.addToDataSet(PizzaProductDatabaseConstants.COLUMN_CATEGORY, category);
+		this.addToDataSet(PizzaProductDatabaseConstants.COLUMN_AVAILABLE, available);
 
 		// Handle this over to the backend
 		Result<? extends Storeable> result = this.doInsertDataSet();
diff --git a/src/java/org/mxchange/pizzaapplication/database/frontend/product/ProductFrontend.java b/src/java/org/mxchange/pizzaapplication/database/frontend/product/ProductFrontend.java
index 4363aac3..4455fd54 100644
--- a/src/java/org/mxchange/pizzaapplication/database/frontend/product/ProductFrontend.java
+++ b/src/java/org/mxchange/pizzaapplication/database/frontend/product/ProductFrontend.java
@@ -35,9 +35,10 @@ public interface ProductFrontend extends DatabaseFrontend {
 	 * @param title Product title
 	 * @param price Product price
 	 * @param category Product category id
+	 * @param available Availability of product (selectable by customer)
 	 * @throws java.sql.SQLException If any SQL errors occur
 	 */
-	public void addProduct (final String title, final Float price, final Integer category) throws SQLException;
+	public void addProduct (final String title, final Float price, final Long category, final Boolean available) throws SQLException;
 
 	/**
 	 * An iterator on all products
@@ -47,7 +48,17 @@ public interface ProductFrontend extends DatabaseFrontend {
 	 * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-)
 	 * @throws java.sql.SQLException If any SQL errors occur
 	 */
-	public Iterator<Product> getProducts () throws IOException, BadTokenException, SQLException;
+	public Iterator<Product> getAllProducts () throws IOException, BadTokenException, SQLException;
+
+	/**
+	 * An iterator on all products
+	 *
+	 * @return Iterator on all products
+	 * @throws java.io.IOException If any IO error occurs
+	 * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found in a file-based database backend's file ... ;-)
+	 * @throws java.sql.SQLException If any SQL errors occur
+	 */
+	public Iterator<Product> getAvailableProducts () throws IOException, BadTokenException, SQLException;
 
 	/**
 	 * Checks wether the given product title is already used.
diff --git a/src/java/org/mxchange/pizzaapplication/database/product/PizzaProductDatabaseConstants.java b/src/java/org/mxchange/pizzaapplication/database/product/PizzaProductDatabaseConstants.java
index 8d3646f7..4d698b11 100644
--- a/src/java/org/mxchange/pizzaapplication/database/product/PizzaProductDatabaseConstants.java
+++ b/src/java/org/mxchange/pizzaapplication/database/product/PizzaProductDatabaseConstants.java
@@ -32,6 +32,11 @@ public final class PizzaProductDatabaseConstants {
 	 */
 	public static final String COLUMN_CATEGORY = "category";
 
+	/**
+	 * Column name for "id"
+	 */
+	public static final String COLUMN_ID = "id";
+
 	/**
 	 * Column name for "price"
 	 */
diff --git a/src/java/org/mxchange/pizzaapplication/product/PizzaProduct.java b/src/java/org/mxchange/pizzaapplication/product/PizzaProduct.java
index 751aaea8..23f37575 100644
--- a/src/java/org/mxchange/pizzaapplication/product/PizzaProduct.java
+++ b/src/java/org/mxchange/pizzaapplication/product/PizzaProduct.java
@@ -16,7 +16,8 @@
  */
 package org.mxchange.pizzaapplication.product;
 
-import org.mxchange.pizzaapplication.category.Category;
+import java.text.MessageFormat;
+import java.util.Objects;
 import org.mxchange.jcore.BaseFrameworkSystem;
 
 /**
@@ -25,10 +26,15 @@ import org.mxchange.jcore.BaseFrameworkSystem;
  * @author Roland Haeder
  */
 public class PizzaProduct extends BaseFrameworkSystem implements Product {
+	/**
+	 * Availability of product
+	 */
+	private Boolean available;
+
 	/**
 	 * Product category
 	 */
-	private Category category;
+	private Long category;
 
 	/**
 	 * Id number of product
@@ -45,26 +51,67 @@ public class PizzaProduct extends BaseFrameworkSystem implements Product {
 	 */
 	private String title;
 
+
 	/**
 	 * Constructor for products with a name and a price.
 	 * 
 	 * @param id Id number of product
 	 * @param title Name of product
 	 * @param price Price
+	 * @deprecated Please use constructor with category and available
 	 */
+	@Deprecated
 	public PizzaProduct (final Long id, final String title, final float price) {
 		this.setId(id);
 		this.setTitle(title);
 		this.setPrice(price);
 	}
 
+	/**
+	 * Constructor will all required data
+	 *
+	 * @param id Id number of product
+	 * @param title Name of product
+	 * @param price Price
+	 * @param category Category id
+	 * @param available Availability (selectable by customer)
+	 */
+	public PizzaProduct (final Long id, final String title, final Float price, final Long category, final Boolean available) {
+		// Set all here
+		this.setId(id);
+		this.setTitle(title);
+		this.setPrice(price);
+		this.setCategory(category);
+		this.setAvailable(available);
+	}
+
+	/**
+	 * Getter for product availability
+	 *
+	 * @return Product availability
+	 */
+	@Override
+	public final Boolean getAvailable () {
+		return this.available;
+	}
+
+	/**
+	 * Setter for product availability
+	 *
+	 * @param available Product availability
+	 */
+	@Override
+	public final void setAvailable (final Boolean available) {
+		this.available = available;
+	}
+
 	/**
 	 * Getter for product category
 	 *
 	 * @return Product category
 	 */
 	@Override
-	public final Category getCategory () {
+	public final Long getCategory () {
 		return this.category;
 	}
 
@@ -74,7 +121,7 @@ public class PizzaProduct extends BaseFrameworkSystem implements Product {
 	 * @param category Product category
 	 */
 	@Override
-	public final void setCategory (final Category category) {
+	public final void setCategory (final Long category) {
 		this.category = category;
 	}
 
@@ -131,4 +178,36 @@ public class PizzaProduct extends BaseFrameworkSystem implements Product {
 	public final void setTitle (final String title) {
 		this.title = title;
 	}
+
+	/**
+	 * Compares two categories with each other
+	 *
+	 * @param product Product comparator
+	 * @return Comparison value
+	 */
+	@Override
+	public int compareTo (final Product product) {
+		// Trace message
+		this.getLogger().trace(MessageFormat.format("product={0} - CALLED!", product));
+		
+		// category should not be null
+		if (product == null) {
+			throw new NullPointerException("product is null");
+		}
+
+		// Debug message
+		this.getLogger().debug(MessageFormat.format("this.id={0},product.id={1}", this.getId(), product.getId()));
+
+		// Is the id the same?
+		if (Objects.equals(this.getId(), product.getId())) {
+			// Same id, means same category
+			return 0;
+		} else if (this.getId() > product.getId()) {
+			// This id is larger than compared to
+			return -1;
+		}
+
+		// The other id is larger
+		return 1;
+	}
 }
diff --git a/src/java/org/mxchange/pizzaapplication/product/Product.java b/src/java/org/mxchange/pizzaapplication/product/Product.java
index 6157ad6e..2e17f8c8 100644
--- a/src/java/org/mxchange/pizzaapplication/product/Product.java
+++ b/src/java/org/mxchange/pizzaapplication/product/Product.java
@@ -16,14 +16,14 @@
  */
 package org.mxchange.pizzaapplication.product;
 
-import org.mxchange.pizzaapplication.category.Category;
 import org.mxchange.jcore.database.storage.Storeable;
 
 /**
+ * An interface for in database storeable products
  *
  * @author Roland Haeder
  */
-public interface Product extends Storeable {
+public interface Product extends Storeable, Comparable<Product> {
 	/**
 	 * Getter for id number, suitable for form fields.
 	 * 
@@ -68,12 +68,33 @@ public interface Product extends Storeable {
 	 *
 	 * @return Product category
 	 */
-	public Category getCategory ();
+	public Long getCategory ();
 
 	/**
 	 * Setter for product category
 	 *
 	 * @param category Product category
 	 */
-	public void setCategory (final Category category);
+	public void setCategory (final Long category);
+
+	/**
+	 * Getter for product availability
+	 *
+	 * @return Product availability
+	 */
+	public Boolean getAvailable ();
+
+	/**
+	 * Setter for product availability
+	 *
+	 * @param available Product availability
+	 */
+	public void setAvailable (final Boolean available);
+
+	/**
+	 * Compare method
+	 * @param category Category to compare to
+	 */
+	@Override
+	public int compareTo (final Product category);
 }
diff --git a/web/admin/product.jsp b/web/admin/product.jsp
index 4fa59cbc..9f827724 100644
--- a/web/admin/product.jsp
+++ b/web/admin/product.jsp
@@ -24,12 +24,12 @@
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 		<link rel="stylesheet" href="<%=request.getContextPath()%>/style.css" type="text/css"/>
-		<title><%=PizzaServiceApplication.MAIN_TITLE%> - Bestellung anzeigen</title>
+		<title><%=PizzaServiceApplication.MAIN_TITLE%> - Produkte</title>
 	</head>
 
 	<body>
 		<div id="title">
-			<h1><%=PizzaServiceApplication.MAIN_TITLE%> - Bestellung anzeigen</h1>
+			<h1><%=PizzaServiceApplication.MAIN_TITLE%> - Produkte</h1>
 		</div>
 
 		<jsp:include page="/static/admin/menu.jsp" flush="true" />
@@ -46,7 +46,7 @@
 						<thead class="table_header">
 							<tr>
 								<th class="table_header_column">
-									Produktname: (Schlüssel)
+									Produktnummer:
 								</th>
 								<th class="table_header_column">
 									Produktbezeichnung:
@@ -61,7 +61,7 @@
 						</thead>
 
 						<tbody class="table_body">
-							<c:forEach var="product" items="<%=app.getProducts()%>">
+							<c:forEach var="product" items="<%=app.getAllProducts()%>">
 							<tr>
 								<td>
 									${product.getId()}
@@ -136,6 +136,21 @@
 
 								<div class="clear"></div>
 							</div>
+
+							<div class="data_row">
+								<div class="table_left">
+									Verfügbar?
+								</div>
+
+								<div class="table_right">
+									<select name="available" size="1">
+										<option value="true">Ja</option>
+										<option value="false">Nein</option>
+									</select>
+								</div>
+
+								<div class="clear"></div>
+							</div>
 						</fieldset>
 
 						<div class="table_footer">
diff --git a/web/finished.jsp b/web/finished.jsp
index 3a2430b4..4f574d8b 100644
--- a/web/finished.jsp
+++ b/web/finished.jsp
@@ -66,7 +66,7 @@
 					<tbody class="table_body">
 						<%
 						// Get Iterator
-						Iterator<Product> iterator = app.getProducts();
+						Iterator<Product> iterator = app.getAvailableProducts();
 
 						// "Walk" through all products and unmark them as ordered
 						while (iterator.hasNext()) {
diff --git a/web/form_handler/do_preview.jsp b/web/form_handler/do_preview.jsp
index a1b20cb0..51e5b0cf 100644
--- a/web/form_handler/do_preview.jsp
+++ b/web/form_handler/do_preview.jsp
@@ -21,7 +21,7 @@
 	// Is it post?
 	if ("POST".equals(request.getMethod())) { //NOI18N
 		// Get Iterator
-		Iterator<Product> iterator = app.getProducts();
+		Iterator<Product> iterator = app.getAvailableProducts();
 
 		// "Walk" through all products and unmark them as ordered
 		while (iterator.hasNext()) {
diff --git a/web/index.jsp b/web/index.jsp
index 7dd9458f..31610d6b 100644
--- a/web/index.jsp
+++ b/web/index.jsp
@@ -59,7 +59,7 @@
 					<tbody class="table_body">
 						<%
 						// Get Iterator
-						Iterator<Product> iterator = app.getProducts();
+						Iterator<Product> iterator = app.getAvailableProducts();
 
 						// "Walk" through all products and unmark them as ordered
 						while (iterator.hasNext()) {
diff --git a/web/preview.jsp b/web/preview.jsp
index fb93d386..ca5a32d7 100644
--- a/web/preview.jsp
+++ b/web/preview.jsp
@@ -66,7 +66,7 @@
 					<tbody class="table_body">
 						<%
 						// Get Iterator
-						Iterator<Product> iterator = app.getProducts();
+						Iterator<Product> iterator = app.getAvailableProducts();
 
 						// "Walk" through all products and unmark them as ordered
 						while (iterator.hasNext()) {
-- 
2.39.5