Thanks for reviewing Scott,

From: "Scott Gray" <[email protected]>
Hi Jacques,

I haven't reviewed the actual logic but a few comments inline.

Regards
Scott

HotWax Media
http://www.hotwaxmedia.com

On 27/12/2009, at 12:21 AM, [email protected] wrote:

Author: jleroux
Date: Sat Dec 26 11:21:21 2009
New Revision: 893961

URL: http://svn.apache.org/viewvc?rev=893961&view=rev
Log:
* Introduces a new createUpdatePartyRelationshipAndRoles service
* Cleans imports of PartyHelper.java
* A new getActivePartyRelationships method in new  PartyRelationshipHelper class
* A new checkPartyType method in new PartyTypeHelper class

Added:
   ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipHelper.java   (with props)
   ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyTypeHelper.java   (with props)
Modified:
   ofbiz/trunk/applications/party/servicedef/services.xml
   ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ PartyHelper.java
   ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipServices.java

Modified: ofbiz/trunk/applications/party/servicedef/services.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/servicedef/services.xml?rev=893961&r1=893960&r2=893961&view=diff
= = = = = = = = 
======================================================================
--- ofbiz/trunk/applications/party/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/party/servicedef/services.xml Sat Dec  26 11:21:21 
2009
@@ -351,6 +351,22 @@
        <auto-attributes include="nonpk" mode="IN" optional="true"/>
        <override name="partyRelationshipName" optional="false"/>
    </service>
+
+    <service name="createUpdatePartyRelationshipAndRoles"  engine="java" 
default-entity-name="PartyRelationship"
+        location="org.ofbiz.party.party.PartyRelationshipServices"  
invoke="createUpdatePartyRelationshipAndRoles" auth="true">
+        <description>
+            Create or update both parties roles and parties  relationship, 
partyRelationshipTypeId being mandatory.
+            The relationship is considered from one side or another  (partyId 
is checked internally against partyIdFrom)
+            If a type of parties relationship exists PartyIdTo or  PartyIdFrom 
are updated.
+            The history is maintained, allowing to track changes.
+        </description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <attribute name="partyId" type="String" mode="IN"  optional="false"/>
+        <override name="partyId" optional="false"/>

This partyId override seems redundant

Yes, should be removed

+        <override name="fromDate" optional="true"/>
+    </service>
+

    <service name="createPartyRelationshipContactAccount"  engine="simple"
        location="component://party/script/org/ofbiz/party/party/ 
PartyServices.xml"
invoke="createPartyRelationshipContactAccount"  auth="true">

Modified: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyHelper.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyHelper.java?rev=893961&r1=893960&r2=893961&view=diff
= = = = = = = = 
======================================================================
--- ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ PartyHelper.java 
(original)
+++ ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ PartyHelper.java 
Sat Dec 26 11:21:21 2009
@@ -19,20 +19,13 @@

package org.ofbiz.party.party;

-import java.util.Locale;
-import java.util.Map;
-
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilFormatOut;
import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.model.ModelEntity;
-import org.ofbiz.security.Security;
-import org.ofbiz.service.ModelService;
-import org.ofbiz.service.ServiceUtil;

/**
 * PartyHelper

Added: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipHelper.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyRelationshipHelper.java?rev=893961&view=auto
= = = = = = = = 
======================================================================
--- ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipHelper.java (added)
+++ ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipHelper.java Sat Dec 26 11:21:21 2009
@@ -0,0 +1,85 @@
+/ 
*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+  
*******************************************************************************/
+
+package org.ofbiz.party.party;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Map;
+
+import javolution.util.FastList;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilDateTime;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.condition.EntityOperator;
+
+/**
+ * PartyRelationshipHelper
+ */
+public class PartyRelationshipHelper {
+
+    public static final String module =  
PartyRelationshipHelper.class.getName();
+
+    /** Return A List of the active Party Relationships (ie with  valid from 
and thru dates)
+     *...@param delegator needed Delegator
+     *...@param partyRelationshipValues Map containing the input  parameters 
(primaries keys + partyRelationshipTypeId)
+     *...@return List of the active Party Relationships
+     */
+    public static List<GenericValue>  getActivePartyRelationships(Delegator 
delegator, Map<String, ?>  partyRelationshipValues)
{
+        String partyIdFrom = (String)  
partyRelationshipValues.get("partyIdFrom") ;
+        String partyIdTo = (String)  partyRelationshipValues.get("partyIdTo") ;
+        String roleTypeIdFrom = (String)  
partyRelationshipValues.get("roleTypeIdFrom") ;
+        String roleTypeIdTo = (String)  
partyRelationshipValues.get("roleTypeIdTo") ;
+        String partyRelationshipTypeId = (String)  
partyRelationshipValues.get("partyRelationshipTypeId") ;
+        Timestamp fromDate = UtilDateTime.nowTimestamp();
+
+        List<EntityCondition> condList = FastList.newInstance();
+        condList.add(EntityCondition.makeCondition("partyIdFrom",  
partyIdFrom));
+        condList.add(EntityCondition.makeCondition("partyIdTo",  partyIdTo));
+         condList.add(EntityCondition.makeCondition("roleTypeIdFrom",  
roleTypeIdFrom));
+        condList.add(EntityCondition.makeCondition("roleTypeIdTo",  
roleTypeIdTo));
+         condList 
.add(EntityCondition.makeCondition("partyRelationshipTypeId",  
partyRelationshipTypeId));
+        condList.add(EntityCondition.makeCondition("fromDate",  
EntityOperator.LESS_THAN_EQUAL_TO, fromDate));
+        EntityCondition thruCond =  
EntityCondition.makeCondition(UtilMisc.toList(
+                EntityCondition.makeCondition("thruDate", null),
+                EntityCondition.makeCondition("thruDate",  
EntityOperator.GREATER_THAN, fromDate)),
+                EntityOperator.OR);
+        condList.add(thruCond);

EntityUtil has some methods for filtering by fromDate/thruDate which  makes 
this a bit easier

Ha yes, EntityUtil.getFilterByDateExpr()

+        EntityCondition condition =  EntityCondition.makeCondition(condList);
+
+        List<GenericValue> partyRelationships = null;
+        try {
+            partyRelationships =  delegator.findList("PartyRelationship", 
condition, null, null, null,  false);
+        } catch (GenericEntityException e) {
+            Debug.logError(e, "Problem finding PartyRelationships.  ", module);
+            return null;
+        }
+        if (UtilValidate.isNotEmpty(partyRelationships)) {
+           return partyRelationships;
+        } else {
+            return null;
+        }
+    }
+}

Propchange: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipHelper.java
------------------------------------------------------------------------------
   svn:eol-style = native

Propchange: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipHelper.java
------------------------------------------------------------------------------
   svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipHelper.java
------------------------------------------------------------------------------
   svn:mime-type = text/plain

Modified: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipServices.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyRelationshipServices.java?rev=893961&r1=893960&r2=893961&view=diff
= = = = = = = = 
======================================================================
--- ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipServices.java (original)
+++ ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyRelationshipServices.java Sat Dec 26 11:21:21 2009
@@ -1,15 +1,15 @@
/ 
*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
+ * Licensed partyIdTo the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
+ * partyIdTo you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
- * Unless required by applicable law or agreed to in writing,
+ * Unless required by applicable law or agreed partyIdTo in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the

Unintended changes in the license?

Yes, I saw them but forgot to remove

@@ -19,20 +19,27 @@

package org.ofbiz.party.party;

+import java.util.List;
import java.util.Map;

import javolution.util.FastMap;

import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.security.Security;
import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ModelService;
import org.ofbiz.service.ServiceUtil;

+
/**
 * Services for Party Relationship maintenance
 */
@@ -52,7 +59,7 @@
        Security security = ctx.getSecurity();
        GenericValue userLogin = (GenericValue)  context.get("userLogin");

-        String partyId =  ServiceUtil.getPartyIdCheckSecurity(userLogin, security, context,  
result, "PARTYMGR", "_CREATE");
+        ServiceUtil.getPartyIdCheckSecurity(userLogin, security,  context, result, 
"PARTYMGR", "_CREATE");

        if (result.size() > 0)
            return result;
@@ -85,4 +92,68 @@
        result.put(ModelService.RESPONSE_MESSAGE,  
ModelService.RESPOND_SUCCESS);
        return result;
    }
+
+    /** Creates and updates a PartyRelationship creating related  PartyRoles 
if needed.
+     *  A side of the relationship is checked to maintain history
+     *...@param ctx The DispatchContext that this service is operating  in
+     *...@param context Map containing the input parameters
+     *...@return Map with the result of the service, the output  parameters
+     */
+    public static Map<String, Object>  
createUpdatePartyRelationshipAndRoles(DispatchContext ctx,  Map<String, ? extends 
Object>
context) {
+        Map<String, Object> result = FastMap.newInstance();
+        Delegator delegator = ctx.getDelegator();
+        LocalDispatcher dispatcher = ctx.getDispatcher();
+
+        try {
+            List<GenericValue> partyRelationShipList =  
PartyRelationshipHelper.getActivePartyRelationships(delegator,
context);

Ship in relationship shouldn't be camel cased

Yes

+            if (UtilValidate.isEmpty(partyRelationShipList)) { //  If already 
exists and active nothing to do: keep the current
one
+                String partyId = (String) context.get("partyId") ;
+                String partyIdFrom = (String)  context.get("partyIdFrom") ;
+                String partyIdTo = (String)  context.get("partyIdTo") ;
+                String roleTypeIdFrom = (String)  
context.get("roleTypeIdFrom") ;
+                String roleTypeIdTo = (String)  context.get("roleTypeIdTo") ;
+                String partyRelationshipTypeId = (String)  
context.get("partyRelationshipTypeId") ;
+
+                // Before creating the partyRelationShip, create  the 
partyRoles if they don't exist
+                GenericValue partyToRole = null;
+                partyToRole = delegator.findOne("PartyRole",  UtilMisc.toMap("partyId", 
partyIdTo, "roleTypeId", roleTypeIdTo),
false);
+                if (partyToRole == null) {
+                    partyToRole = delegator.makeValue("PartyRole",  
UtilMisc.toMap("partyId", partyIdTo, "roleTypeId",
roleTypeIdTo));
+                    partyToRole.create();

You should always use the services provided to create entities and not  create 
the records yourself

Yes it's definitely better to use createPartyRole (there are some other 
instances in OFBiz which should be also changed)

+                }
+
+                GenericValue partyFromRole= null;
+                partyFromRole = delegator.findOne("PartyRole",  
UtilMisc.toMap("partyId", partyIdFrom, "roleTypeId",
roleTypeIdFrom), false);
+                if (partyFromRole == null) {
+                    partyFromRole =  delegator.makeValue("PartyRole", 
UtilMisc.toMap("partyId",  partyIdFrom, "roleTypeId",
roleTypeIdFrom));
+                    partyFromRole.create();
+                }
+
+                // Check if there is already a partyRelationship of  that type 
with another party from the side indicated
+                String sideChecked = partyIdFrom.equals(partyId)?  "partyIdFrom" : 
"partyIdTo";
+                partyRelationShipList =  
delegator.findByAnd("PartyRelationship", UtilMisc.toMap(sideChecked,  partyId,
+                        "roleTypeIdFrom", roleTypeIdFrom,
+                        "roleTypeIdTo", roleTypeIdTo,
+                        "partyRelationshipTypeId",  partyRelationshipTypeId));
+                // We consider the last one (in time) as sole  active (we try 
to maintain a unique relationship and keep changes
history)
+                partyRelationShipList =  
EntityUtil.filterByDate(partyRelationShipList);
+                GenericValue oldPartyRelationShip =  
EntityUtil.getFirst(partyRelationShipList);
+                if (UtilValidate.isNotEmpty(oldPartyRelationShip)) {
+                         
oldPartyRelationShip.setFields(UtilMisc.toMap("thruDate",  
UtilDateTime.nowTimestamp())); // Current
becomes inactive
+                        oldPartyRelationShip.store();

Should be using the crud services but this also seems strange, it  looks like 
your expiring the existing PartyRelationship by only
considering one party rather than both?

My requirements are simple
Create or update an active (valid from/thru dates) PartyRelationship and also 
create PartyRoles if needed.
I always consider the PartyRelationship from one side. I update when I change 
only one side of the PartyRelationship, I create when
it's totally new.
I'm only interested by the most recent active PartyRelationship between 2 
parties.
I looked at createPartyRelationshipAndRole but as it was only creating one 
PartyRole, I decided to write a new service

Coding
I created and use PartyRelationshipHelper.getActivePartyRelationships at top of 
the code block to bypass if an active relationship
exist (any sides change). Because I don't want to change the from and thru 
dates.
Else I create the PartyRoles if needed and check if there is a 
PartyRelationship with another party from the side indicated (either
from or to) I use <<String sideChecked = partyIdFrom.equals(partyId)? "partyIdFrom" : 
"partyIdTo";>> for that. Where partyId is the
side I'm interested in.

If there is one PartyRelationship (with another party), I expire it before 
creating the new PartyRelationship. Maybe it's too
specific to be in OFBiz, because it suppose that there is only one active 
PartyRelationship for 2 parties...

Also David does not like the way it's done. I will consider his advice 
(simple-method service implementation, and a couple of SECA
rules) though I'm not quite sure how to do it  right now.

Jacques

+                }
+                try {
+                    dispatcher.runSync("createPartyRelationship",  context); 
// Create new one

I'm guessing this will fail if a partyId was supplied to the calling  service 
since createPartyRelationship doesn't take a
parameter named  partyId.  If you want to do a passthru you should really get 
the  service model and call the makeValid instance
method.

partyId is not supposed to be passed to createPartyRelationship


+                } catch (GenericServiceException e) {
+                    Debug.logWarning(e.getMessage(), module);
+                    return ServiceUtil.returnError("Could not  create party 
relationship (write failure): " + e.getMessage());
+                }
+            }
+        } catch (GenericEntityException e) {
+            Debug.logWarning(e.getMessage(), module);
+            return ServiceUtil.returnError("Could not create party  relationship 
(write failure): " + e.getMessage());
+        }
+        result.put(ModelService.RESPONSE_MESSAGE,  
ModelService.RESPOND_SUCCESS);
+        return result;
+    }
}

Added: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyTypeHelper.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyTypeHelper.java?rev=893961&view=auto
= = = = = = = = 
======================================================================
--- ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyTypeHelper.java (added)
+++ ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyTypeHelper.java Sat Dec 26 11:21:21 2009
@@ -0,0 +1,56 @@
+/ 
*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+  
*******************************************************************************/
+
+package org.ofbiz.party.party;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityTypeUtil;
+
+/**
+ * PartyTypeHelper
+ */
+public class PartyTypeHelper {
+
+    public static final String module =  PartyTypeHelper.class.getName();
+
+    /** Check if a related party is of the right party type (PERSON  or 
PARTY_GROUP)
+     *...@param delegator needed Delegator
+     *...@param partyId a a valid Party Id string
+     *...@param checkedPartyType a string in {PERSON, PARTY_GROUP}
+     *...@return Boolean, false in case of error
+     */
+    public static Boolean checkPartyType(Delegator delegator,  String partyId, 
String checkedPartyType) {
+        GenericValue party = null;
+        GenericValue partyType = null;
+        GenericValue checkedTypeOfParty = null;
+        try {
+            party = delegator.findOne("Party",  UtilMisc.toMap("partyId", 
partyId), false);

The cache could be used here since Party.partyType is unlikely to change

OK


+            partyType = party.getRelatedOneCache("PartyType");
+            checkedTypeOfParty = delegator.findOne("PartyType",  
UtilMisc.toMap("partyTypeId", checkedPartyType), true);
+        } catch (GenericEntityException e) {
+            Debug.logWarning(e, module);
+            return false;
+        }
+        return EntityTypeUtil.isType(partyType, checkedTypeOfParty);
+    }
+}

Propchange: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyTypeHelper.java
------------------------------------------------------------------------------
   svn:eol-style = native

Propchange: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyTypeHelper.java
------------------------------------------------------------------------------
   svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/ 
PartyTypeHelper.java
------------------------------------------------------------------------------
   svn:mime-type = text/plain






Reply via email to