You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by nm...@apache.org on 2014/11/08 22:00:55 UTC

svn commit: r1637596 - in /ofbiz/trunk/framework/service: config/ServiceErrorUiLabels.xml servicedef/services_test_se.xml src/org/ofbiz/service/engine/EntityAutoEngine.java src/org/ofbiz/service/test/ServiceEntityAutoTests.java

Author: nmalin
Date: Sat Nov  8 21:00:55 2014
New Revision: 1637596

URL: http://svn.apache.org/r1637596
Log:
Manage multi pk with sub-sequence on entity-auto (OFBIZ-5800), 

Add the possibility to the entity-auto engine on the create action to manage entities with more than 2 primary keys which one is under sub sequence or fromDate, like PerfReview (employeePartyId, employeeRoleTypeId, perfReviewId) or PartyQual (partyId, partyQualTypeId, fromDate).

Improve return message for the create action if the entity value exist and the delete action if the entity value not exist instead of the database message error.

Modified:
    ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml
    ofbiz/trunk/framework/service/servicedef/services_test_se.xml
    ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
    ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java

Modified: ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml?rev=1637596&r1=1637595&r2=1637596&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml (original)
+++ ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml Sat Nov  8 21:00:55 2014
@@ -272,11 +272,22 @@
         <value xml:lang="zh">缺少参数</value>
         <value xml:lang="zh_TW">缺少參數</value>
     </property>
+    <property key="ServiceValueFound">
+        <value xml:lang="en">Value found (with ids ${pkFields}), cannot create a new one</value>
+        <value xml:lang="fr">La valeur a été trouvée (avec les réfs. ${pkFields}), une nouvelle ne peut donc pas être créée</value>
+        <value xml:lang="it">Valore troavato, non è possibile creare</value>
+    </property>
     <property key="ServiceValueNotFound">
         <value xml:lang="en">Value not found, cannot update</value>
+        <value xml:lang="fr">La valeur n'a pas été trouvée, elle ne peut donc pas être mise à jour</value>
         <value xml:lang="it">Valore non troavato, non è possibile aggiornare</value>
         <value xml:lang="ja">値が見つかりません。更新できません</value>
         <value xml:lang="zh">没有找到值,无法更新</value>
         <value xml:lang="zh_TW">沒有找到值,無法更新</value>
     </property>
+    <property key="ServiceValueNotFoundForRemove">
+        <value xml:lang="en">Value not found, cannot remove</value>
+        <value xml:lang="fr">La valeur n'a pas été trouvée, suppression impossible</value>
+        <value xml:lang="it">Valore non troavato, non è possibile sopprimere</value>
+    </property>
 </resource>

Modified: ofbiz/trunk/framework/service/servicedef/services_test_se.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/servicedef/services_test_se.xml?rev=1637596&r1=1637595&r2=1637596&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/servicedef/services_test_se.xml (original)
+++ ofbiz/trunk/framework/service/servicedef/services_test_se.xml Sat Nov  8 21:00:55 2014
@@ -80,7 +80,7 @@ under the License.
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <attribute name="testingId" mode="IN" type="String"/>
         <attribute name="testingNodeId" mode="IN" type="String"/>
-        <attribute name="fromDate" mode="OUT" type="String"/>
+        <attribute name="fromDate" mode="OUT" type="Timestamp"/>
     </service>
     <service name="testEntityAutoUpdateTesting" auth="false"
         engine="entity-auto" default-entity-name="Testing" invoke="update">

Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java?rev=1637596&r1=1637595&r2=1637596&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java (original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java Sat Nov  8 21:00:55 2014
@@ -20,6 +20,7 @@ package org.ofbiz.service.engine;
 
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.Locale;
 import java.util.Map;
 
@@ -88,11 +89,16 @@ public final class EntityAutoEngine exte
 
         try {
             boolean allPksInOnly = true;
+            LinkedList<String> pkFieldNameOutOnly = null;
             for (ModelField pkField: modelEntity.getPkFieldsUnmodifiable()) {
                 ModelParam pkParam = modelService.getParam(pkField.getName());
                 if (pkParam.isOut()) {
                     allPksInOnly = false;
                 }
+                if (pkParam.isOut() && !pkParam.isIn()) {
+                    if (pkFieldNameOutOnly == null) pkFieldNameOutOnly = new LinkedList();
+                    pkFieldNameOutOnly.add(pkField.getName());
+                }
             }
 
             if ("create".equals(modelService.invoke)) {
@@ -128,7 +134,6 @@ public final class EntityAutoEngine exte
                     }
                 }
 
-
                 if (isSinglePk && isSinglePkOut && !isSinglePkIn) {
                     /*
                      **** primary sequenced primary key ****
@@ -145,7 +150,6 @@ public final class EntityAutoEngine exte
 
                     String sequencedId = dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
                     newEntity.set(singlePkModeField.getName(), sequencedId);
-                    result.put(singlePkModelParam.name, sequencedId);
                 } else if (isSinglePk && isSinglePkOut && isSinglePkIn) {
                     /*
                      **** primary sequenced key with optional override passed in ****
@@ -181,7 +185,6 @@ public final class EntityAutoEngine exte
                         }
                     }
                     newEntity.set(singlePkModeField.getName(), pkValue);
-                    result.put(singlePkModelParam.name, pkValue);
                 } else if (isDoublePk && doublePkPrimaryInParam != null && doublePkSecondaryOutParam != null) {
                     /*
                      **** secondary sequenced primary key ****
@@ -199,7 +202,6 @@ public final class EntityAutoEngine exte
 
                     newEntity.setPKFields(parameters, true);
                     dctx.getDelegator().setNextSubSeqId(newEntity, doublePkSecondaryOutField.getName(), 5, 1);
-                    result.put(doublePkSecondaryOutParam.name, newEntity.get(doublePkSecondaryOutField.getName()));
                 } else if (allPksInOnly) {
                     /*
                      **** plain specified primary key ****
@@ -213,24 +215,46 @@ public final class EntityAutoEngine exte
                      *
                      */
                     newEntity.setPKFields(parameters, true);
+                    //with all pks present on parameters, check if the entity is not already exists.
+                    GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false, true, null, null);
+                    if (lookedUpValue != null) {
+                        return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceValueFound", UtilMisc.toMap("pkFields", newEntity.getPkShortValueString()), locale));
+                    }
                 } else {
-                    throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the create invoke option: " +
-                            "could not find a valid combination of primary key settings to do a known create operation; options include: " +
-                            "1. a single OUT pk for primary auto-sequencing, " +
-                            "2. a single INOUT pk for primary auto-sequencing with optional override, " +
-                            "3. a 2-part pk with one part IN (existing primary pk) and one part OUT (the secdonary pk to sub-sequence, " +
-                            "4. all pk fields are IN for a manually specified primary key");
+                    /* We haven't all Pk and their are 3 or more, now check if isn't a associate entity with own sequence
+                    <set-pk-fields map="parameters" value-field="newEntity"/>
+                    <sequenced-id sequence-name="ExempleItemAssoc" field="newEntity.exempleItemAssocId"/>
+                    <create-value value-field="newEntity"/>
+                     */
+                    if (pkFieldNameOutOnly != null && pkFieldNameOutOnly.size() == 1) {
+                        newEntity.setPKFields(parameters, true);
+                        String pkFieldName = pkFieldNameOutOnly.getFirst();
+                        //if it's a fromDate, don't update it now, it's will be done next step
+                        if (! "fromDate".equals(pkFieldName)) { 
+                            String pkValue = dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
+                            newEntity.set(pkFieldName, pkValue);
+                        }
+                    } else {
+                        throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the create invoke option: " +
+                                "could not find a valid combination of primary key settings to do a known create operation; options include: " +
+                                "1. a single OUT pk for primary auto-sequencing, " +
+                                "2. a single INOUT pk for primary auto-sequencing with optional override, " +
+                                "3. a 2-part pk with one part IN (existing primary pk) and one part OUT (the secondary pk to sub-sequence), " +
+                                "4. a N-part pk with N-1 part IN and one party OUT only (missing pk is a sub-sequence mainly for entity assoc), " +
+                                "5. all pk fields are IN for a manually specified primary key");
+                    }
                 }
 
                 // handle the case where there is a fromDate in the pk of the entity, and it is optional or undefined in the service def, populate automatically
                 ModelField fromDateField = modelEntity.getField("fromDate");
                 if (fromDateField != null && fromDateField.getIsPk()) {
                     ModelParam fromDateParam = modelService.getParam("fromDate");
-                    if (fromDateParam == null || (fromDateParam.isOptional() && parameters.get("fromDate") == null)) {
+                    if (fromDateParam == null || parameters.get("fromDate") == null) {
                         newEntity.set("fromDate", UtilDateTime.nowTimestamp());
                     }
                 }
 
+                newEntity.setNonPKFields(parameters, true);
                 if (modelEntity.getField("createdDate") != null) {
                     newEntity.set("createdDate", UtilDateTime.nowTimestamp());
                     if (modelEntity.getField("createdByUserLogin") != null) {
@@ -246,8 +270,8 @@ public final class EntityAutoEngine exte
                         newEntity.set("lastModifiedDate", UtilDateTime.nowTimestamp());
                     }
                 }
-                newEntity.setNonPKFields(parameters, true);
                 newEntity.create();
+                result.putAll(modelService.makeValid(newEntity, "OUT"));
             } else if ("update".equals(modelService.invoke)) {
                 /*
                 <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -313,9 +337,9 @@ public final class EntityAutoEngine exte
                         }
                     }
                 }
-
                 // NOTE: nothing here to maintain the status history, that should be done with a custom service called by SECA rule
 
+                lookedUpValue.setNonPKFields(parameters, true);
                 if (modelEntity.getField("lastModifiedDate") != null) {
                     lookedUpValue.set("lastModifiedDate", UtilDateTime.nowTimestamp());
                     if (modelEntity.getField("lastModifiedByUserLogin") != null) {
@@ -325,8 +349,6 @@ public final class EntityAutoEngine exte
                         }
                     }
                 }
-
-                lookedUpValue.setNonPKFields(parameters, true);
                 lookedUpValue.store();
             } else if ("delete".equals(modelService.invoke)) {
                 /*
@@ -344,6 +366,8 @@ public final class EntityAutoEngine exte
                 GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false, true, null, null);
                 if (lookedUpValue != null) {
                     lookedUpValue.remove();
+                } else {
+                    return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceValueNotFoundForRemove", locale));
                 }
             }
         } catch (GeneralException e) {

Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java?rev=1637596&r1=1637595&r2=1637596&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java (original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java Sat Nov  8 21:00:55 2014
@@ -104,11 +104,10 @@ public class ServiceEntityAutoTests exte
         testingNodeMember.remove();
 
         //test create auto sub-sequence
-        //test missing pk
+        //test missing pk fromDate
         Map<String, Object> testingNodeMemberPkMissingMap = UtilMisc.toMap("testingId", "TESTING_3", "testingNodeId", "NODE_1");
         results = dispatcher.runSync("testEntityAutoCreateTestingNodeMemberPkMissing", testingNodeMemberPkMissingMap, 10, true);
-        assertTrue(ServiceUtil.isError(results));
-        assertTrue(ServiceUtil.getErrorMessage(results).contains("1. a single OUT pk for primary auto-sequencing"));
+        assertTrue(ServiceUtil.isSuccess(results));
     }
 
     public void testEntityAutoUpdateEntity() throws Exception {
@@ -141,7 +140,7 @@ public class ServiceEntityAutoTests exte
         //test create with bad pk
         Map<String, Object> testingDeleteFailedMap = UtilMisc.toMap("testingId", "TESTING_5_FAILED");
         results = dispatcher.runSync("testEntityAutoRemoveTesting", testingDeleteFailedMap);
-        assertTrue(ServiceUtil.isSuccess(results));
-        //assertEquals(UtilProperties.getMessage("ServiceErrorUiLabels", "ServiceValueNotFound", Locale.ENGLISH), ServiceUtil.getErrorMessage(results));
+        assertTrue(ServiceUtil.isError(results));
+        assertEquals(UtilProperties.getMessage("ServiceErrorUiLabels", "ServiceValueNotFoundForRemove", Locale.ENGLISH), ServiceUtil.getErrorMessage(results));
     }
 }