]> git.mxchange.org Git - jfinancials-war.git/commitdiff
Maybe cherry-pick:
authorRoland Häder <roland@mxchange.org>
Sat, 4 Nov 2017 00:16:54 +0000 (01:16 +0100)
committerRoland Häder <roland@mxchange.org>
Sat, 4 Nov 2017 11:35:49 +0000 (12:35 +0100)
- renamed product -> generic_product
- renamed category -> product_category
- added validators for both product/category i18n keys as direct titles are not
  localizable
- added product manufacturer with is a connection to basic_data entity
- general controller may have reusable methods like allFoos() or
  isFooI18nKeyAdded(), by exposing them in corresponding interface, they can be
  accessed by the administrative bean to check if entity Foo is really not
  there.
- code convention applied: in comparison, first value then variable

Signed-off-by: Roland Häder <roland@mxchange.org>
19 files changed:
src/java/org/mxchange/jfinancials/beans/generic_product/FinancialAdminProductWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/generic_product/FinancialProductWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/generic_product/FinancialProductWebRequestController.java
src/java/org/mxchange/jfinancials/beans/product_category/FinancialAdminCategoryWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/product_category/FinancialCategoryWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/product_category/FinancialCategoryWebRequestController.java
src/java/org/mxchange/jfinancials/converter/generic_product/FinancialsGenericProductConverter.java
src/java/org/mxchange/jfinancials/converter/product_category/FinancialsProductCategoryConverter.java
src/java/org/mxchange/jfinancials/validator/generic_product/FinancialsGenericProductValidator.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/validator/product_category/FinancialsProductCategoryValidator.java [new file with mode: 0644]
web/WEB-INF/faces-config.xml
web/WEB-INF/resources/tags/admin/links/mini/category/admin_product_category_links.tpl [deleted file]
web/WEB-INF/resources/tags/admin/links/mini/generic_product/admin_generic_product_links.tpl [new file with mode: 0644]
web/WEB-INF/resources/tags/admin/links/mini/product/admin_generic_product_links.tpl [deleted file]
web/WEB-INF/resources/tags/admin/links/mini/product_category/admin_product_category_links.tpl [new file with mode: 0644]
web/WEB-INF/resources/tags/input/panel_grid/generic_product/product_price_input_panel_grid.tpl [new file with mode: 0644]
web/WEB-INF/resources/tags/input/panel_grid/product/product_price_input_panel_grid.tpl [deleted file]
web/WEB-INF/templates/admin/generic_product/admin_form_product_data.tpl
web/WEB-INF/templates/admin/product_category/admin_form_category_data.tpl

index 14ee0cc48618321010e68c1bcbfa4e8e21782d01..e405fad363d6a4e77c444c1bddd36a79280ba42c 100644 (file)
@@ -23,6 +23,7 @@ import javax.enterprise.inject.Any;
 import javax.faces.view.facelets.FaceletException;
 import javax.inject.Inject;
 import javax.inject.Named;
+import org.mxchange.jcontactsbusiness.model.basicdata.BasicData;
 import org.mxchange.jfinancials.beans.BaseFinancialsBean;
 import org.mxchange.jproduct.events.product.AddedProductEvent;
 import org.mxchange.jproduct.events.product.ProductAddedEvent;
@@ -73,6 +74,11 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl
         */
        private Float productGrossPrice;
 
+       /**
+        * Product's manufacturing/producing company
+        */
+       private BasicData productManufacturer;
+
        /**
         * Product's net price
         */
@@ -84,6 +90,12 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl
        @EJB (lookup = "java:global/jfinancials-ejb/adminProduct!org.mxchange.jproduct.model.product.AdminProductSessionBeanRemote")
        private AdminProductSessionBeanRemote adminProductBean;
 
+       /**
+        * General product controller
+        */
+       @Inject
+       private FinancialProductWebRequestController productController;
+
        /**
         * Product's tax rate
         */
@@ -118,6 +130,12 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl
         * @throws FaceletException If something unexpected happened
         */
        public void addProduct () throws FaceletException {
+               // Is product i18n key already used?
+               if (this.productController.isProductI18nKeyAdded(this.getProductI18nKey())) {
+                       // Then throw exception
+                       throw new FaceletException("Product i18n key " + this.getProductI18nKey() + " already added.");
+               }
+
                // Create product instance
                final Product product = this.createProductInstance();
 
@@ -211,6 +229,24 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl
                this.productGrossPrice = productGrossPrice;
        }
 
+       /**
+        * Getter for product's manufacturing/producing company
+        * <p>
+        * @return Product's manufacturing/producing company
+        */
+       public BasicData getProductManufacturer () {
+               return this.productManufacturer;
+       }
+
+       /**
+        * Setter for product's manufacturing/producing company
+        * <p>
+        * @param productManufacturer Product's manufacturing/producing company
+        */
+       public void setProductManufacturer (final BasicData productManufacturer) {
+               this.productManufacturer = productManufacturer;
+       }
+
        /**
         * Getter for product's net price
         * <p>
@@ -307,10 +343,11 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl
        private void clear () {
                this.setProductAvailability(Boolean.FALSE);
                this.setProductCategory(null);
-               this.setProductNetPrice(null);
-               this.setProductTaxRate(null);
                this.setProductGrossPrice(null);
                this.setProductI18nKey(null);
+               this.setProductNetPrice(null);
+               this.setProductManufacturer(null);
+               this.setProductTaxRate(null);
                this.setProductUnitAmount(null);
                this.setProductUnitType(null);
        }
@@ -326,6 +363,7 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl
 
                // Set all optional fields
                product.setProductNetPrice(this.getProductNetPrice());
+               product.setProductManufacturer(this.getProductManufacturer());
                product.setProductTaxRate(this.getProductTaxRate());
                product.setProductUnitAmount(this.getProductUnitAmount());
                product.setProductUnitType(this.getProductUnitType());
index 55ec53258f9573c69e7e5b10daed454d996fd50c..ba765fddbec8cc7bedac57ded61b0eca9c53ca31 100644 (file)
@@ -22,6 +22,7 @@ import java.util.Comparator;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Objects;
 import javax.annotation.PostConstruct;
 import javax.cache.Cache;
 import javax.ejb.EJB;
@@ -53,7 +54,7 @@ public class FinancialProductWebRequestBean extends BaseFinancialsBean implement
        /**
         * List for all products
         */
-       private List<Product> allProducts;
+       private final List<Product> allProducts;
 
        /**
         * List for filtered products
@@ -91,7 +92,7 @@ public class FinancialProductWebRequestBean extends BaseFinancialsBean implement
         * <p>
         * @todo Move this to own controller
         */
-       public void afterProductAdded (@Observes final AddedProductEvent event) {
+       public void afterProductAddedEvent (@Observes final AddedProductEvent event) {
                // Is all valid?
                if (null == event) {
                        // Throw NPE
@@ -107,11 +108,9 @@ public class FinancialProductWebRequestBean extends BaseFinancialsBean implement
                        throw new IllegalArgumentException(MessageFormat.format("event.addedProduct.productId={0} is not valid.", event.getAddedProduct().getProductId())); //NOI18N
                }
 
-               // Is the product available?
-               if (event.getAddedProduct().getProductAvailability()) {
-                       // Add it
-                       this.allProducts.add(event.getAddedProduct());
-               }
+               // Add it
+               this.productCache.put(event.getAddedProduct().getProductId(), event.getAddedProduct());
+               this.allProducts.add(event.getAddedProduct());
        }
 
        @Override
@@ -129,7 +128,7 @@ public class FinancialProductWebRequestBean extends BaseFinancialsBean implement
                        throw new NullPointerException("productId is null"); //NOI18N
                } else if (productId < 1) {
                        // Throw IAE
-                       throw new IllegalArgumentException("productId=" + productId + " is invalid"); //NOI18N
+                       throw new IllegalArgumentException("productId=" + productId + " is invalid"); //NOI18N //NOI18N
                } else if (!this.productCache.containsKey(productId)) {
                        // Not found
                        throw new ProductNotFoundException(productId);
@@ -204,4 +203,32 @@ public class FinancialProductWebRequestBean extends BaseFinancialsBean implement
                }
        }
 
+       @Override
+       public boolean isProductI18nKeyAdded (final String productI18nKey) {
+               // Validate parameter
+               if (null == productI18nKey) {
+                       // Throw NPE
+                       throw new NullPointerException("productI18nKey is null"); //NOI18N
+               } else if (productI18nKey.isEmpty()) {
+                       // Throw IAE
+                       throw new IllegalArgumentException("productI18nKey is empty"); //NOI18N
+               }
+
+               // Default is not the same
+               boolean isFound = false;
+
+               // Check all added,products
+               for (final Product product : this.allProducts()) {
+                       // Is i18n key the same?
+                       if (Objects.equals(product.getProductI18nKey(), productI18nKey)) {
+                               // Found it
+                               isFound = true;
+                               break;
+                       }
+               }
+
+               // Return flag
+               return isFound;
+       }
+
 }
index 7dbe48cca660397b301534dd1635eeae9fc97618..52490c107453efab2d5873e010b9b4b2b6199e5a 100644 (file)
@@ -31,6 +31,15 @@ import org.mxchange.jproduct.model.product.Product;
 @Local
 public interface FinancialProductWebRequestController extends Serializable {
 
+       /**
+        * Checks whether the given product i18n key has already used.
+        * <p>
+        * @param productI18nKey Product i18n key
+        * <p>
+        * @return Whether the i18n key has been used
+        */
+       boolean isProductI18nKeyAdded (final String productI18nKey);
+
        /**
         * Some "getter" for a linked list of only available products
         * <p>
index fb45265ac7ae69d6e3fc248b434957db125c49a1..4c8a31ae12605c3aaace81d7abf22aee066e35a0 100644 (file)
@@ -58,6 +58,12 @@ public class FinancialAdminCategoryWebRequestBean extends BaseFinancialsBean imp
        @EJB (lookup = "java:global/jfinancials-ejb/adminCategory!org.mxchange.jproduct.model.category.AdminCategorySessionBeanRemote")
        private AdminCategorySessionBeanRemote categoryBean;
 
+       /**
+        * General category controller
+        */
+       @Inject
+       private FinancialCategoryWebRequestController categoryController;
+
        /**
         * Whether this category is shown in statistics
         */
@@ -84,10 +90,15 @@ public class FinancialAdminCategoryWebRequestBean extends BaseFinancialsBean imp
        /**
         * Adds given category data from request to database
         * <p>
-        * @throws javax.faces.view.facelets.FaceletException If something
-        * unexpected happened
+        * @throws FaceletException If something unexpected happened
         */
        public void addCategory () throws FaceletException {
+               // Is i18n key already used?
+               if (this.categoryController.isCategoryI18nKeyAdded(this.getCategoryI18nKey())) {
+                       // Throw exception
+                       throw new FaceletException("Category i18n key " + this.getCategoryI18nKey() + " is already used.");
+               }
+
                // Create category
                final Category category = this.createCategoryInstance();
 
index 3dac53be33144aad1bc2fcdb74a2ca5e63976472..6fec05267c67a07e4f046921805064721402f7dc 100644 (file)
@@ -22,6 +22,7 @@ import java.util.Comparator;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Objects;
 import javax.annotation.PostConstruct;
 import javax.cache.Cache;
 import javax.ejb.EJB;
@@ -88,7 +89,7 @@ public class FinancialCategoryWebRequestBean extends BaseFinancialsBean implemen
         * <p>
         * @param event Event to be observed
         */
-       public void afterShopCategoryAdded (@Observes final AddedCategoryEvent event) {
+       public void afterCategoryAddedEvent (@Observes final AddedCategoryEvent event) {
                // Is all valid?
                if (null == event) {
                        // Throw NPE
@@ -105,6 +106,7 @@ public class FinancialCategoryWebRequestBean extends BaseFinancialsBean implemen
                }
 
                // Add the category
+               this.categoryCache.put(event.getAddedCategory().getCategoryId(), event.getAddedCategory());
                this.allCategories.add(event.getAddedCategory());
        }
 
@@ -202,4 +204,32 @@ public class FinancialCategoryWebRequestBean extends BaseFinancialsBean implemen
                }
        }
 
+       @Override
+       public boolean isCategoryI18nKeyAdded (final String categoryI18nKey) {
+               // Validate parameter
+               if (null == categoryI18nKey) {
+                       // Throw NPE
+                       throw new NullPointerException("categoryI18nKey is null"); //NOI18N
+               } else if (categoryI18nKey.isEmpty()) {
+                       // Throw IAE
+                       throw new IllegalArgumentException("categoryI18nKey is empty"); //NOI18N
+               }
+
+               // Default is not the same
+               boolean isFound = false;
+
+               // Check all added,products
+               for (final Category category : this.allCategories()) {
+                       // Is i18n key the same?
+                       if (Objects.equals(category.getCategoryI18nKey(), categoryI18nKey)) {
+                               // Found it
+                               isFound = true;
+                               break;
+                       }
+               }
+
+               // Return flag
+               return isFound;
+       }
+
 }
index 69fde5ee8caac3185be62318cf1eb97382b9333e..b2bfca38d046cd6fb9d6661b7a93db7938330943 100644 (file)
@@ -40,4 +40,14 @@ public interface FinancialCategoryWebRequestController extends Serializable {
         */
        Category findCategoryById (final Long categoryId) throws CategoryNotFoundException;
 
+       /**
+        * Checks whether given category i18n key has already been used.
+        * <p>
+        * @param categoryI18nKey Category i18n key
+        * <p>
+        * @return Whether i18n key is already added
+        * <p>
+        */
+       boolean isCategoryI18nKeyAdded (final String categoryI18nKey);
+
 }
index 4c78bd34719ca3196c38d6b3e989acde730346cd..68452ea877e049e17b3a754ef617f219a4e164de 100644 (file)
@@ -43,7 +43,7 @@ public class FinancialsGenericProductConverter implements Converter<Product> {
        @Override
        public Product getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
                // Is the instance there?
-               if (PRODUCT_CONTROLLER == null) {
+               if (null == PRODUCT_CONTROLLER) {
                        // Get bean from CDI directly
                        PRODUCT_CONTROLLER = CDI.current().select(FinancialProductWebRequestBean.class).get();
                }
index 4978f233a3e28205580cce3f858a601b2a5ba559..025ec3a12d019d9e0fb59b3076a5b4d742ff1ad6 100644 (file)
@@ -43,7 +43,7 @@ public class FinancialsProductCategoryConverter implements Converter<Category> {
        @Override
        public Category getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) {
                // Is the instance there?
-               if (CATEGORY_CONTROLLER == null) {
+               if (null == CATEGORY_CONTROLLER) {
                        // Get bean from CDI directly
                        CATEGORY_CONTROLLER = CDI.current().select(FinancialCategoryWebRequestBean.class).get();
                }
diff --git a/src/java/org/mxchange/jfinancials/validator/generic_product/FinancialsGenericProductValidator.java b/src/java/org/mxchange/jfinancials/validator/generic_product/FinancialsGenericProductValidator.java
new file mode 100644 (file)
index 0000000..dd633d7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.validator.generic_product;
+
+import java.text.MessageFormat;
+import javax.enterprise.inject.spi.CDI;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.FacesValidator;
+import javax.faces.validator.ValidatorException;
+import org.mxchange.jcoreee.validator.string.BaseStringValidator;
+import org.mxchange.jfinancials.beans.generic_product.FinancialProductWebRequestBean;
+import org.mxchange.jfinancials.beans.generic_product.FinancialProductWebRequestController;
+
+/**
+ * A validator for generic products, will fail when product i18n key is already
+ * used.
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@FacesValidator (value = "GenericProductValidator")
+public class FinancialsGenericProductValidator extends BaseStringValidator {
+
+       /**
+        * Backing bean for product categories
+        */
+       private static FinancialProductWebRequestController PRODUCT_CONTROLLER;
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 1_086_256_763_716_450L;
+
+       @Override
+       public void validate (final FacesContext context, final UIComponent component, final Object productI18nKey) throws ValidatorException {
+               // The required field
+               final String[] requiredFields = {"categoryI18nKey"}; //NOI18N
+
+               // Pre-validate it
+               super.preValidate(context, component, productI18nKey, requiredFields, Boolean.FALSE);
+
+               // Is the instance there?
+               if (null == PRODUCT_CONTROLLER) {
+                       // Then get it from CDI
+                       PRODUCT_CONTROLLER = CDI.current().select(FinancialProductWebRequestBean.class).get();
+               }
+
+               // Check, if the name has already been used
+               if (PRODUCT_CONTROLLER.isProductI18nKeyAdded((String) productI18nKey)) {
+                       // Create message
+                       final String message = MessageFormat.format("I18n key {0} is already used. Please type an other.", productI18nKey);
+
+                       // Throw exception
+                       throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_WARN, message, message));
+               }
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/validator/product_category/FinancialsProductCategoryValidator.java b/src/java/org/mxchange/jfinancials/validator/product_category/FinancialsProductCategoryValidator.java
new file mode 100644 (file)
index 0000000..4da8099
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.validator.product_category;
+
+import java.text.MessageFormat;
+import javax.enterprise.inject.spi.CDI;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.FacesValidator;
+import javax.faces.validator.ValidatorException;
+import org.mxchange.jcoreee.validator.string.BaseStringValidator;
+import org.mxchange.jfinancials.beans.product_category.FinancialCategoryWebRequestBean;
+import org.mxchange.jfinancials.beans.product_category.FinancialCategoryWebRequestController;
+
+/**
+ * A validator for product categories, will fail when category i18n key is
+ * already used.
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@FacesValidator(value = "ProductCategoryValidator")
+public class FinancialsProductCategoryValidator extends BaseStringValidator {
+
+       /**
+        * Backing bean for product categories
+        */
+       private static FinancialCategoryWebRequestController CATEGORY_CONTROLLER;
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 1_086_256_763_716_450L;
+
+       @Override
+       public void validate (final FacesContext context, final UIComponent component, final Object categoryI18nKey) throws ValidatorException {
+               // The required field
+               final String[] requiredFields = {"categoryI18nKey"}; //NOI18N
+
+               // Pre-validate it
+               super.preValidate(context, component, categoryI18nKey, requiredFields, Boolean.FALSE);
+
+               // Is the instance there?
+               if (null == CATEGORY_CONTROLLER) {
+                       // Then get it from CDI
+                       CATEGORY_CONTROLLER = CDI.current().select(FinancialCategoryWebRequestBean.class).get();
+               }
+
+               // Check, if the name has already been used
+               if (CATEGORY_CONTROLLER.isCategoryI18nKeyAdded((String) categoryI18nKey)) {
+                       // Create message
+                       final String message = MessageFormat.format("I18n key {0} is already used. Please type an other.", categoryI18nKey);
+
+                       // Throw exception
+                       throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_WARN, message, message));
+               }
+       }
+
+}
index 2a0b620329f529b61681fccf20f4ceaf126e94e6..442d848ac3ae675f6d0d40fd2cf2067082a70dc9 100644 (file)
                        <from-outcome>admin_delete_generic_product</from-outcome>
                        <to-view-id>/admin/generic_product/admin_generic_product_delete.xhtml</to-view-id>
                </navigation-case>
+               <navigation-case>
+                       <from-outcome>admin_show_product_category</from-outcome>
+                       <to-view-id>/admin/product_category/admin_product_category_show.xhtml</to-view-id>
+               </navigation-case>
        </navigation-rule>
        <!--
        <factory>
diff --git a/web/WEB-INF/resources/tags/admin/links/mini/category/admin_product_category_links.tpl b/web/WEB-INF/resources/tags/admin/links/mini/category/admin_product_category_links.tpl
deleted file mode 100644 (file)
index b988c21..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-       xmlns="http://www.w3.org/1999/xhtml"
-       xmlns:f="http://java.sun.com/jsf/core"
-       xmlns:h="http://java.sun.com/jsf/html"
-       xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-       xmlns:p="http://primefaces.org/ui">
-
-       <ui:fragment rendered="#{empty rendered or rendered}">
-               <ul class="navbar-mini">
-                       <ui:fragment rendered="#{empty renderShowLink or renderShowLink}">
-                               <li class="navlink-mini">
-                                       <p:link outcome="admin_show_product_category" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_PRODUCT_CATEGORY_TITLE}">
-                                               <f:param name="categoryId" value="#{category.categoryId}" />
-                                       </p:link>
-                               </li>
-                       </ui:fragment>
-
-                       <li class="navlink-mini">
-                               <p:link outcome="admin_edit_product_category" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_PRODUCT_CATEGORY_TITLE}">
-                                       <f:param name="categoryId" value="#{category.categoryId}" />
-                               </p:link>
-                       </li>
-
-                       <li class="navlink-mini">
-                               <p:link outcome="admin_delete_product_category">
-                                       <h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_PRODUCT_CATEGORY_TITLE}" />
-                                       <f:param name="categoryId" value="#{category.categoryId}" />
-                               </p:link>
-                       </li>
-               </ul>
-       </ui:fragment>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/links/mini/generic_product/admin_generic_product_links.tpl b/web/WEB-INF/resources/tags/admin/links/mini/generic_product/admin_generic_product_links.tpl
new file mode 100644 (file)
index 0000000..4ac5d9f
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<ui:composition
+       xmlns="http://www.w3.org/1999/xhtml"
+       xmlns:f="http://java.sun.com/jsf/core"
+       xmlns:h="http://java.sun.com/jsf/html"
+       xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
+       xmlns:p="http://primefaces.org/ui">
+
+       <ui:fragment rendered="#{empty rendered or rendered}">
+               <ul class="navbar-mini">
+                       <ui:fragment rendered="#{empty renderShowLink or renderShowLink}">
+                               <li class="navlink-mini">
+                                       <p:link outcome="admin_show_generic_product" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_GENERIC_PRODUCT_TITLE}">
+                                               <f:param name="productId" value="#{product.productId}" />
+                                       </p:link>
+                               </li>
+                       </ui:fragment>
+
+                       <li class="navlink-mini">
+                               <p:link outcome="admin_edit_generic_product" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_GENERIC_PRODUCT_TITLE}">
+                                       <f:param name="productId" value="#{product.productId}" />
+                               </p:link>
+                       </li>
+
+                       <li class="navlink-mini">
+                               <p:link outcome="admin_delete_generic_product">
+                                       <h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_GENERIC_PRODUCT_TITLE}" />
+                                       <f:param name="productId" value="#{product.productId}" />
+                               </p:link>
+                       </li>
+               </ul>
+       </ui:fragment>
+</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/links/mini/product/admin_generic_product_links.tpl b/web/WEB-INF/resources/tags/admin/links/mini/product/admin_generic_product_links.tpl
deleted file mode 100644 (file)
index 8d748ae..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition
-       xmlns="http://www.w3.org/1999/xhtml"
-       xmlns:f="http://java.sun.com/jsf/core"
-       xmlns:h="http://java.sun.com/jsf/html"
-       xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-       xmlns:p="http://primefaces.org/ui">
-
-       <ui:fragment rendered="#{empty rendered or rendered}">
-               <ul class="navbar-mini">
-                       <ui:fragment rendered="#{empty renderShowLink or renderShowLink}">
-                               <li class="navlink-mini">
-                                       <p:link outcome="admin_show_product" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_GENERIC_PRODUCT_TITLE}">
-                                               <f:param name="productId" value="#{product.productId}" />
-                                       </p:link>
-                               </li>
-                       </ui:fragment>
-
-                       <li class="navlink-mini">
-                               <p:link outcome="admin_edit_product" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_GENERIC_PRODUCT_TITLE}">
-                                       <f:param name="productId" value="#{product.productId}" />
-                               </p:link>
-                       </li>
-
-                       <li class="navlink-mini">
-                               <p:link outcome="admin_delete_product">
-                                       <h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_GENERIC_PRODUCT_TITLE}" />
-                                       <f:param name="productId" value="#{product.productId}" />
-                               </p:link>
-                       </li>
-               </ul>
-       </ui:fragment>
-</ui:composition>
diff --git a/web/WEB-INF/resources/tags/admin/links/mini/product_category/admin_product_category_links.tpl b/web/WEB-INF/resources/tags/admin/links/mini/product_category/admin_product_category_links.tpl
new file mode 100644 (file)
index 0000000..b988c21
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<ui:composition
+       xmlns="http://www.w3.org/1999/xhtml"
+       xmlns:f="http://java.sun.com/jsf/core"
+       xmlns:h="http://java.sun.com/jsf/html"
+       xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
+       xmlns:p="http://primefaces.org/ui">
+
+       <ui:fragment rendered="#{empty rendered or rendered}">
+               <ul class="navbar-mini">
+                       <ui:fragment rendered="#{empty renderShowLink or renderShowLink}">
+                               <li class="navlink-mini">
+                                       <p:link outcome="admin_show_product_category" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_PRODUCT_CATEGORY_TITLE}">
+                                               <f:param name="categoryId" value="#{category.categoryId}" />
+                                       </p:link>
+                               </li>
+                       </ui:fragment>
+
+                       <li class="navlink-mini">
+                               <p:link outcome="admin_edit_product_category" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_PRODUCT_CATEGORY_TITLE}">
+                                       <f:param name="categoryId" value="#{category.categoryId}" />
+                               </p:link>
+                       </li>
+
+                       <li class="navlink-mini">
+                               <p:link outcome="admin_delete_product_category">
+                                       <h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_PRODUCT_CATEGORY_TITLE}" />
+                                       <f:param name="categoryId" value="#{category.categoryId}" />
+                               </p:link>
+                       </li>
+               </ul>
+       </ui:fragment>
+</ui:composition>
diff --git a/web/WEB-INF/resources/tags/input/panel_grid/generic_product/product_price_input_panel_grid.tpl b/web/WEB-INF/resources/tags/input/panel_grid/generic_product/product_price_input_panel_grid.tpl
new file mode 100644 (file)
index 0000000..4dfc544
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- @TODO Hard-coded values below -->
+<ui:composition
+       xmlns="http://www.w3.org/1999/xhtml"
+       xmlns:f="http://java.sun.com/jsf/core"
+       xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
+       xmlns:p="http://primefaces.org/ui">
+
+       <p:panelGrid layout="grid" columns="3" columnClasses="ui-grid-col-5,ui-grid-col-2,ui-grid-col-5" styleClass="table table-full ui-noborder" rendered="#{empty rendered or rendered == true}">
+               <p:outputLabel for="productNetPrice" value="#{project.ENTER_NET_PRICE}" />
+
+               <p:outputLabel for="productTaxRate" value="#{project.ENTER_TAX_RATE}" />
+
+               <p:outputLabel for="productGrossPrice" value="#{project.ENTER_GROSS_PRICE}" />
+
+               <p:inputNumber
+                       id="productNetPrice"
+                       title="#{project.ENTER_PRODUCT_NET_PRICE_TITLE}"
+                       value="#{targetController.productNetPrice}"
+                       symbol=" EUR"
+                       symbolPosition="s"
+                       decimalSeparator=","
+                       thousandSeparator="."
+                       >
+               </p:inputNumber>
+
+               <p:inputNumber
+                       id="productTaxRate"
+                       title="#{project.ENTER_PRODUCT_TAX_RATE_TITLE}"
+                       value="#{targetController.productTaxRate}"
+                       symbol="%"
+                       symbolPosition="s"
+                       thousandSeparator="."
+                       decimalSeparator=","
+                       emptyValue="sign"
+                       >
+                       <f:validateDoubleRange minimum="0" maximum="100" />
+               </p:inputNumber>
+
+               <p:inputNumber
+                       id="productGrossPrice"
+                       title="#{project.ENTER_PRODUCT_GROSS_PRICE_TITLE}"
+                       value="#{targetController.productGrossPrice}"
+                       symbol=" EUR"
+                       symbolPosition="s"
+                       decimalSeparator=","
+                       thousandSeparator="."
+                       required="true"
+                       requiredMessage="#{project.PRODUCT_GROSS_PRICE_REQUIRED}"
+                       >
+               </p:inputNumber>
+       </p:panelGrid>
+</ui:composition>
diff --git a/web/WEB-INF/resources/tags/input/panel_grid/product/product_price_input_panel_grid.tpl b/web/WEB-INF/resources/tags/input/panel_grid/product/product_price_input_panel_grid.tpl
deleted file mode 100644 (file)
index 4dfc544..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!-- @TODO Hard-coded values below -->
-<ui:composition
-       xmlns="http://www.w3.org/1999/xhtml"
-       xmlns:f="http://java.sun.com/jsf/core"
-       xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
-       xmlns:p="http://primefaces.org/ui">
-
-       <p:panelGrid layout="grid" columns="3" columnClasses="ui-grid-col-5,ui-grid-col-2,ui-grid-col-5" styleClass="table table-full ui-noborder" rendered="#{empty rendered or rendered == true}">
-               <p:outputLabel for="productNetPrice" value="#{project.ENTER_NET_PRICE}" />
-
-               <p:outputLabel for="productTaxRate" value="#{project.ENTER_TAX_RATE}" />
-
-               <p:outputLabel for="productGrossPrice" value="#{project.ENTER_GROSS_PRICE}" />
-
-               <p:inputNumber
-                       id="productNetPrice"
-                       title="#{project.ENTER_PRODUCT_NET_PRICE_TITLE}"
-                       value="#{targetController.productNetPrice}"
-                       symbol=" EUR"
-                       symbolPosition="s"
-                       decimalSeparator=","
-                       thousandSeparator="."
-                       >
-               </p:inputNumber>
-
-               <p:inputNumber
-                       id="productTaxRate"
-                       title="#{project.ENTER_PRODUCT_TAX_RATE_TITLE}"
-                       value="#{targetController.productTaxRate}"
-                       symbol="%"
-                       symbolPosition="s"
-                       thousandSeparator="."
-                       decimalSeparator=","
-                       emptyValue="sign"
-                       >
-                       <f:validateDoubleRange minimum="0" maximum="100" />
-               </p:inputNumber>
-
-               <p:inputNumber
-                       id="productGrossPrice"
-                       title="#{project.ENTER_PRODUCT_GROSS_PRICE_TITLE}"
-                       value="#{targetController.productGrossPrice}"
-                       symbol=" EUR"
-                       symbolPosition="s"
-                       decimalSeparator=","
-                       thousandSeparator="."
-                       required="true"
-                       requiredMessage="#{project.PRODUCT_GROSS_PRICE_REQUIRED}"
-                       >
-               </p:inputNumber>
-       </p:panelGrid>
-</ui:composition>
index 2587060e29b878f0d36edb502b740d66c5f9490f..772b573a1b07337d8607a66bb163ba54613fccf6 100644 (file)
                                required="true"
                                requiredMessage="#{project.ADMIN_PRODUCT_I18N_KEY_REQUIRED}"
                                title="#{project.ADMIN_ENTER_PRODUCT_I18N_KEY_TITLE}"
-                               />
+                               validatorMessage="#{project.ADMIN_ENTERED_PRODUCT_I18N_KEY_ALREADY_ADDED}"
+                               >
+                               <f:validator validatorId="GenericProductValidator" />
+                       </p:inputText>
+
+                       <p:outputLabel for="productManufacturer" value="#{project.ADMIN_ASSIGN_PRODUCT_MANUFACTURER}" />
+                       <p:selectOneMenu
+                               id="productManufacturer"
+                               value="#{adminProductController.productManufacturer}"
+                               filter="true"
+                               filterMatchMode="contains"
+                               title="#{project.ADMIN_ASSIGN_PRODUCT_MANUFACTURER_TITLE}"
+                               >
+                               <f:converter converterId="BasicCompanyDataConverter" />
+                               <f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" />
+                               <f:selectItems value="#{basicCompanyDataController.allBasicData()}" var="basicData" itemValue="#{basicData}" itemLabel="#{basicData.companyName}" />
+                       </p:selectOneMenu>
 
                        <p:outputLabel for="productAvailability" value="#{project.ADMIN_ENABLE_PRODUCT_AVAILABILITY}" />
                        <p:selectBooleanCheckbox
index c4d265cda56b3ca7e2ea5ae216bf70f12662b125..313124f102a59f77e55083e7c84e45a55ba73ce7 100644 (file)
                                required="true"
                                requiredMessage="#{project.ADMIN_CATEGORY_I18N_KEY_REQUIRED}"
                                title="#{project.ADMIN_ENTER_CATEGORY_I18N_KEY_TITLE}"
-                               />
+                               validatorMessage="#{project.ADMIN_ENTERED_CATEGORY_I18N_KEY_ALREADY_ADDED}"
+                               >
+                               <f:validator validatorId="ProductCategoryValidator" />
+                       </p:inputText>
 
                        <p:outputLabel for="categoryShownInStatistics" value="#{project.ADMIN_ENABLE_CATEGORY_IN_STATISTICS}" />
                        <p:selectBooleanCheckbox