[Characteristics]Apply code review fixes.
authorGorka Ion Damián <gorkaion.damian@openbravo.com>
Mon, 12 Aug 2013 11:13:35 +0200
changeset 20972 3f5e8c7117d6
parent 20971 829a6eeb2e3f
child 20973 8151a5b44678
[Characteristics]Apply code review fixes.
modules/org.openbravo.client.application/src/org/openbravo/client/application/event/UpdateInvariantCharacteristicsHandler.java
modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/CharacteristicsUIDefinition.java
src-db/database/model/functions/C_GENERATESOFROMPROJECTORDER.xml
src-db/database/model/functions/C_GENERATESOFROMPROJECTPHASE.xml
src-db/database/model/functions/C_INVOICE_POST.xml
src-db/database/model/functions/C_ORDER_POST1.xml
src-db/database/model/functions/MA_WORKEFFORT_VALIDATE.xml
src-db/database/model/functions/M_INOUT_POST.xml
src-db/database/model/functions/M_INTERNAL_CONSUMPTION_POST1.xml
src-db/database/model/functions/M_INVENTORY_LISTCREATE.xml
src-db/database/model/functions/M_INVENTORY_POST.xml
src-db/database/model/functions/M_PRODUCTION_RUN.xml
src-db/database/model/functions/M_REQUISITION_POST.xml
src-db/database/model/functions/M_RESERVATION_POST.xml
src-db/database/model/tables/M_PRODUCT_CH.xml
src-db/database/model/tables/M_PRODUCT_CH_VALUE.xml
src-db/database/model/triggers/C_INVLINE_CHK_RESTRICTIONS_TRG.xml
src-db/database/model/triggers/C_ORDLINE_CHK_RESTRICTIONS_TRG.xml
src-db/database/model/triggers/MA_GLOBALUSE_TRG.xml
src-db/database/model/triggers/M_INTERNAL_CONSUMPTIONLINE_TRG.xml
src-db/database/model/triggers/M_INVENTORYLINE2_TRG.xml
src-db/database/model/triggers/M_IOLINE_CHK_RESTRICTIONS_TRG.xml
src-db/database/model/triggers/M_MOVEMENTLINE_TRG.xml
src-db/database/model/triggers/M_PRODUCTIONLINE_TRG.xml
src-db/database/model/triggers/M_REQUISITIONLINE_TRG.xml
src-db/database/model/triggers/M_RESERVATION_TRG.xml
src-db/database/model/triggers/M_STORAGE_DETAIL_TRG.xml
src-db/database/model/triggers/S_TIMEEXPENSELINE_TRG.xml
src-db/database/sourcedata/AD_MESSAGE.xml
src/org/openbravo/common/actionhandler/OrderCreatePOLines.java
src/org/openbravo/event/ProductCharacteristicEventHandler.java
src/org/openbravo/materialmgmt/CharacteristicsUtils.java
src/org/openbravo/materialmgmt/ManageVariantsDS.java
src/org/openbravo/materialmgmt/VariantAutomaticGenerationProcess.java
src/org/openbravo/materialmgmt/VariantChDescUpdateProcess.java
src/org/openbravo/materialmgmt/actionhandler/AddProductsToChValue.java
src/org/openbravo/materialmgmt/actionhandler/ManageVariants.java
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/event/UpdateInvariantCharacteristicsHandler.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/event/UpdateInvariantCharacteristicsHandler.java	Mon Aug 12 11:13:35 2013 +0200
@@ -44,7 +44,7 @@
  * Process in charge of updating the product characteristics
  * 
  * When this process is called with the INITIALIZE action, it will provide the data needed to
- * initializar a popup that displays the invariant characteristics of the provided product
+ * initialize a popup that displays the invariant characteristics of the provided product
  * 
  * This process can also be called with the UPDATE action. In that case, it will update the value of
  * the product invariant characteristics using the provided data
@@ -54,7 +54,8 @@
  * 
  */
 public class UpdateInvariantCharacteristicsHandler extends BaseActionHandler {
-  final static Logger log = LoggerFactory.getLogger(UpdateInvariantCharacteristicsHandler.class);
+  final static private Logger log = LoggerFactory
+      .getLogger(UpdateInvariantCharacteristicsHandler.class);
 
   @Override
   protected JSONObject execute(Map<String, Object> parameters, String content) {
@@ -121,6 +122,7 @@
         final JSONObject updatedValues = request.getJSONObject("updatedValues");
         final JSONObject existingProdChValues = request.getJSONObject("existingProdChValues");
 
+        @SuppressWarnings("unchecked")
         Iterator<String> keysIterator = updatedValues.keys();
         while (keysIterator.hasNext()) {
           String characteristicId = keysIterator.next();
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/CharacteristicsUIDefinition.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/CharacteristicsUIDefinition.java	Mon Aug 12 11:13:35 2013 +0200
@@ -24,6 +24,7 @@
 import org.codehaus.jettison.json.JSONObject;
 import org.openbravo.base.exception.OBException;
 import org.openbravo.client.kernel.RequestContext;
+import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.data.Sqlc;
 import org.openbravo.model.ad.ui.Field;
@@ -45,6 +46,7 @@
   @Override
   public String getFieldProperties(Field field, boolean getValueFromSession) {
     String result = super.getFieldProperties(field, getValueFromSession);
+    OBContext.setAdminMode(true);
     try {
       JSONObject jsnobject = new JSONObject(result);
 
@@ -57,7 +59,6 @@
       String productId = rq.getRequestParameter("inpmProductId");
       Product product = null;
       if (!StringUtils.isEmpty(productId)) {
-        // TODO: admin mode?
         product = OBDal.getInstance().get(Product.class, productId);
       }
       if (product == null) {
@@ -80,6 +81,9 @@
       return jsnobject.toString();
     } catch (JSONException e) {
       throw new OBException("Exception when parsing date ", e);
+    } finally {
+      OBContext.restorePreviousMode();
     }
   }
+
 }
--- a/src-db/database/model/functions/C_GENERATESOFROMPROJECTORDER.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/C_GENERATESOFROMPROJECTORDER.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -128,7 +128,7 @@
             (SELECT * FROM C_PROJECTLINE WHERE C_PROJECT_ID=v_Record_ID)
           LOOP
             IF (solines.m_product_id IS NOT NULL) THEN
-              SELECT COALESCE(isgeneric, 'N'), name INTO v_isgeneric, v_productname
+              SELECT isgeneric, name INTO v_isgeneric, v_productname
               FROM m_product
               WHERE m_product_id = solines.m_product_id;
               IF (v_isgeneric = 'Y') THEN
--- a/src-db/database/model/functions/C_GENERATESOFROMPROJECTPHASE.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/C_GENERATESOFROMPROJECTPHASE.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -192,7 +192,7 @@
           FOR Cur_SOLINES IN
             (
             SELECT 'phase' AS PROV, pp.SEQNO, pp.NAME AS LINE_NAME, pp.DESCRIPTION, pr.NAME AS PRODUCT_NAME, pp.M_PRODUCT_ID, pp.QTY, pp.PRICEACTUAL,
-              COALESCE(pr.isgeneric, 'N') as isgeneric
+              pr.isgeneric
             FROM C_PROJECTPHASE pp, M_PRODUCT pr
             WHERE pp.C_PROJECTPHASE_ID = v_Record_ID
               AND pp.M_PRODUCT_ID = pr.M_PRODUCT_ID
@@ -200,7 +200,7 @@
               AND pp.IsActive = 'Y'
             UNION
             SELECT 'task' as PROV, pt.SEQNO, pt.NAME AS LINE_NAME, pt.DESCRIPTION, pr.NAME AS PRODUCT_NAME, pt.M_PRODUCT_ID, pt.QTY, pt.PRICEACTUAL,
-              COALESCE(pr.isgeneric, 'N') as isgeneric
+              pr.isgeneric
             FROM C_PROJECTTASK pt, C_PROJECTPHASE pp, M_PRODUCT pr
             WHERE pp.C_PROJECTPHASE_ID = v_Record_ID
               AND pp.C_PROJECTPHASE_ID = pt.C_PROJECTPHASE_ID
--- a/src-db/database/model/functions/C_INVOICE_POST.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/C_INVOICE_POST.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -294,11 +294,18 @@
     IF (v_count=0) THEN
       RAISE_APPLICATION_ERROR(-20000, '@InvoicesNeedLines@');
     END IF;
-    SELECT count(*), max(p.name) INTO v_count, v_productname
-    FROM c_invoiceline il JOIN m_product p ON il.m_product_id = p.m_product_id
-    WHERE COALESCE(p.isgeneric, 'N') = 'Y'
-      AND il.c_invoice_id = v_record_id;
+    SELECT count(*) INTO v_count
+    FROM dual
+    WHERE EXISTS (
+        SELECT 1
+        FROM c_invoiceline il JOIN m_product p ON il.m_product_id = p.m_product_id
+        WHERE p.isgeneric = 'Y'
+          AND il.c_invoice_id = v_record_id);
     IF (v_count > 0) THEN
+      SELECT max(p.name) INTO v_productname
+      FROM c_invoiceline il JOIN m_product p ON il.m_product_id = p.m_product_id
+      WHERE p.isgeneric = 'Y'
+        AND il.c_invoice_id = v_record_id;
       RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_productName);
     END IF;
 
--- a/src-db/database/model/functions/C_ORDER_POST1.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/C_ORDER_POST1.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -211,11 +211,18 @@
     SELECT name INTO v_Org_Name FROM AD_ORG WHERE ad_org_id = v_Org_ID;
     DBMS_OUTPUT.PUT_LINE('DocAction=' || v_DocAction || ', DocStatus=' || v_DocStatus || ', DocType_ID=' || v_DocType_ID || ', DocTypeTarget_ID=' || v_DocTypeTarget_ID || ', DocSubTypeSO=' || v_DocSubTypeSO) ;
 
-    SELECT count(*), max(p.name) INTO v_aux, v_productname
-    FROM c_orderline ol JOIN m_product p ON ol.m_product_id = p.m_product_id
-    WHERE ol.c_order_id = v_record_id
-      AND COALESCE(p.isgeneric, 'N') = 'Y';
-    IF (v_aux > 0) THEN
+    SELECT count(*) INTO v_count
+    FROM dual
+    WHERE EXISTS (
+        SELECT 1
+        FROM c_orderline ol JOIN m_product p ON ol.m_product_id = p.m_product_id
+        WHERE ol.c_order_id = v_record_id
+          AND p.isgeneric = 'Y');
+    IF (v_count > 0) THEN
+      SELECT max(p.name) INTO v_productname
+      FROM c_orderline ol JOIN m_product p ON ol.m_product_id = p.m_product_id
+      WHERE ol.c_order_id = v_record_id
+        AND p.isgeneric = 'Y';
       RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_productName);
     END IF;
 
--- a/src-db/database/model/functions/MA_WORKEFFORT_VALIDATE.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/MA_WORKEFFORT_VALIDATE.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -105,13 +105,22 @@
       v_Message:='@WorkEffortValidated@';
       RAISE_APPLICATION_ERROR(-20000, v_Message);
     END IF;
-    SELECT count(*), max(p.name) INTO v_count, v_productname
-    FROM m_productionplan pp
-        JOIN m_productionline pl ON pp.m_productionplan_id = pl.m_productionplan_id
-        JOIN m_product p ON p.m_product_id = pl.m_product_id
-    WHERE pp.m_production_id = v_record_id
-      AND COALESCE(p.isgeneric, 'N') = 'Y';
+    SELECT count(*) INTO v_count
+    FROM dual
+    WHERE EXISTS (
+        SELECT 1
+        FROM m_productionplan pp
+            JOIN m_productionline pl ON pp.m_productionplan_id = pl.m_productionplan_id
+            JOIN m_product p ON p.m_product_id = pl.m_product_id
+        WHERE pp.m_production_id = v_record_id
+          AND p.isgeneric = 'Y');
     IF (v_count > 0) THEN
+      SELECT max(p.name) INTO v_productname
+      FROM m_productionplan pp
+          JOIN m_productionline pl ON pp.m_productionplan_id = pl.m_productionplan_id
+          JOIN m_product p ON p.m_product_id = pl.m_product_id
+      WHERE pp.m_production_id = v_record_id
+        AND p.isgeneric = 'Y';
       RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_productName);
     END IF;
     
--- a/src-db/database/model/functions/M_INOUT_POST.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/M_INOUT_POST.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -262,12 +262,18 @@
         RAISE_APPLICATION_ERROR(-20000, '@ReturnInOutNegativeQty@');
       END IF;
     END IF;
-      SELECT count(*), max(p.name)
-        INTO v_count, v_productname
-      FROM m_inoutline il JOIN m_product p ON il.m_product_id = p.m_product_id
-      WHERE il.m_inout_id = v_record_id
-        AND COALESCE(p.isgeneric, 'N') = 'Y';
+      SELECT count(*) INTO v_count
+      FROM dual
+      WHERE EXISTS (
+          SELECT 1
+          FROM m_inoutline il JOIN m_product p ON il.m_product_id = p.m_product_id
+          WHERE il.m_inout_id = v_record_id
+            AND p.isgeneric = 'Y');
       IF (v_count > 0) THEN
+        SELECT max(p.name) INTO v_productname
+        FROM m_inoutline il JOIN m_product p ON il.m_product_id = p.m_product_id
+        WHERE il.m_inout_id = v_record_id
+          AND p.isgeneric = 'Y';
         RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_productName);
       END IF;
       
--- a/src-db/database/model/functions/M_INTERNAL_CONSUMPTION_POST1.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/M_INTERNAL_CONSUMPTION_POST1.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -115,12 +115,18 @@
     RAISE_APPLICATION_ERROR(-20000, '@InternalConsuptionNoLines@') ;
   END IF;
 
-  SELECT count(*), max(p.name)
-    INTO v_count, v_productname
-  FROM m_internal_consumptionline icl JOIN m_product p ON icl.m_product_id = p.m_product_id
-  WHERE icl.m_internal_consumption_id = record_id
-    AND COALESCE(p.isgeneric, 'N') = 'Y';
+  SELECT count(*) INTO v_count
+  FROM dual
+  WHERE EXISTS (
+      SELECT 1
+      FROM m_internal_consumptionline icl JOIN m_product p ON icl.m_product_id = p.m_product_id
+      WHERE icl.m_internal_consumption_id = record_id
+        AND p.isgeneric = 'Y');
   IF (v_count > 0) THEN
+    SELECT max(p.name) INTO v_productname
+    FROM m_internal_consumptionline icl JOIN m_product p ON icl.m_product_id = p.m_product_id
+    WHERE icl.m_internal_consumption_id = record_id
+      AND p.isgeneric = 'Y';
     RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_productName);
   END IF;
   
--- a/src-db/database/model/functions/M_INVENTORY_LISTCREATE.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/M_INVENTORY_LISTCREATE.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -165,7 +165,7 @@
           FROM M_Product p
           WHERE p.AD_Client_ID=v_Client_ID
             AND IsStocked='Y'
-            AND COALESCE(p.isgeneric, 'N') = 'N'
+            AND p.isgeneric = 'N'
             AND NOT EXISTS
             (SELECT *
             FROM M_Storage_Detail s
@@ -241,7 +241,7 @@
 		 AND COALESCE(QTYORDERONHAND,0) = 0
 		 AND PREQTYONHAND=0
 		 AND COALESCE(PREQTYORDERONHAND,0) = 0) OR v_QtyRange = '=')
-        AND COALESCE(p.isgeneric, 'N') = 'N'
+        AND p.isgeneric = 'N'
       ORDER BY s.M_Locator_ID,
         p.Value,
         s.Created
--- a/src-db/database/model/functions/M_INVENTORY_POST.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/M_INVENTORY_POST.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -133,14 +133,21 @@
     IF v_Count<>0 THEN
       RAISE_APPLICATION_ERROR(-20000, '@Inline@'||' '||v_line||' '||'@productWithoutAttributeSet@') ;
     END IF;
-    SELECT count(*), max(p.name)
-      INTO v_count, v_productname
-    FROM m_inventoryline il JOIN m_product p ON il.m_product_id = p.m_product_id
-    WHERE il.m_inventory_id = v_record_id
-      AND COALESCE(p.isgeneric, 'N') = 'Y';
+    SELECT count(*) INTO v_count
+    FROM dual
+    WHERE EXISTS (
+        SELECT 1
+        FROM m_inventoryline il JOIN m_product p ON il.m_product_id = p.m_product_id
+        WHERE il.m_inventory_id = v_record_id
+          AND p.isgeneric = 'Y');
     IF (v_count > 0) THEN
+      SELECT max(p.name) INTO v_productname
+      FROM m_inventoryline il JOIN m_product p ON il.m_product_id = p.m_product_id
+      WHERE il.m_inventory_id = v_record_id
+        AND p.isgeneric = 'Y';
       RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_productName);
     END IF;
+
   END IF;--PROCESS_ERROR
   IF(NOT PROCESS_ERROR AND NOT END_PROCESS AND NOT END_PROCESSING) THEN
     -- Check for products in multiple lines
--- a/src-db/database/model/functions/M_PRODUCTION_RUN.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/M_PRODUCTION_RUN.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -456,13 +456,22 @@
       v_Message:='@Product@'||' "' ||v_Product_Name ||'" ' || '@ProductWithoutAttributeSet@';
       RAISE_APPLICATION_ERROR(-20000, v_Message);
     END IF;
-    SELECT count(*), max(p.name) INTO v_count, v_product_name
-    FROM m_productionplan pp
-        JOIN m_productionline pl ON pp.m_productionplan_id = pl.m_productionplan_id
-        JOIN m_product p ON pl.m_product_id = p.m_product_id
-    WHERE pp.m_production_id = v_record_id
-      AND COALESCE(p.isgeneric, 'N') = 'Y';
+    SELECT count(*) INTO v_count
+    FROM dual
+    WHERE EXISTS (
+        SELECT 1
+        FROM m_productionplan pp
+            JOIN m_productionline pl ON pp.m_productionplan_id = pl.m_productionplan_id
+            JOIN m_product p ON pl.m_product_id = p.m_product_id
+        WHERE pp.m_production_id = v_record_id
+          AND p.isgeneric = 'Y');
     IF (v_count > 0) THEN
+      SELECT max(p.name) INTO v_product_name
+      FROM m_productionplan pp
+          JOIN m_productionline pl ON pp.m_productionplan_id = pl.m_productionplan_id
+          JOIN m_product p ON pl.m_product_id = p.m_product_id
+      WHERE pp.m_production_id = v_record_id
+        AND p.isgeneric = 'Y';
       RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_product_Name);
     END IF;
 
--- a/src-db/database/model/functions/M_REQUISITION_POST.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/M_REQUISITION_POST.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -107,11 +107,18 @@
       END IF;
     END IF;
 
-    SELECT count(*), max(p.name) INTO v_aux, v_productname
-    FROM m_requisitionline rl JOIN m_product p ON rl.m_product_id = p.m_product_id
-    WHERE rl.m_requisition_id = v_record_id
-      AND COALESCE(p.isgeneric, 'N') = 'Y';
+    SELECT count(*) INTO v_aux
+    FROM dual
+    WHERE EXISTS (
+        SELECT 1
+        FROM m_requisitionline rl JOIN m_product p ON rl.m_product_id = p.m_product_id
+        WHERE rl.m_requisition_id = v_record_id
+          AND p.isgeneric = 'Y');
     IF (v_aux > 0) THEN
+      SELECT max(p.name) INTO v_productname
+      FROM m_requisitionline rl JOIN m_product p ON rl.m_product_id = p.m_product_id
+      WHERE rl.m_requisition_id = v_record_id
+        AND p.isgeneric = 'Y';
       RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_productName);
     END IF;
 
--- a/src-db/database/model/functions/M_RESERVATION_POST.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/functions/M_RESERVATION_POST.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -87,11 +87,18 @@
   FROM m_reservation
   WHERE m_reservation_id = v_reservation_id;
   
-  SELECT count(*), max(p.name) INTO v_count, v_productname
-  FROM m_product p 
-  WHERE p.m_product_id = v_product_id
-    AND COALESCE(p.isgeneric, 'N') = 'Y';
+  SELECT count(*) INTO v_count
+  FROM dual
+  WHERE EXISTS (
+      SELECT 1
+      FROM m_product p 
+      WHERE p.m_product_id = v_product_id
+        AND p.isgeneric = 'Y');
   IF (v_count > 0) THEN
+    SELECT max(p.name) INTO v_productname
+    FROM m_product p 
+    WHERE p.m_product_id = v_product_id
+      AND p.isgeneric = 'Y';
     RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@ ' || v_productName);
   END IF;
   
--- a/src-db/database/model/tables/M_PRODUCT_CH.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/tables/M_PRODUCT_CH.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -80,9 +80,6 @@
         <index-column name="M_PRODUCT_ID"/>
         <index-column name="M_CHARACTERISTIC_ID"/>
       </index>
-      <index name="M_PRODUCT_CH_PRODUCT" unique="false">
-        <index-column name="M_PRODUCT_ID"/>
-      </index>
       <check name="M_PRODUCT_CH_DEFINE_IMAGE_CHK"><![CDATA[DEFINE_IMAGE IN ('Y', 'N')]]></check>
       <check name="M_PRODUCT_CH_DEFINE_PRICE_CHK"><![CDATA[DEFINE_PRICE IN ('Y', 'N')]]></check>
       <check name="M_PRODUCT_CH_ISACTIVE"><![CDATA[ISACTIVE IN ('Y', 'N')]]></check>
--- a/src-db/database/model/tables/M_PRODUCT_CH_VALUE.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/tables/M_PRODUCT_CH_VALUE.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -60,9 +60,6 @@
       <foreign-key foreignTable="M_PRODUCT" name="M_PRODUCT_CH_VALUE_M_PRODUCT">
         <reference local="M_PRODUCT_ID" foreign="M_PRODUCT_ID"/>
       </foreign-key>
-      <index name="M_PRODUCT_CH_VALUE_PRODUCT" unique="false">
-        <index-column name="M_PRODUCT_ID"/>
-      </index>
       <index name="M_PRODUCT_CH_VALUE_VALUE" unique="true">
         <index-column name="M_PRODUCT_ID"/>
         <index-column name="M_CH_VALUE_ID"/>
--- a/src-db/database/model/triggers/C_INVLINE_CHK_RESTRICTIONS_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/C_INVLINE_CHK_RESTRICTIONS_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -104,7 +104,7 @@
     END IF;
     
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/C_ORDLINE_CHK_RESTRICTIONS_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/C_ORDLINE_CHK_RESTRICTIONS_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -99,7 +99,7 @@
     RAISE_APPLICATION_ERROR(-20000, '@20501@') ;
   END IF;
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/MA_GLOBALUSE_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/MA_GLOBALUSE_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -40,7 +40,7 @@
     END IF;
    END IF;
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/M_INTERNAL_CONSUMPTIONLINE_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/M_INTERNAL_CONSUMPTIONLINE_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -89,6 +89,16 @@
     END IF;
    END IF;
   END IF;
+  IF (INSERTING OR UPDATING) THEN
+    IF (:NEW.m_product_id IS NOT NULL) THEN
+      SELECT isgeneric, name INTO v_isgeneric, v_productname
+      FROM m_product
+      WHERE m_product_id = :NEW.m_product_id;
+      IF (v_isgeneric = 'Y') THEN
+        RAISE_APPLICATION_ERROR(-20000, '@CannotUseGenericProduct@');
+      END IF;
+    END IF;
+  END IF;
 
 END M_INTERNAL_CONSUMPTIONLINE_TRG
 ]]></body>
--- a/src-db/database/model/triggers/M_INVENTORYLINE2_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/M_INVENTORYLINE2_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -43,7 +43,7 @@
     :NEW.QuantityOrderBook:=NULL;
   END IF;
  END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/M_IOLINE_CHK_RESTRICTIONS_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/M_IOLINE_CHK_RESTRICTIONS_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -70,7 +70,7 @@
   IF((DELETING OR INSERTING) AND v_Processed='Y') THEN
     RAISE_APPLICATION_ERROR(-20000, '@20501@') ;
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/M_MOVEMENTLINE_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/M_MOVEMENTLINE_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -87,7 +87,7 @@
     END IF;
    END IF;
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/M_PRODUCTIONLINE_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/M_PRODUCTIONLINE_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -140,7 +140,7 @@
     END IF;
    END IF;
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/M_REQUISITIONLINE_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/M_REQUISITIONLINE_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -88,7 +88,7 @@
     END IF;
   END IF;
 
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/M_RESERVATION_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/M_RESERVATION_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -105,7 +105,7 @@
       WHERE c_order_id = v_sales_order_id;
     END IF;
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/M_STORAGE_DETAIL_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/M_STORAGE_DETAIL_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -40,7 +40,7 @@
     END IF;
    END IF;
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/model/triggers/S_TIMEEXPENSELINE_TRG.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/model/triggers/S_TIMEEXPENSELINE_TRG.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -151,7 +151,7 @@
       END IF;
     END IF;
   END IF;
-  IF (INSERTING) THEN
+  IF (INSERTING OR UPDATING) THEN
     IF (:NEW.m_product_id IS NOT NULL) THEN
       SELECT isgeneric, name INTO v_isgeneric, v_productname
       FROM m_product
--- a/src-db/database/sourcedata/AD_MESSAGE.xml	Mon Aug 12 10:36:36 2013 +0200
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml	Mon Aug 12 11:13:35 2013 +0200
@@ -23204,6 +23204,18 @@
 <!--CAC30D6E2AB44791ABC9D8099794685A-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--CAC30D6E2AB44791ABC9D8099794685A--></AD_MESSAGE>
 
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A--><AD_MESSAGE>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <AD_MESSAGE_ID><![CDATA[CB8ACCC0A9574A9380E7CB308DFADA7A]]></AD_MESSAGE_ID>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <VALUE><![CDATA[NewVariantChWithVariantsError]]></VALUE>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <MSGTEXT><![CDATA[It is not possible to add a Variant characteristic to a Generic Product that already has variants created.]]></MSGTEXT>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <MSGTYPE><![CDATA[E]]></MSGTYPE>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--CB8ACCC0A9574A9380E7CB308DFADA7A--></AD_MESSAGE>
+
 <!--CBDF571CAC604569A1BC5A5080806E71--><AD_MESSAGE>
 <!--CBDF571CAC604569A1BC5A5080806E71-->  <AD_MESSAGE_ID><![CDATA[CBDF571CAC604569A1BC5A5080806E71]]></AD_MESSAGE_ID>
 <!--CBDF571CAC604569A1BC5A5080806E71-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src/org/openbravo/common/actionhandler/OrderCreatePOLines.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/src/org/openbravo/common/actionhandler/OrderCreatePOLines.java	Mon Aug 12 11:13:35 2013 +0200
@@ -82,7 +82,6 @@
 
       } catch (Exception e2) {
         log.error(e.getMessage(), e2);
-        // do nothing, give up
       }
     } finally {
       OBContext.restorePreviousMode();
@@ -99,13 +98,13 @@
     obc.add(Restrictions.eq(OrderLine.PROPERTY_SALESORDER, order));
     obc.setProjection(Projections.max(OrderLine.PROPERTY_LINENO));
     Long lineNo = 0L;
-    Object o = obc.list().get(0);
+    Object o = obc.uniqueResult();
     if (o != null) {
       lineNo = (Long) o;
     }
 
-    for (long i = 0; i < selectedLines.length(); i++) {
-      JSONObject selectedLine = selectedLines.getJSONObject((int) i);
+    for (int i = 0; i < selectedLines.length(); i++) {
+      JSONObject selectedLine = selectedLines.getJSONObject(i);
       log.debug("{}", selectedLine);
 
       OrderLine newOrderLine = OBProvider.getInstance().get(OrderLine.class);
--- a/src/org/openbravo/event/ProductCharacteristicEventHandler.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/src/org/openbravo/event/ProductCharacteristicEventHandler.java	Mon Aug 12 11:13:35 2013 +0200
@@ -61,6 +61,9 @@
     }
     final ProductCharacteristic prCh = (ProductCharacteristic) event.getTargetInstance();
     if (prCh.isVariant() && prCh.getProduct().isGeneric()) {
+      if (!prCh.getProduct().getProductGenericProductList().isEmpty()) {
+        throw new OBException(OBMessageUtils.messageBD("NewVariantChWithVariantsError"));
+      }
       if (prCh.isDefinesPrice()) {
         // Check there is only 1.
         for (ProductCharacteristic prChAux : prCh.getProduct().getProductCharacteristicList()) {
@@ -98,8 +101,14 @@
     }
     final ProductCharacteristic prCh = (ProductCharacteristic) event.getTargetInstance();
     if (prCh.isVariant() && prCh.getProduct().isGeneric()) {
-      if (!prCh.getProduct().getProductGenericProductList().isEmpty()) {
-        // throw new OBException();
+      final Entity prodCharEntity = ModelProvider.getInstance().getEntity(
+          ProductCharacteristic.ENTITY_NAME);
+      final Property variantProperty = prodCharEntity
+          .getProperty(ProductCharacteristic.PROPERTY_VARIANT);
+      boolean oldIsVariant = (Boolean) event.getPreviousState(variantProperty);
+
+      if (!prCh.getProduct().getProductGenericProductList().isEmpty() && !oldIsVariant) {
+        throw new OBException(OBMessageUtils.messageBD("NewVariantChWithVariantsError"));
       }
       if (prCh.isDefinesPrice()) {
         // Check there is only 1.
@@ -117,8 +126,6 @@
           }
         }
       }
-      final Entity prodCharEntity = ModelProvider.getInstance().getEntity(
-          ProductCharacteristic.ENTITY_NAME);
 
       final Property charConfListProperty = prodCharEntity
           .getProperty(ProductCharacteristic.PROPERTY_PRODUCTCHARACTERISTICCONFLIST);
--- a/src/org/openbravo/materialmgmt/CharacteristicsUtils.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/src/org/openbravo/materialmgmt/CharacteristicsUtils.java	Mon Aug 12 11:13:35 2013 +0200
@@ -64,11 +64,7 @@
     obCriteria.add(Restrictions.eq(ProductCharacteristicValue.PROPERTY_CHARACTERISTIC,
         characteristic));
     obCriteria.setMaxResults(1);
-    if (obCriteria.count() > 0) {
-      return ((ProductCharacteristicValue) obCriteria.uniqueResult());
-    } else {
-      return null;
-    }
+    return (ProductCharacteristicValue) obCriteria.uniqueResult();
   }
 
   private static void setCharacteristic(Product product, Characteristic characteristic) {
--- a/src/org/openbravo/materialmgmt/ManageVariantsDS.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/src/org/openbravo/materialmgmt/ManageVariantsDS.java	Mon Aug 12 11:13:35 2013 +0200
@@ -65,7 +65,7 @@
   @Override
   protected List<Map<String, Object>> getData(Map<String, String> parameters, int startRow,
       int endRow) {
-    OBContext.setAdminMode();
+    OBContext.setAdminMode(true);
     final List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
     try {
       readCriteria(parameters);
@@ -92,7 +92,6 @@
             ProductCharacteristicConf.class);
         prChConfCrit.add(Restrictions.eq(
             ProductCharacteristicConf.PROPERTY_CHARACTERISTICOFPRODUCT, prCh));
-        prChConfCrit.add(Restrictions.eq(ProductCharacteristicConf.PROPERTY_ACTIVE, true));
         List<ProductCharacteristicConf> prChConfs = prChConfCrit.list();
         long valuesCount = prChConfs.size();
 
@@ -177,8 +176,7 @@
         for (i = 0; i < chNumber; i++) {
           ProductCharacteristicConf prChConf = currentValues[i];
           Characteristic characteristic = prChConf.getCharacteristicOfProduct().getCharacteristic();
-          where.append(buildExistsClause(characteristic.getId(), prChConf.getCharacteristicValue()
-              .getId()));
+          where.append(buildExistsClause(i));
           if (StringUtils.isNotBlank(strChDesc)) {
             strChDesc += ", ";
           }
@@ -198,6 +196,12 @@
         OBQuery<Product> variantQry = OBDal.getInstance().createQuery(Product.class,
             where.toString());
         variantQry.setNamedParameter("product", product);
+        for (i = 0; i < chNumber; i++) {
+          ProductCharacteristicConf prChConf = currentValues[i];
+          Characteristic characteristic = prChConf.getCharacteristicOfProduct().getCharacteristic();
+          variantQry.setNamedParameter("ch" + i, characteristic.getId());
+          variantQry.setNamedParameter("chvalue" + i, prChConf.getCharacteristicValue().getId());
+        }
         Product existingProduct = variantQry.uniqueResult();
         if (existingProduct != null) {
           variantMap.put("name", existingProduct.getName());
@@ -303,15 +307,15 @@
     }
   }
 
-  private String buildExistsClause(String strChId, String strChValueId) {
+  private String buildExistsClause(int i) {
     StringBuffer clause = new StringBuffer();
     clause.append(" and exists (select 1 from " + ProductCharacteristicValue.ENTITY_NAME
         + " as pcv");
     clause.append("    where pcv." + ProductCharacteristicValue.PROPERTY_PRODUCT + " = p");
-    clause.append("      and pcv." + ProductCharacteristicValue.PROPERTY_CHARACTERISTIC + ".id = '"
-        + strChId + "'");
+    clause.append("      and pcv." + ProductCharacteristicValue.PROPERTY_CHARACTERISTIC
+        + ".id = :ch" + i);
     clause.append("      and pcv." + ProductCharacteristicValue.PROPERTY_CHARACTERISTICVALUE
-        + ".id = '" + strChValueId + "'");
+        + ".id = :chvalue" + i);
     clause.append("     )");
     return clause.toString();
   }
--- a/src/org/openbravo/materialmgmt/VariantAutomaticGenerationProcess.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/src/org/openbravo/materialmgmt/VariantAutomaticGenerationProcess.java	Mon Aug 12 11:13:35 2013 +0200
@@ -87,7 +87,6 @@
             ProductCharacteristicConf.class);
         prChConfCrit.add(Restrictions.eq(
             ProductCharacteristicConf.PROPERTY_CHARACTERISTICOFPRODUCT, prCh));
-        prChConfCrit.add(Restrictions.eq(ProductCharacteristicConf.PROPERTY_ACTIVE, true));
         List<ProductCharacteristicConf> prChConfs = prChConfCrit.list();
         long valuesCount = prChConfs.size();
 
@@ -254,7 +253,7 @@
     }
   }
 
-  private class ProductCharacteristicAux {
+  private static class ProductCharacteristicAux {
     private boolean useCode;
     private boolean isIteratorReset;
     private List<ProductCharacteristicConf> values;
--- a/src/org/openbravo/materialmgmt/VariantChDescUpdateProcess.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/src/org/openbravo/materialmgmt/VariantChDescUpdateProcess.java	Mon Aug 12 11:13:35 2013 +0200
@@ -95,7 +95,7 @@
    *          assigned.
    */
   public void update(String strProductId, String strChValueId) {
-    OBContext.setAdminMode(false);
+    OBContext.setAdminMode(true);
     try {
       if (StringUtils.isNotBlank(strProductId)) {
         Product product = OBDal.getInstance().get(Product.class, strProductId);
@@ -119,7 +119,6 @@
       if (StringUtils.isNotBlank(strChValueId)) {
         productQuery.setNamedParameter("chvid", strChValueId);
       }
-      productQuery.setFetchSize(1000);
       productQuery.setFilterOnReadableOrganization(false);
       productQuery.setFilterOnActive(false);
 
--- a/src/org/openbravo/materialmgmt/actionhandler/AddProductsToChValue.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/src/org/openbravo/materialmgmt/actionhandler/AddProductsToChValue.java	Mon Aug 12 11:13:35 2013 +0200
@@ -43,7 +43,7 @@
 import org.slf4j.LoggerFactory;
 
 public class AddProductsToChValue extends BaseProcessActionHandler {
-  final static Logger log = LoggerFactory.getLogger(AddProductsToChValue.class);
+  final static private Logger log = LoggerFactory.getLogger(AddProductsToChValue.class);
 
   @Override
   protected JSONObject doExecute(Map<String, Object> parameters, String content) {
--- a/src/org/openbravo/materialmgmt/actionhandler/ManageVariants.java	Mon Aug 12 10:36:36 2013 +0200
+++ b/src/org/openbravo/materialmgmt/actionhandler/ManageVariants.java	Mon Aug 12 11:13:35 2013 +0200
@@ -50,7 +50,7 @@
 import org.slf4j.LoggerFactory;
 
 public class ManageVariants extends BaseProcessActionHandler {
-  final static Logger log = LoggerFactory.getLogger(ManageVariants.class);
+  final static private Logger log = LoggerFactory.getLogger(ManageVariants.class);
 
   @Override
   protected JSONObject doExecute(Map<String, Object> parameters, String content) {
@@ -96,7 +96,6 @@
         jsonRequest.put("message", errorMessage);
       } catch (Exception e2) {
         log.error(e.getMessage(), e2);
-        // do nothing, give up
       }
     } finally {
       OBContext.restorePreviousMode();