You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ofbiz.apache.org by Jacques Le Roux <ja...@les7arts.com> on 2013/07/27 10:48:18 UTC

Re: svn commit: r1507200 - in /ofbiz/trunk/applications/party: ./ data/ entitydef/ servicedef/ src/org/ofbiz/party/party/ webapp/partymgr/WEB-INF/ widget/partymgr/

Hi Hans,

There is an issue with this commit. It does not compile on trunk demo nor in my local copy/
I wonder though 
why Buildbot did not detect it (certainly it uses a more recent jdk version);
and also why my IDE (Eclipse) does not detect it (I guess because I use 1.7 complying 1.6 to internally build);
and also why this fails, because the same scheme is successfully used elsewhere in code.

The demo compilers (mine for ant is is jdk 1.6 22, ) say:

classes:
  [javac16] Compiling 11 source files to /home/ofbiz/trunk/applications/party/build/classes
  [javac16] /home/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java:2097: incompatible types
  [javac16] found   : java.util.Map<java.lang.String,org.ofbiz.entity.GenericValue>
  [javac16] required: java.util.Map<java.lang.String,java.lang.Object>
  [javac16]                     Map<String, Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
  [javac16]                                                                       ^
  [javac16] /home/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java:2117: incompatible types
  [javac16] found   : java.util.Map<java.lang.String,org.ofbiz.entity.GenericValue>
  [javac16] required: java.util.Map<java.lang.String,java.lang.Object>
  [javac16]                     Map<String, Object> telecomNumber = UtilMisc.toMap("userLogin", userLogin);
  [javac16]                                                                       ^
  [javac16] 2 errors

BUILD FAILED
/home/ofbiz/trunk/build.xml:206: The following error occurred while executing this line:
/home/ofbiz/trunk/applications/build.xml:67: The following error occurred while executing this line:
/home/ofbiz/trunk/macros.xml:39: The following error occurred while executing this line:
/home/ofbiz/trunk/common.xml:91: Compile failed; see the compiler error output for details.

Total time: 1 minute 2 seconds
$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)


Of course replacing by
    java.util.Map<java.lang.String,java.lang.Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
as the compilers suggest does not help. 

I replaced by
Map<String, Object> postalAddress = new HashMap<String, Object>();
postalAddress.put("userLogin", userLogin);

And it worked, this must be investigated... I guess it's related with how UtilMisc.toMap() works. But still, looking at it it's quite weird, enough for me on that today...

Hans, I guess your jdk version compiles? Do you use a 1.6 version? Which one? Please let us know, thanks!

I restarted the trunk demo

Jacques


----- Original Message ----- 
From: <ha...@apache.org>
To: <co...@ofbiz.apache.org>
Sent: Friday, July 26, 2013 9:00 AM
Subject: svn commit: r1507200 - in /ofbiz/trunk/applications/party: ./ data/ entitydef/ servicedef/ src/org/ofbiz/party/party/ webapp/partymgr/WEB-INF/ widget/partymgr/


> Author: hansbak
> Date: Fri Jul 26 07:00:28 2013
> New Revision: 1507200
> 
> URL: http://svn.apache.org/r1507200
> Log:
> add a csv party import and export function to the party component
> 
> Modified:
>    ofbiz/trunk/applications/party/build.xml
>    ofbiz/trunk/applications/party/data/PartyTypeData.xml
>    ofbiz/trunk/applications/party/entitydef/entitymodel.xml
>    ofbiz/trunk/applications/party/servicedef/services.xml
>    ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java
>    ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml
>    ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml
>    ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml
>    ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml
> 
> Modified: ofbiz/trunk/applications/party/build.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/build.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/build.xml (original)
> +++ ofbiz/trunk/applications/party/build.xml Fri Jul 26 07:00:28 2013
> @@ -32,6 +32,7 @@ under the License.
>     <path id="local.class.path">
>         <!--<fileset dir="${lib.dir}" includes="*.jar"/>-->
>         <fileset dir="../../framework/base/lib" includes="*.jar"/>
> +        <fileset dir="../../framework/base/lib/commons" includes="*.jar"/>
>         <fileset dir="../../framework/base/lib/j2eespecs" includes="*.jar"/>
>         <fileset dir="../../framework/base/build/lib" includes="*.jar"/>
>         <fileset dir="../../framework/entity/lib" includes="*.jar"/>
> 
> Modified: ofbiz/trunk/applications/party/data/PartyTypeData.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/data/PartyTypeData.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/data/PartyTypeData.xml (original)
> +++ ofbiz/trunk/applications/party/data/PartyTypeData.xml Fri Jul 26 07:00:28 2013
> @@ -441,4 +441,6 @@ under the License.
>     <Enumeration description="Organization party" enumCode="" enumId="ORGANIZATION_PARTY" sequenceId="01" enumTypeId="GLOBAL_PREFERENCES"/>
>     <Enumeration description="Visual Theme" enumCode="" enumId="VISUAL_THEME" sequenceId="02" enumTypeId="GLOBAL_PREFERENCES"/>
> 
> +    <PartyIdentificationType partyIdentificationTypeId="PARTY_IMPORT" description="Original ID in the system where this record was imported from"/>
> +
> </entity-engine-xml>
> 
> Modified: ofbiz/trunk/applications/party/entitydef/entitymodel.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/entitydef/entitymodel.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/entitydef/entitymodel.xml (original)
> +++ ofbiz/trunk/applications/party/entitydef/entitymodel.xml Fri Jul 26 07:00:28 2013
> @@ -2929,4 +2929,80 @@ under the License.
>             <key-map field-name="partyId"/>
>         </relation>
>     </extend-entity>
> +    <view-entity entity-name="PartyExport" package-name="org.ofbiz.accounting.reports">
> +        <member-entity entity-alias="PRT" entity-name="Party"/>
> +        <member-entity entity-alias="GRP" entity-name="PartyGroup"/>
> +        <member-entity entity-alias="PER" entity-name="Person"/>
> +        <member-entity entity-alias="PR" entity-name="PartyRelationship"/>
> +        <member-entity entity-alias="CGRP" entity-name="PartyGroup"/>
> +        <member-entity entity-alias="PRL" entity-name="PartyRole"/>
> +        <member-entity entity-alias="PCM" entity-name="PartyContactMech"/>
> +        <member-entity entity-alias="PCP" entity-name="PartyContactMechPurpose"/>
> +        <member-entity entity-alias="CM" entity-name="ContactMech"/>
> +        <member-entity entity-alias="TN" entity-name="TelecomNumber"/>
> +        <member-entity entity-alias="PA" entity-name="PostalAddress"/>
> +        <alias entity-alias="PRT" name="partyId" />
> +        <alias entity-alias="PRT" name="statusId" />
> +        <alias entity-alias="PRT" name="preferredCurrencyUomId" />
> +        <alias entity-alias="GRP" name="groupName"/>
> +        <alias entity-alias="PER" name="firstName"/>
> +        <alias entity-alias="PER" name="middleName"/>
> +        <alias entity-alias="PER" name="lastName"/>
> +        <alias entity-alias="PR" name="companyPartyId" field="partyIdFrom"/>
> +        <alias entity-alias="CGRP" name="companyName" field="groupName"/>
> +        <alias entity-alias="PRL" name="roleTypeId"/>
> +        <alias entity-alias="CM" name="contactMechTypeId"/>
> +        <alias entity-alias="PCP" name="contactMechPurposeTypeId"/>
> +        <alias entity-alias="CM" name="emailAddress" field="infoString"/>
> +        <alias entity-alias="TN" name="telCountryCode" field="countryCode"/>
> +        <alias entity-alias="TN" name="telAreaCode"  field="areaCode"/>
> +        <alias entity-alias="TN" name="telContactNumber" field="contactNumber"/>
> +        <alias entity-alias="PA" name="address1"/>
> +        <alias entity-alias="PA" name="address2"/>
> +        <alias entity-alias="PA" name="city"/>
> +        <alias entity-alias="PA" name="stateProvinceGeoId"/>
> +        <alias entity-alias="PA" name="postalCode"/>
> +        <alias entity-alias="PA" name="countryGeoId"/>
> +        <view-link entity-alias="PRT" rel-entity-alias="GRP" rel-optional="true">
> +            <key-map field-name="partyId"/>
> +        </view-link>
> +        <view-link entity-alias="PRT" rel-entity-alias="PER" rel-optional="true">
> +            <key-map field-name="partyId"/>
> +        </view-link>
> +        <view-link entity-alias="PRT" rel-entity-alias="PR" rel-optional="true">
> +            <key-map field-name="partyId" rel-field-name="partyIdTo"/>
> +            <entity-condition>
> +                <condition-list combine="and">
> +                    <condition-expr field-name="roleTypeIdFrom" entity-alias="PR" value="ACCOUNT"/>
> +                    <condition-expr field-name="partyRelationshipTypeId" entity-alias="PR" value="EMPLOYMENT"/>
> +                </condition-list>
> +            </entity-condition>
> +        </view-link>
> +        <view-link entity-alias="PR" rel-entity-alias="CGRP" rel-optional="true">
> +            <key-map field-name="partyIdFrom" rel-field-name="partyId"/>
> +        </view-link>
> +        <view-link entity-alias="PRT" rel-entity-alias="PRL" rel-optional="true">
> +            <key-map field-name="partyId"/>
> +        </view-link>
> +        <view-link entity-alias="PRT" rel-entity-alias="PCM" rel-optional="true">
> +            <key-map field-name="partyId"/>
> +            <entity-condition filter-by-date="true"/>
> +        </view-link>
> +        <view-link entity-alias="PCM" rel-entity-alias="PA" rel-optional="true">
> +            <key-map field-name="contactMechId"/>
> +        </view-link>
> +        <view-link entity-alias="PCM" rel-entity-alias="CM" rel-optional="true">
> +            <key-map field-name="contactMechId"/>
> +        </view-link>
> +        <view-link entity-alias="PCM" rel-entity-alias="TN" rel-optional="true">
> +            <key-map field-name="contactMechId"/>
> +        </view-link>
> +        <view-link entity-alias="PCM" rel-entity-alias="PCP" rel-optional="true">
> +            <key-map field-name="contactMechId"/>
> +            <key-map field-name="partyId"/>
> +            <entity-condition filter-by-date="true"/>
> +        </view-link>
> +    </view-entity>
> +    
> +    
> </entitymodel>
> 
> Modified: ofbiz/trunk/applications/party/servicedef/services.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/servicedef/services.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/servicedef/services.xml (original)
> +++ ofbiz/trunk/applications/party/servicedef/services.xml Fri Jul 26 07:00:28 2013
> @@ -1355,4 +1355,12 @@ under the License.
>         <attribute name="userLoginId" type="String" mode="IN" optional="false"/>
>         <attribute name="productStoreId" type="String" mode="IN" optional="false"/>
>     </service>
> +    
> +    <service name="importParty" engine="java"
> +        location="org.ofbiz.party.party.PartyServices" invoke="importParty" auth="true">
> +        <description>Import an party with related main role, company and contact info in csv format, will ignore parties already entered</description>
> +        <permission-service service-name="partyGroupPermissionCheck" main-action="CREATE"/>
> +        <attribute mode="IN" name="uploadedFile" type="java.nio.ByteBuffer" optional="true" />
> +    </service>
> +    
> </services>
> 
> Modified: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java (original)
> +++ ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java Fri Jul 26 07:00:28 2013
> @@ -24,12 +24,18 @@ import java.util.Collection;
> import java.util.List;
> import java.util.Locale;
> import java.util.Map;
> +import java.io.BufferedReader;
> +import java.io.IOException;
> +import java.io.StringReader;
> import java.nio.ByteBuffer;
> import java.nio.charset.Charset;
> 
> import javolution.util.FastList;
> import javolution.util.FastMap;
> 
> +import org.apache.commons.csv.CSVFormat;
> +import org.apache.commons.csv.CSVRecord;
> +import org.apache.commons.csv.CSVFormat.CSVFormatBuilder;
> import org.ofbiz.base.util.Debug;
> import org.ofbiz.base.util.UtilDateTime;
> import org.ofbiz.base.util.UtilGenerics;
> @@ -1850,4 +1856,353 @@ public class PartyServices {
>         return result;
>     }
> 
> +    public static Map<String, Object> importParty(DispatchContext dctx, Map<String, Object> context) {
> +        Delegator delegator = dctx.getDelegator();
> +        LocalDispatcher dispatcher = dctx.getDispatcher();
> +        GenericValue userLogin = (GenericValue) context.get("userLogin");
> +        ByteBuffer fileBytes = (ByteBuffer) context.get("uploadedFile");
> +        String encoding = System.getProperty("file.encoding");
> +        String csvString = Charset.forName(encoding).decode(fileBytes).toString();
> +        final BufferedReader csvReader = new BufferedReader(new StringReader(csvString));
> +        final CSVFormatBuilder builder = CSVFormat.newBuilder(',').withQuoteChar('"').withHeader();
> +        CSVFormat fmt = builder.build();
> +        List<String> errMsgs = FastList.newInstance();
> +        List<String> newErrMsgs = FastList.newInstance();
> +        String lastPartyId = null;        // last partyId read from the csv file
> +        String currentPartyId = null;     // current partyId from the csv file
> +        String newPartyId = null;        // new to create/update partyId in the system
> +        String newCompanyPartyId = null;
> +        int partiesCreated = 0;
> +        Map<String, Object> result = null;
> +        String newContactMechId = null;
> +        String currentContactMechTypeId = null;
> +
> +        String lastAddress1 = null;
> +        String lastAddress2 = null;
> +        String lastCity = null;
> +        String lastCountryGeoId = null;
> +
> +        String lastEmailAddress = null;
> +
> +        String lastCountryCode = null;
> +        String lastAreaCode = null;
> +        String lastContactNumber = null;
> +        
> +        String lastContactMechPurposeTypeId = null;
> +        String currentContactMechPurposeTypeId = null;
> +        
> +        Boolean addParty = false; // when modify party, contact mech not added again
> +        
> +        if (fileBytes == null) {
> +            return ServiceUtil.returnError("Uploaded file data not found");
> +        }
> +        
> +        try {
> +            for(final CSVRecord rec : fmt.parse(csvReader)) {
> +                if (UtilValidate.isNotEmpty(rec.get("partyId"))) {
> +                    currentPartyId =  rec.get("partyId");
> +                }
> +                if (lastPartyId == null || !currentPartyId.equals(lastPartyId)) {
> +                    newPartyId = null;
> +                    currentContactMechPurposeTypeId = null;
> +                    lastAddress1 = null;
> +                    lastAddress2 = null;
> +                    lastCity = null;
> +                    lastCountryGeoId = null;
> +
> +                    lastEmailAddress = null;
> +
> +                    lastCountryCode = null;
> +                    lastAreaCode = null;
> +                    lastContactNumber = null;
> +                    
> +                    // party validation
> +                    List <GenericValue> currencyCheck = delegator.findByAnd("Uom", UtilMisc.toMap("abbreviation", rec.get("preferredCurrencyUomId"), "uomTypeId", "CURRENCY_MEASURE"), null, false);
> +                    if (UtilValidate.isNotEmpty(rec.get("preferredCurrencyUomId")) && currencyCheck.size() == 0) {
> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "Currency code not found for: " + rec.get("preferredCurrencyUomId"));
> +                    }
> +
> +                    if (UtilValidate.isEmpty(rec.get("roleTypeId"))) {
> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": Mandatory roletype is missing, possible values: CUSTOMER, SUPPLIER, EMPLOYEE and more....");
> +                    } else if (delegator.findOne("RoleType", UtilMisc.<String, Object>toMap("roleTypeId", rec.get("roleTypeId")), true) == null) {
> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": RoletypeId is not valid: " + rec.get("roleTypeId") );
> +                    }
> +
> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) &&
> +                            delegator.findOne("ContactMechType", true, UtilMisc.toMap("contactMechTypeId", rec.get("contactMechTypeId"))) == null) {
> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + " contactMechTypeId code not found for: " + rec.get("contactMechTypeId"));
> +                    }
> +                    
> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechPurposeTypeId")) &&
> +                            delegator.findOne("ContactMechPurposeType", true, UtilMisc.toMap("contactMechPurposeTypeId", rec.get("contactMechPurposeTypeId"))) == null) {
> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "contactMechPurposeTypeId code not found for: " + rec.get("contactMechPurposeTypeId"));
> +                    }
> +                    
> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "POSTAL_ADDRESS".equals(rec.get("contactMechTypeId"))) {
> +                        if (UtilValidate.isEmpty(rec.get("countryGeoId"))) {
> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "Country code missing");
> +                        } else {
> +                            List <GenericValue> countryCheck = delegator.findByAnd("Geo", UtilMisc.toMap("geoTypeId", "COUNTRY", "abbreviation", rec.get("countryGeoId")), null, false);
> +                            if (countryCheck.size() == 0) {
> +                                newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " Invalid Country code: " + rec.get("countryGeoId"));
> +                            }
> +                        }
> +
> +                        if (UtilValidate.isEmpty(rec.get("city"))) {
> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + "City name is missing");
> +                        } 
> +
> +                        if (UtilValidate.isNotEmpty(rec.get("stateProvinceGeoId"))) {
> +                            List <GenericValue> stateCheck = delegator.findByAnd("Geo", UtilMisc.toMap("geoTypeId", "STATE", "abbreviation", rec.get("stateProvinceGeoId")), null, false);
> +                            if (stateCheck.size() == 0) {
> +                                newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " Invalid stateProvinceGeoId code: " + rec.get("countryGeoId"));
> +                            }
> +                        }
> +                    }
> +
> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "TELECOM_NUMBER".equals(rec.get("contactMechTypeId"))) {
> +                        if (UtilValidate.isEmpty(rec.get("telAreaCode")) && UtilValidate.isEmpty(rec.get("telAreaCode"))) {
> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " telephone number missing");
> +                        }
> +                    }
> +          
> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "EMAIL_ADDRESS".equals(rec.get("contactMechTypeId"))) {
> +                        if (UtilValidate.isEmpty(rec.get("emailAddress"))) {
> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " email address missing");
> +                        }
> +                    }
> +          
> +                    if (errMsgs.size() == 0) {
> +                        List <GenericValue> partyCheck = delegator.findByAnd("PartyIdentification", UtilMisc.toMap("partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId")), null, false);
> +                        addParty = partyCheck.size() == 0;
> +                        if (!addParty) { // update party
> +                            newPartyId = EntityUtil.getFirst(partyCheck).getString("partyId");
> +                            
> +                            if (UtilValidate.isNotEmpty(rec.get("groupName"))) {
> +                                Map<String, Object> partyGroup = UtilMisc.toMap(
> +                                        "partyId", newPartyId,
> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
> +                                        "groupName", rec.get("groupName"),
> +                                        "userLogin", userLogin
> +                                        );                   
> +                                result = dispatcher.runSync("updatePartyGroup", partyGroup);
> +                            } else { // person
> +                                Map<String, Object> person = UtilMisc.toMap(
> +                                        "partyId", newPartyId,
> +                                        "firstName", rec.get("firstName"),
> +                                        "middleName", rec.get("midleName"),
> +                                        "lastName", rec.get("lastName"),
> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
> +                                        "userLogin", userLogin
> +                                        );                   
> +                                result = dispatcher.runSync("updatePerson", person);
> +                            }
> +                            
> +                        } else { // create new party
> +                            if (UtilValidate.isNotEmpty(rec.get("groupName"))) {
> +                                Map<String, Object> partyGroup = UtilMisc.toMap(
> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
> +                                        "groupName", rec.get("groupName"),
> +                                        "userLogin", userLogin,
> +                                        "statusId", "PARTY_ENABLED"
> +                                        );                   
> +                                result = dispatcher.runSync("createPartyGroup", partyGroup);
> +                            } else { // person
> +                                Map<String, Object> person = UtilMisc.toMap(
> +                                        "firstName", rec.get("firstName"),
> +                                        "middleName", rec.get("midleName"),
> +                                        "lastName", rec.get("lastName"),
> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
> +                                        "statusId", "PARTY_ENABLED",
> +                                        "userLogin", userLogin
> +                                        );                   
> +                                result = dispatcher.runSync("createPerson", person);
> +                            }
> +                            newPartyId = (String) result.get("partyId");
> +
> +                            Map<String, Object> partyIdentification = UtilMisc.toMap(
> +                                "partyId", newPartyId,
> +                                "partyIdentificationTypeId", "PARTY_IMPORT", 
> +                                "idValue", rec.get("partyId"),
> +                                "userLogin", userLogin
> +                                );
> +
> +                            result = dispatcher.runSync("createPartyIdentification", partyIdentification);
> +
> +                            Map<String, Object> partyRole = UtilMisc.toMap(
> +                                    "partyId", newPartyId,
> +                                    "roleTypeId", rec.get("roleTypeId"), 
> +                                    "userLogin", userLogin
> +                                    );
> +                            dispatcher.runSync("createPartyRole", partyRole);
> +
> +                            if (UtilValidate.isNotEmpty(rec.get("companyPartyId"))) {
> +                                List <GenericValue> companyCheck = delegator.findByAnd("PartyIdentification", UtilMisc.toMap("partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId")), null, false);
> +                                if (companyCheck.size() == 0) { // update party group
> +                                    // company does not exist so create
> +                                    Map<String, Object> companyPartyGroup = UtilMisc.toMap(
> +                                        "partyId", newCompanyPartyId, 
> +                                        "statusId", "PARTY_ENABLED",
> +                                        "userLogin", userLogin
> +                                        );                   
> +                                    result = dispatcher.runSync("createPartyGroup", companyPartyGroup);
> +                                    newCompanyPartyId = (String) result.get("partyId");
> +                                } else {
> +                                    newCompanyPartyId = EntityUtil.getFirst(companyCheck).getString("partyId");
> +                                }
> +
> +                                Map<String, Object> companyRole = UtilMisc.toMap(
> +                                        "partyId", newCompanyPartyId,
> +                                        "roleTypeId", "ACCOUNT", 
> +                                        "userLogin", userLogin
> +                                        );
> +                                dispatcher.runSync("createPartyRole", companyRole);
> +                                
> +                                // company exist, so create link
> +                                Map<String, Object> partyRelationship = UtilMisc.toMap(
> +                                    "partyIdTo", newPartyId,
> +                                    "partyIdFrom", newCompanyPartyId,
> +                                    "roleTypeIdFrom", "ACCOUNT",
> +                                    "partyRelationshipTypeId", "EMPLOYMENT",
> +                                    "userLogin", userLogin
> +                                    );                   
> +                                result = dispatcher.runSync("createPartyRelationship", partyRelationship);
> +                            }
> +                        }
> +                        Debug.logInfo(" =========================================================party created id: " + newPartyId, module);
> +                        partiesCreated++;
> +                    } else {
> +                        errMsgs.addAll(newErrMsgs);
> +                        newErrMsgs = FastList.newInstance();
> +                    }
> +                }
> +                
> +                currentContactMechTypeId = rec.get("contactMechTypeId");
> +                currentContactMechPurposeTypeId = rec.get("contactMechPurposeTypeId"); 
> +                // party correctly created (not updated) and contactMechtype provided?
> +                if (newPartyId != null && addParty && UtilValidate.isNotEmpty(currentContactMechTypeId)) {
> +                                        
> +                    // fill maps and check changes
> +                    Map<String, Object> emailAddress = UtilMisc.toMap(
> +                            "contactMechTypeId", "EMAIL_ADDRESS", 
> +                            "userLogin", userLogin
> +                            );
> +                    Boolean emailAddressChanged = false;
> +                    if ("EMAIL_ADDRESS".equals(currentContactMechTypeId)) {
> +                        emailAddress.put("infoString", rec.get("emailAddress"));
> +                        emailAddressChanged = lastEmailAddress == null || !lastEmailAddress.equals(rec.get("emailAddress"));
> +                        lastEmailAddress = rec.get("emailAddress");
> +                    }
> +                    
> +                    Map<String, Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
> +                    Boolean postalAddressChanged = false;
> +                    if ("POSTAL_ADDRESS".equals(currentContactMechTypeId)) {
> +                        postalAddress.put("address1", rec.get("address1"));
> +                        postalAddress.put("address2", rec.get("address2"));
> +                           postalAddress.put("city", rec.get("city"));
> +                        postalAddress.put("stateProvinceGeoId", rec.get("stateProvinceGeoId"));
> +                        postalAddress.put("countryGeoId", rec.get("countryGeoId"));
> +                        postalAddress.put("postalCode", rec.get("postalCode"));
> +                        postalAddressChanged =
> +                                lastAddress1 == null || !lastAddress1.equals(postalAddress.get("address1")) ||
> +                                lastAddress2 == null || !lastAddress2.equals(postalAddress.get("address2")) ||
> +                                lastCity == null || !lastCity.equals(postalAddress.get("city")) ||
> +                                lastCountryGeoId == null || !lastCountryGeoId.equals(postalAddress.get("countryGeoId"));
> +                        lastAddress1 = (String) postalAddress.get("address1");
> +                        lastAddress2 = (String) postalAddress.get("address2");
> +                        lastCity = (String) postalAddress.get("city");
> +                        lastCountryGeoId = (String) postalAddress.get("countryGeoId");
> +                    }                            
> +                            
> +                    Map<String, Object> telecomNumber = UtilMisc.toMap("userLogin", userLogin);
> +                    Boolean telecomNumberChanged = false;
> +                    if ("TELECOM_NUMBER".equals(currentContactMechTypeId)) {
> +                        telecomNumber.put("countryCode", rec.get("telCountryCode"));
> +                        telecomNumber.put("areaCode", rec.get("telAreaCode"));
> +                        telecomNumber.put("contactNumber", rec.get("telContactNumber"));
> +                        telecomNumberChanged = 
> +                                lastCountryCode == null || !lastCountryCode.equals(telecomNumber.get("countryCode")) ||
> +                                lastAreaCode == null || !lastAreaCode.equals(telecomNumber.get("areaCode")) ||
> +                                lastContactNumber == null || !lastContactNumber.equals(telecomNumber.get("contactNumber"));
> +                        lastCountryCode = (String) telecomNumber.get("countryCode");
> +                        lastAreaCode = (String) telecomNumber.get("areaCode");
> +                        lastContactNumber = (String) telecomNumber.get("contactNumber");
> +                    }
> +                    
> +                    Map<String, Object> partyContactMechPurpose = UtilMisc.toMap("partyId", newPartyId, "userLogin", userLogin);
> +                    Boolean partyContactMechPurposeChanged = false;
> +                    currentContactMechPurposeTypeId = rec.get("contactMechPurposeTypeId"); 
> +                    if (currentContactMechPurposeTypeId != null && ("TELECOM_NUMBER".equals(currentContactMechTypeId) || "POSTAL_ADDRESS".equals(currentContactMechTypeId) ||"EMAIL_ADDRESS".equals(currentContactMechTypeId))) {
> +                        partyContactMechPurpose.put("contactMechPurposeTypeId", currentContactMechPurposeTypeId);
> +                        partyContactMechPurposeChanged = (lastContactMechPurposeTypeId == null || !lastContactMechPurposeTypeId.equals(currentContactMechPurposeTypeId)) && !telecomNumberChanged && !postalAddressChanged && !emailAddressChanged;
> +                        Debug.logInfo("===================================last:" + lastContactMechPurposeTypeId + " current: " + currentContactMechPurposeTypeId + " t :" + telecomNumberChanged + " p: " + postalAddressChanged + " e: " + emailAddressChanged + " result: " + partyContactMechPurposeChanged, module); 
> +                    }
> +                    lastContactMechPurposeTypeId = currentContactMechPurposeTypeId;
> +                    
> +                    // update 
> +                    if (errMsgs.size() == 0) {
> +
> +                        if (postalAddressChanged) {
> +                            result = dispatcher.runSync("createPostalAddress", postalAddress);
> +                               newContactMechId = (String) result.get("contactMechId");
> +                            if (currentContactMechPurposeTypeId == null) {
> +                                currentContactMechPurposeTypeId = "GENERAL_LOCATION";
> +                            }
> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
> +                        }
> +
> +                        if (telecomNumberChanged) {
> +                            result = dispatcher.runSync("createTelecomNumber", telecomNumber);
> +                               newContactMechId = (String) result.get("contactMechId");
> +                            if (currentContactMechPurposeTypeId == null) {
> +                                currentContactMechPurposeTypeId= "PHONE_WORK";
> +                            }
> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
> +                        }
> +
> +                        if (emailAddressChanged) {
> +                            result = dispatcher.runSync("createContactMech", emailAddress);
> +                               newContactMechId = (String) result.get("contactMechId");
> +                            if (currentContactMechPurposeTypeId == null) {
> +                                currentContactMechPurposeTypeId = "PRIMARY_EMAIL";
> +                            }
> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
> +                        }
> +                        
> +                        if (partyContactMechPurposeChanged) {
> +                            partyContactMechPurpose.put("contactMechId", newContactMechId);
> +                            result = dispatcher.runSync("createPartyContactMechPurpose", partyContactMechPurpose);
> +                        }
> +                        
> +                    lastPartyId = currentPartyId;
> +                    errMsgs.addAll(newErrMsgs);
> +                    newErrMsgs = FastList.newInstance();
> +                    }
> +                }
> +
> +            }
> +            
> +        } 
> +        catch (GenericServiceException e) {
> +        Debug.logError(e, module);
> +            return ServiceUtil.returnError(e.getMessage());
> +        }
> +        
> +        catch (GenericEntityException e) {
> +                Debug.logError(e, module);
> +                return ServiceUtil.returnError(e.getMessage());
> +        }
> +    
> +        catch (IOException e) {
> +        Debug.logError(e, module);
> +            return ServiceUtil.returnError(e.getMessage());
> +        }
> +        
> +        if (errMsgs.size() > 0) {
> +            return ServiceUtil.returnError(errMsgs);
> +        }
> +
> +        result = ServiceUtil.returnSuccess(partiesCreated + " new parties created");
> +        return result;
> +    }
> }
> 
> Modified: ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml (original)
> +++ ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml Fri Jul 26 07:00:28 2013
> @@ -906,6 +906,22 @@ under the License.
>         <response name="success" type="view" value="FindAddressMatch"/>
>     </request-map>
> 
> +    <!-- Import export -->
> +    <request-map uri="ImportExport">
> +        <security https="true" auth="true"/>
> +        <response name="success" type="view" value="ImportExport"/>
> +    </request-map>
> +    <request-map uri="ExportPartyCsv.csv">
> +        <security https="true" auth="true"/>
> +        <response name="success" type="view" value="PartyExportCsv"/>
> +    </request-map>
> +    <request-map uri="uploadParty">
> +        <security auth="true" https="true"/>
> +        <event invoke="importParty" path="" type="service"/>
> +        <response name="success" type="request" value="ImportExport"/>
> +        <response name="error" type="view" value="ImportExport"/>
> +    </request-map>
> +
>    <!-- ================ SimpleContent Requests ================= -->
> 
>     <request-map uri="ViewSimpleContent">
> @@ -1352,6 +1368,10 @@ under the License.
> 
>     <view-map name="AddressMatchMap" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#AddressMatchMap"/>
>     <view-map name="FindAddressMatch" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#FindAddressMatch"/>
> +
> +    <view-map name="ImportExport" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#ImportExport"/>
> +    <view-map name="PartyExportCsv" type="screencsv" page="component://party/widget/partymgr/PartyScreens.xml#PartyExportCsv" content-type="text/csv" encoding="none"/>
> +
>     <view-map name="EditPartyContents" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#EditPartyContents"/>
>     <view-map name="editCarrierAccount" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#editCarrierAccount"/>
>     <view-map name="partyInvitation" type="screen" page="component://party/widget/partymgr/PartyInvitationScreens.xml#FindPartyInvitations"/>
> 
> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml (original)
> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml Fri Jul 26 07:00:28 2013
> @@ -1198,4 +1198,56 @@ under the License.
>             </hyperlink>
>         </field>
>     </form>
> +
> +    <form name="ExportParty" type="single" target="ExportPartyCsv.csv" title="" >
> +        <field name="partyId" tooltip="blank for all"><lookup target-form-name="LookupPartyName"/></field>
> +        <field name="submitButton" title="${uiLabelMap.CommonSubmit}"><submit button-type="button"/></field>
> +    </form>
> +
> +    <form name="ExportPartyCsv" list-name="listIt" target="" title="" type="list" view-size="99999"
> +        odd-row-style="alternate-row" header-row-style="header-row-2" default-table-style="basic-table hover-bar" paginate="false">
> +        <actions>
> +            <entity-condition entity-name="PartyExport">
> +                <condition-list combine="and">
> +                    <condition-list combine="or">
> +                        <condition-expr field-name="roleTypeId" value="CUSTOMER" operator="equals"/>
> +                        <condition-expr field-name="roleTypeId" value="SUPPLIER" operator="equals"/>
> +                        <condition-expr field-name="roleTypeId" value="EMPLOYEE" operator="equals"/>
> +                    </condition-list>
> +                    <condition-expr field-name="statusId" value="PARTY_DISABLED" operator="not-equals"/>
> +                    <condition-expr field-name="partyId" from-field="partyId" operator="equals" value="${parameters.partyId}" ignore-if-empty="true"/>
> +                </condition-list>
> +                <order-by field-name="partyId"/>
> +            </entity-condition>
> +        </actions>
> +        <field name="partyId" title="partyId"><display/></field>
> +        <field name="preferredCurrencyUomId" title="preferredCurrencyUomId"><display/></field>
> +        <field name="groupName" title="groupName"><display/></field>
> +        <field name="firstName" title="firstName"><display/></field>
> +        <field name="middleName" title="middleName"><display/></field>
> +        <field name="lastName" title="lastName"><display/></field>
> +        <field name="companyPartyId" title="companyPartyId"><display/></field>
> +        <field name="companyName" title="companyName"><display/></field>
> +        <field name="roleTypeId" title="roleTypeId"><display/></field>
> +        <field name="contactMechPurposeTypeId" title="contactMechPurposeTypeId"><display/></field>
> +        <field name="contactMechTypeId" title="contactMechTypeId"><display/></field>
> +        <field name="emailAddress" title="emailAddress"><display/></field>
> +        <field name="telCountryCode" title="telCountryCode"><display/></field>
> +        <field name="telAreaCode" title="telAreaCode"><display/></field>
> +        <field name="telContactNumber" title="telContactNumber"><display/></field>
> +        <field name="address1" title="address1"><display/></field>
> +        <field name="address2" title="address2"><display/></field>
> +        <field name="city" title="city"><display/></field>
> +        <field name="stateProvinceGeoId" title="stateProvinceGeoId"><display/></field>
> +        <field name="postalCode" title="postalCode"><display/></field>
> +        <field name="countryGeoId" title="countryGeoId"><display/></field>
> +    </form>
> +    
> +    <form name="ImportParty" type="upload" target="uploadParty" title="" >
> +        <field name="uploadedFile"><file/></field>
> +        <field name="submitButton" title="${uiLabelMap.CommonUpload}"><submit button-type="button"/></field>
> +    </form>
> +    
> +
> +    
> </forms>
> 
> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml (original)
> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml Fri Jul 26 07:00:28 2013
> @@ -35,6 +35,7 @@
>         </menu-item>
>         <menu-item name="addrmap" title="${uiLabelMap.PageTitleAddressMatchMap}"><link target="addressMatchMap"/></menu-item>
>         <menu-item name="partyinv" title="${uiLabelMap.PartyInvitation}"><link target="partyInvitation"/></menu-item>
> +        <menu-item name="importexport" title="${uiLabelMap.CommonImportExport}"><link target="ImportExport"/></menu-item>
>     </menu>
> 
>     <menu name="ProfileTabBar" extends="CommonTabBarMenu" extends-resource="component://common/widget/CommonMenus.xml"
> 
> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
> ==============================================================================
> --- ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml (original)
> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml Fri Jul 26 07:00:28 2013
> @@ -1302,4 +1302,41 @@ under the License.
>             </widgets>
>         </section>
>     </screen>
> +    <screen name="ImportExport">
> +        <section>
> +            <actions>
> +                <set field="titleProperty" value="CommonImportExport"/>
> +                <set field="headerItem" value="importexport"/>
> +            </actions>
> +            <widgets>
> +                <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
> +                    <decorator-section name="body">
> +                        <screenlet title="${uiLabelMap.PartyParty} ${uiLabelMap.CommonImportExport} ID Name, single role (employee, customer, supplier) and contactmechs">
> +                            <container style="lefthalf">
> +                                <label style="h2">${uiLabelMap.CommonImport}</label>
> +                                <include-form name="ImportParty" location="component://party/widget/partymgr/PartyForms.xml"/>
> +                            </container>
> +                            <container style="righthalf">
> +                                <label style="h2">${uiLabelMap.CommonExport}</label>
> +                                <include-form name="ExportParty" location="component://party/widget/partymgr/PartyForms.xml"/>
> +                            </container>
> +                         </screenlet>
> +                    </decorator-section>
> +                </decorator-screen>
> +            </widgets>
> +        </section>
> +    </screen>
> +    <screen name="PartyExportCsv">
> +        <section>
> +            <actions>
> +                <property-map resource="CommonUiLabels" map-name="uiLabelMap" global="true"/>
> +                <property-map resource="AccountingUiLabels" map-name="uiLabelMap" global="true"/>
> +                <set field="organizationPartyId" from-field="parameters.organizationPartyId"/>
> +            </actions>
> +            <widgets>
> +                <include-form name="ExportPartyCsv" location="component://party/widget/partymgr/PartyForms.xml"/>           
> +            </widgets>
> +        </section>
> +    </screen>
> +    
> </screens>
> 
>

Re: svn commit: r1507200 - in /ofbiz/trunk/applications/party: ./ data/ entitydef/ servicedef/ src/org/ofbiz/party/party/ webapp/partymgr/WEB-INF/ widget/partymgr/

Posted by Jacques Le Roux <ja...@les7arts.com>.
Yes, I first thought about that. But what I find weird is that lines like

Map<String, Object> filter = UtilMisc.toMap("orderItemSeqId", orderItem.get("orderItemSeqId"));
Map<String, Object> deletePcmCtx = UtilMisc.toMap("contactMechId", context.get("contactMechId"));

compile and also that Hans, and buildbot did not detect it, so some 1.6(?) compilers are ok with it.

For the lines above I guess it's due to how UtilMisc.toMap() works, but for the compilers, it's still weird to me.

BTW, you might also use

Map<String, Object> postalAddress = UtilMisc.toMap("userLogin", (Object) userLogin);

Which is a little less verbose ;)

Jacques


From: "Scott Gray" <sc...@hotwaxmedia.com>
>> I replaced by
>> Map<String, Object> postalAddress = new HashMap<String, Object>();
>> postalAddress.put("userLogin", userLogin);
> 
> The correct approach is:
> Map<String, Object> postalAddress = UtilMisc.<String, Object>toMap("userLogin", userLogin);
> 
> Regards
> Scott
> 
> On 27/07/2013, at 8:48 PM, Jacques Le Roux wrote:
> 
>> Hi Hans,
>> 
>> There is an issue with this commit. It does not compile on trunk demo nor in my local copy/
>> I wonder though 
>> why Buildbot did not detect it (certainly it uses a more recent jdk version);
>> and also why my IDE (Eclipse) does not detect it (I guess because I use 1.7 complying 1.6 to internally build);
>> and also why this fails, because the same scheme is successfully used elsewhere in code.
>> 
>> The demo compilers (mine for ant is is jdk 1.6 22, ) say:
>> 
>> classes:
>>  [javac16] Compiling 11 source files to /home/ofbiz/trunk/applications/party/build/classes
>>  [javac16] /home/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java:2097: incompatible types
>>  [javac16] found   : java.util.Map<java.lang.String,org.ofbiz.entity.GenericValue>
>>  [javac16] required: java.util.Map<java.lang.String,java.lang.Object>
>>  [javac16]                     Map<String, Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
>>  [javac16]                                                                       ^
>>  [javac16] /home/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java:2117: incompatible types
>>  [javac16] found   : java.util.Map<java.lang.String,org.ofbiz.entity.GenericValue>
>>  [javac16] required: java.util.Map<java.lang.String,java.lang.Object>
>>  [javac16]                     Map<String, Object> telecomNumber = UtilMisc.toMap("userLogin", userLogin);
>>  [javac16]                                                                       ^
>>  [javac16] 2 errors
>> 
>> BUILD FAILED
>> /home/ofbiz/trunk/build.xml:206: The following error occurred while executing this line:
>> /home/ofbiz/trunk/applications/build.xml:67: The following error occurred while executing this line:
>> /home/ofbiz/trunk/macros.xml:39: The following error occurred while executing this line:
>> /home/ofbiz/trunk/common.xml:91: Compile failed; see the compiler error output for details.
>> 
>> Total time: 1 minute 2 seconds
>> $ java -version
>> java version "1.6.0_26"
>> Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
>> Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
>> 
>> 
>> Of course replacing by
>>    java.util.Map<java.lang.String,java.lang.Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
>> as the compilers suggest does not help. 
>> 
>> I replaced by
>> Map<String, Object> postalAddress = new HashMap<String, Object>();
>> postalAddress.put("userLogin", userLogin);
>> 
>> And it worked, this must be investigated... I guess it's related with how UtilMisc.toMap() works. But still, looking at it it's quite weird, enough for me on that today...
>> 
>> Hans, I guess your jdk version compiles? Do you use a 1.6 version? Which one? Please let us know, thanks!
>> 
>> I restarted the trunk demo
>> 
>> Jacques
>> 
>> 
>> ----- Original Message ----- 
>> From: <ha...@apache.org>
>> To: <co...@ofbiz.apache.org>
>> Sent: Friday, July 26, 2013 9:00 AM
>> Subject: svn commit: r1507200 - in /ofbiz/trunk/applications/party: ./ data/ entitydef/ servicedef/ src/org/ofbiz/party/party/ webapp/partymgr/WEB-INF/ widget/partymgr/
>> 
>> 
>>> Author: hansbak
>>> Date: Fri Jul 26 07:00:28 2013
>>> New Revision: 1507200
>>> 
>>> URL: http://svn.apache.org/r1507200
>>> Log:
>>> add a csv party import and export function to the party component
>>> 
>>> Modified:
>>>   ofbiz/trunk/applications/party/build.xml
>>>   ofbiz/trunk/applications/party/data/PartyTypeData.xml
>>>   ofbiz/trunk/applications/party/entitydef/entitymodel.xml
>>>   ofbiz/trunk/applications/party/servicedef/services.xml
>>>   ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java
>>>   ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml
>>>   ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml
>>>   ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml
>>>   ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml
>>> 
>>> Modified: ofbiz/trunk/applications/party/build.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/build.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/build.xml (original)
>>> +++ ofbiz/trunk/applications/party/build.xml Fri Jul 26 07:00:28 2013
>>> @@ -32,6 +32,7 @@ under the License.
>>>    <path id="local.class.path">
>>>        <!--<fileset dir="${lib.dir}" includes="*.jar"/>-->
>>>        <fileset dir="../../framework/base/lib" includes="*.jar"/>
>>> +        <fileset dir="../../framework/base/lib/commons" includes="*.jar"/>
>>>        <fileset dir="../../framework/base/lib/j2eespecs" includes="*.jar"/>
>>>        <fileset dir="../../framework/base/build/lib" includes="*.jar"/>
>>>        <fileset dir="../../framework/entity/lib" includes="*.jar"/>
>>> 
>>> Modified: ofbiz/trunk/applications/party/data/PartyTypeData.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/data/PartyTypeData.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/data/PartyTypeData.xml (original)
>>> +++ ofbiz/trunk/applications/party/data/PartyTypeData.xml Fri Jul 26 07:00:28 2013
>>> @@ -441,4 +441,6 @@ under the License.
>>>    <Enumeration description="Organization party" enumCode="" enumId="ORGANIZATION_PARTY" sequenceId="01" enumTypeId="GLOBAL_PREFERENCES"/>
>>>    <Enumeration description="Visual Theme" enumCode="" enumId="VISUAL_THEME" sequenceId="02" enumTypeId="GLOBAL_PREFERENCES"/>
>>> 
>>> +    <PartyIdentificationType partyIdentificationTypeId="PARTY_IMPORT" description="Original ID in the system where this record was imported from"/>
>>> +
>>> </entity-engine-xml>
>>> 
>>> Modified: ofbiz/trunk/applications/party/entitydef/entitymodel.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/entitydef/entitymodel.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/entitydef/entitymodel.xml (original)
>>> +++ ofbiz/trunk/applications/party/entitydef/entitymodel.xml Fri Jul 26 07:00:28 2013
>>> @@ -2929,4 +2929,80 @@ under the License.
>>>            <key-map field-name="partyId"/>
>>>        </relation>
>>>    </extend-entity>
>>> +    <view-entity entity-name="PartyExport" package-name="org.ofbiz.accounting.reports">
>>> +        <member-entity entity-alias="PRT" entity-name="Party"/>
>>> +        <member-entity entity-alias="GRP" entity-name="PartyGroup"/>
>>> +        <member-entity entity-alias="PER" entity-name="Person"/>
>>> +        <member-entity entity-alias="PR" entity-name="PartyRelationship"/>
>>> +        <member-entity entity-alias="CGRP" entity-name="PartyGroup"/>
>>> +        <member-entity entity-alias="PRL" entity-name="PartyRole"/>
>>> +        <member-entity entity-alias="PCM" entity-name="PartyContactMech"/>
>>> +        <member-entity entity-alias="PCP" entity-name="PartyContactMechPurpose"/>
>>> +        <member-entity entity-alias="CM" entity-name="ContactMech"/>
>>> +        <member-entity entity-alias="TN" entity-name="TelecomNumber"/>
>>> +        <member-entity entity-alias="PA" entity-name="PostalAddress"/>
>>> +        <alias entity-alias="PRT" name="partyId" />
>>> +        <alias entity-alias="PRT" name="statusId" />
>>> +        <alias entity-alias="PRT" name="preferredCurrencyUomId" />
>>> +        <alias entity-alias="GRP" name="groupName"/>
>>> +        <alias entity-alias="PER" name="firstName"/>
>>> +        <alias entity-alias="PER" name="middleName"/>
>>> +        <alias entity-alias="PER" name="lastName"/>
>>> +        <alias entity-alias="PR" name="companyPartyId" field="partyIdFrom"/>
>>> +        <alias entity-alias="CGRP" name="companyName" field="groupName"/>
>>> +        <alias entity-alias="PRL" name="roleTypeId"/>
>>> +        <alias entity-alias="CM" name="contactMechTypeId"/>
>>> +        <alias entity-alias="PCP" name="contactMechPurposeTypeId"/>
>>> +        <alias entity-alias="CM" name="emailAddress" field="infoString"/>
>>> +        <alias entity-alias="TN" name="telCountryCode" field="countryCode"/>
>>> +        <alias entity-alias="TN" name="telAreaCode"  field="areaCode"/>
>>> +        <alias entity-alias="TN" name="telContactNumber" field="contactNumber"/>
>>> +        <alias entity-alias="PA" name="address1"/>
>>> +        <alias entity-alias="PA" name="address2"/>
>>> +        <alias entity-alias="PA" name="city"/>
>>> +        <alias entity-alias="PA" name="stateProvinceGeoId"/>
>>> +        <alias entity-alias="PA" name="postalCode"/>
>>> +        <alias entity-alias="PA" name="countryGeoId"/>
>>> +        <view-link entity-alias="PRT" rel-entity-alias="GRP" rel-optional="true">
>>> +            <key-map field-name="partyId"/>
>>> +        </view-link>
>>> +        <view-link entity-alias="PRT" rel-entity-alias="PER" rel-optional="true">
>>> +            <key-map field-name="partyId"/>
>>> +        </view-link>
>>> +        <view-link entity-alias="PRT" rel-entity-alias="PR" rel-optional="true">
>>> +            <key-map field-name="partyId" rel-field-name="partyIdTo"/>
>>> +            <entity-condition>
>>> +                <condition-list combine="and">
>>> +                    <condition-expr field-name="roleTypeIdFrom" entity-alias="PR" value="ACCOUNT"/>
>>> +                    <condition-expr field-name="partyRelationshipTypeId" entity-alias="PR" value="EMPLOYMENT"/>
>>> +                </condition-list>
>>> +            </entity-condition>
>>> +        </view-link>
>>> +        <view-link entity-alias="PR" rel-entity-alias="CGRP" rel-optional="true">
>>> +            <key-map field-name="partyIdFrom" rel-field-name="partyId"/>
>>> +        </view-link>
>>> +        <view-link entity-alias="PRT" rel-entity-alias="PRL" rel-optional="true">
>>> +            <key-map field-name="partyId"/>
>>> +        </view-link>
>>> +        <view-link entity-alias="PRT" rel-entity-alias="PCM" rel-optional="true">
>>> +            <key-map field-name="partyId"/>
>>> +            <entity-condition filter-by-date="true"/>
>>> +        </view-link>
>>> +        <view-link entity-alias="PCM" rel-entity-alias="PA" rel-optional="true">
>>> +            <key-map field-name="contactMechId"/>
>>> +        </view-link>
>>> +        <view-link entity-alias="PCM" rel-entity-alias="CM" rel-optional="true">
>>> +            <key-map field-name="contactMechId"/>
>>> +        </view-link>
>>> +        <view-link entity-alias="PCM" rel-entity-alias="TN" rel-optional="true">
>>> +            <key-map field-name="contactMechId"/>
>>> +        </view-link>
>>> +        <view-link entity-alias="PCM" rel-entity-alias="PCP" rel-optional="true">
>>> +            <key-map field-name="contactMechId"/>
>>> +            <key-map field-name="partyId"/>
>>> +            <entity-condition filter-by-date="true"/>
>>> +        </view-link>
>>> +    </view-entity>
>>> +    
>>> +    
>>> </entitymodel>
>>> 
>>> Modified: ofbiz/trunk/applications/party/servicedef/services.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/servicedef/services.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/servicedef/services.xml (original)
>>> +++ ofbiz/trunk/applications/party/servicedef/services.xml Fri Jul 26 07:00:28 2013
>>> @@ -1355,4 +1355,12 @@ under the License.
>>>        <attribute name="userLoginId" type="String" mode="IN" optional="false"/>
>>>        <attribute name="productStoreId" type="String" mode="IN" optional="false"/>
>>>    </service>
>>> +    
>>> +    <service name="importParty" engine="java"
>>> +        location="org.ofbiz.party.party.PartyServices" invoke="importParty" auth="true">
>>> +        <description>Import an party with related main role, company and contact info in csv format, will ignore parties already entered</description>
>>> +        <permission-service service-name="partyGroupPermissionCheck" main-action="CREATE"/>
>>> +        <attribute mode="IN" name="uploadedFile" type="java.nio.ByteBuffer" optional="true" />
>>> +    </service>
>>> +    
>>> </services>
>>> 
>>> Modified: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java (original)
>>> +++ ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java Fri Jul 26 07:00:28 2013
>>> @@ -24,12 +24,18 @@ import java.util.Collection;
>>> import java.util.List;
>>> import java.util.Locale;
>>> import java.util.Map;
>>> +import java.io.BufferedReader;
>>> +import java.io.IOException;
>>> +import java.io.StringReader;
>>> import java.nio.ByteBuffer;
>>> import java.nio.charset.Charset;
>>> 
>>> import javolution.util.FastList;
>>> import javolution.util.FastMap;
>>> 
>>> +import org.apache.commons.csv.CSVFormat;
>>> +import org.apache.commons.csv.CSVRecord;
>>> +import org.apache.commons.csv.CSVFormat.CSVFormatBuilder;
>>> import org.ofbiz.base.util.Debug;
>>> import org.ofbiz.base.util.UtilDateTime;
>>> import org.ofbiz.base.util.UtilGenerics;
>>> @@ -1850,4 +1856,353 @@ public class PartyServices {
>>>        return result;
>>>    }
>>> 
>>> +    public static Map<String, Object> importParty(DispatchContext dctx, Map<String, Object> context) {
>>> +        Delegator delegator = dctx.getDelegator();
>>> +        LocalDispatcher dispatcher = dctx.getDispatcher();
>>> +        GenericValue userLogin = (GenericValue) context.get("userLogin");
>>> +        ByteBuffer fileBytes = (ByteBuffer) context.get("uploadedFile");
>>> +        String encoding = System.getProperty("file.encoding");
>>> +        String csvString = Charset.forName(encoding).decode(fileBytes).toString();
>>> +        final BufferedReader csvReader = new BufferedReader(new StringReader(csvString));
>>> +        final CSVFormatBuilder builder = CSVFormat.newBuilder(',').withQuoteChar('"').withHeader();
>>> +        CSVFormat fmt = builder.build();
>>> +        List<String> errMsgs = FastList.newInstance();
>>> +        List<String> newErrMsgs = FastList.newInstance();
>>> +        String lastPartyId = null;        // last partyId read from the csv file
>>> +        String currentPartyId = null;     // current partyId from the csv file
>>> +        String newPartyId = null;        // new to create/update partyId in the system
>>> +        String newCompanyPartyId = null;
>>> +        int partiesCreated = 0;
>>> +        Map<String, Object> result = null;
>>> +        String newContactMechId = null;
>>> +        String currentContactMechTypeId = null;
>>> +
>>> +        String lastAddress1 = null;
>>> +        String lastAddress2 = null;
>>> +        String lastCity = null;
>>> +        String lastCountryGeoId = null;
>>> +
>>> +        String lastEmailAddress = null;
>>> +
>>> +        String lastCountryCode = null;
>>> +        String lastAreaCode = null;
>>> +        String lastContactNumber = null;
>>> +        
>>> +        String lastContactMechPurposeTypeId = null;
>>> +        String currentContactMechPurposeTypeId = null;
>>> +        
>>> +        Boolean addParty = false; // when modify party, contact mech not added again
>>> +        
>>> +        if (fileBytes == null) {
>>> +            return ServiceUtil.returnError("Uploaded file data not found");
>>> +        }
>>> +        
>>> +        try {
>>> +            for(final CSVRecord rec : fmt.parse(csvReader)) {
>>> +                if (UtilValidate.isNotEmpty(rec.get("partyId"))) {
>>> +                    currentPartyId =  rec.get("partyId");
>>> +                }
>>> +                if (lastPartyId == null || !currentPartyId.equals(lastPartyId)) {
>>> +                    newPartyId = null;
>>> +                    currentContactMechPurposeTypeId = null;
>>> +                    lastAddress1 = null;
>>> +                    lastAddress2 = null;
>>> +                    lastCity = null;
>>> +                    lastCountryGeoId = null;
>>> +
>>> +                    lastEmailAddress = null;
>>> +
>>> +                    lastCountryCode = null;
>>> +                    lastAreaCode = null;
>>> +                    lastContactNumber = null;
>>> +                    
>>> +                    // party validation
>>> +                    List <GenericValue> currencyCheck = delegator.findByAnd("Uom", UtilMisc.toMap("abbreviation", rec.get("preferredCurrencyUomId"), "uomTypeId", "CURRENCY_MEASURE"), null, false);
>>> +                    if (UtilValidate.isNotEmpty(rec.get("preferredCurrencyUomId")) && currencyCheck.size() == 0) {
>>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "Currency code not found for: " + rec.get("preferredCurrencyUomId"));
>>> +                    }
>>> +
>>> +                    if (UtilValidate.isEmpty(rec.get("roleTypeId"))) {
>>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": Mandatory roletype is missing, possible values: CUSTOMER, SUPPLIER, EMPLOYEE and more....");
>>> +                    } else if (delegator.findOne("RoleType", UtilMisc.<String, Object>toMap("roleTypeId", rec.get("roleTypeId")), true) == null) {
>>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": RoletypeId is not valid: " + rec.get("roleTypeId") );
>>> +                    }
>>> +
>>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) &&
>>> +                            delegator.findOne("ContactMechType", true, UtilMisc.toMap("contactMechTypeId", rec.get("contactMechTypeId"))) == null) {
>>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + " contactMechTypeId code not found for: " + rec.get("contactMechTypeId"));
>>> +                    }
>>> +                    
>>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechPurposeTypeId")) &&
>>> +                            delegator.findOne("ContactMechPurposeType", true, UtilMisc.toMap("contactMechPurposeTypeId", rec.get("contactMechPurposeTypeId"))) == null) {
>>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "contactMechPurposeTypeId code not found for: " + rec.get("contactMechPurposeTypeId"));
>>> +                    }
>>> +                    
>>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "POSTAL_ADDRESS".equals(rec.get("contactMechTypeId"))) {
>>> +                        if (UtilValidate.isEmpty(rec.get("countryGeoId"))) {
>>> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "Country code missing");
>>> +                        } else {
>>> +                            List <GenericValue> countryCheck = delegator.findByAnd("Geo", UtilMisc.toMap("geoTypeId", "COUNTRY", "abbreviation", rec.get("countryGeoId")), null, false);
>>> +                            if (countryCheck.size() == 0) {
>>> +                                newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " Invalid Country code: " + rec.get("countryGeoId"));
>>> +                            }
>>> +                        }
>>> +
>>> +                        if (UtilValidate.isEmpty(rec.get("city"))) {
>>> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + "City name is missing");
>>> +                        } 
>>> +
>>> +                        if (UtilValidate.isNotEmpty(rec.get("stateProvinceGeoId"))) {
>>> +                            List <GenericValue> stateCheck = delegator.findByAnd("Geo", UtilMisc.toMap("geoTypeId", "STATE", "abbreviation", rec.get("stateProvinceGeoId")), null, false);
>>> +                            if (stateCheck.size() == 0) {
>>> +                                newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " Invalid stateProvinceGeoId code: " + rec.get("countryGeoId"));
>>> +                            }
>>> +                        }
>>> +                    }
>>> +
>>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "TELECOM_NUMBER".equals(rec.get("contactMechTypeId"))) {
>>> +                        if (UtilValidate.isEmpty(rec.get("telAreaCode")) && UtilValidate.isEmpty(rec.get("telAreaCode"))) {
>>> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " telephone number missing");
>>> +                        }
>>> +                    }
>>> +          
>>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "EMAIL_ADDRESS".equals(rec.get("contactMechTypeId"))) {
>>> +                        if (UtilValidate.isEmpty(rec.get("emailAddress"))) {
>>> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " email address missing");
>>> +                        }
>>> +                    }
>>> +          
>>> +                    if (errMsgs.size() == 0) {
>>> +                        List <GenericValue> partyCheck = delegator.findByAnd("PartyIdentification", UtilMisc.toMap("partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId")), null, false);
>>> +                        addParty = partyCheck.size() == 0;
>>> +                        if (!addParty) { // update party
>>> +                            newPartyId = EntityUtil.getFirst(partyCheck).getString("partyId");
>>> +                            
>>> +                            if (UtilValidate.isNotEmpty(rec.get("groupName"))) {
>>> +                                Map<String, Object> partyGroup = UtilMisc.toMap(
>>> +                                        "partyId", newPartyId,
>>> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
>>> +                                        "groupName", rec.get("groupName"),
>>> +                                        "userLogin", userLogin
>>> +                                        );                   
>>> +                                result = dispatcher.runSync("updatePartyGroup", partyGroup);
>>> +                            } else { // person
>>> +                                Map<String, Object> person = UtilMisc.toMap(
>>> +                                        "partyId", newPartyId,
>>> +                                        "firstName", rec.get("firstName"),
>>> +                                        "middleName", rec.get("midleName"),
>>> +                                        "lastName", rec.get("lastName"),
>>> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
>>> +                                        "userLogin", userLogin
>>> +                                        );                   
>>> +                                result = dispatcher.runSync("updatePerson", person);
>>> +                            }
>>> +                            
>>> +                        } else { // create new party
>>> +                            if (UtilValidate.isNotEmpty(rec.get("groupName"))) {
>>> +                                Map<String, Object> partyGroup = UtilMisc.toMap(
>>> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
>>> +                                        "groupName", rec.get("groupName"),
>>> +                                        "userLogin", userLogin,
>>> +                                        "statusId", "PARTY_ENABLED"
>>> +                                        );                   
>>> +                                result = dispatcher.runSync("createPartyGroup", partyGroup);
>>> +                            } else { // person
>>> +                                Map<String, Object> person = UtilMisc.toMap(
>>> +                                        "firstName", rec.get("firstName"),
>>> +                                        "middleName", rec.get("midleName"),
>>> +                                        "lastName", rec.get("lastName"),
>>> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
>>> +                                        "statusId", "PARTY_ENABLED",
>>> +                                        "userLogin", userLogin
>>> +                                        );                   
>>> +                                result = dispatcher.runSync("createPerson", person);
>>> +                            }
>>> +                            newPartyId = (String) result.get("partyId");
>>> +
>>> +                            Map<String, Object> partyIdentification = UtilMisc.toMap(
>>> +                                "partyId", newPartyId,
>>> +                                "partyIdentificationTypeId", "PARTY_IMPORT", 
>>> +                                "idValue", rec.get("partyId"),
>>> +                                "userLogin", userLogin
>>> +                                );
>>> +
>>> +                            result = dispatcher.runSync("createPartyIdentification", partyIdentification);
>>> +
>>> +                            Map<String, Object> partyRole = UtilMisc.toMap(
>>> +                                    "partyId", newPartyId,
>>> +                                    "roleTypeId", rec.get("roleTypeId"), 
>>> +                                    "userLogin", userLogin
>>> +                                    );
>>> +                            dispatcher.runSync("createPartyRole", partyRole);
>>> +
>>> +                            if (UtilValidate.isNotEmpty(rec.get("companyPartyId"))) {
>>> +                                List <GenericValue> companyCheck = delegator.findByAnd("PartyIdentification", UtilMisc.toMap("partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId")), null, false);
>>> +                                if (companyCheck.size() == 0) { // update party group
>>> +                                    // company does not exist so create
>>> +                                    Map<String, Object> companyPartyGroup = UtilMisc.toMap(
>>> +                                        "partyId", newCompanyPartyId, 
>>> +                                        "statusId", "PARTY_ENABLED",
>>> +                                        "userLogin", userLogin
>>> +                                        );                   
>>> +                                    result = dispatcher.runSync("createPartyGroup", companyPartyGroup);
>>> +                                    newCompanyPartyId = (String) result.get("partyId");
>>> +                                } else {
>>> +                                    newCompanyPartyId = EntityUtil.getFirst(companyCheck).getString("partyId");
>>> +                                }
>>> +
>>> +                                Map<String, Object> companyRole = UtilMisc.toMap(
>>> +                                        "partyId", newCompanyPartyId,
>>> +                                        "roleTypeId", "ACCOUNT", 
>>> +                                        "userLogin", userLogin
>>> +                                        );
>>> +                                dispatcher.runSync("createPartyRole", companyRole);
>>> +                                
>>> +                                // company exist, so create link
>>> +                                Map<String, Object> partyRelationship = UtilMisc.toMap(
>>> +                                    "partyIdTo", newPartyId,
>>> +                                    "partyIdFrom", newCompanyPartyId,
>>> +                                    "roleTypeIdFrom", "ACCOUNT",
>>> +                                    "partyRelationshipTypeId", "EMPLOYMENT",
>>> +                                    "userLogin", userLogin
>>> +                                    );                   
>>> +                                result = dispatcher.runSync("createPartyRelationship", partyRelationship);
>>> +                            }
>>> +                        }
>>> +                        Debug.logInfo(" =========================================================party created id: " + newPartyId, module);
>>> +                        partiesCreated++;
>>> +                    } else {
>>> +                        errMsgs.addAll(newErrMsgs);
>>> +                        newErrMsgs = FastList.newInstance();
>>> +                    }
>>> +                }
>>> +                
>>> +                currentContactMechTypeId = rec.get("contactMechTypeId");
>>> +                currentContactMechPurposeTypeId = rec.get("contactMechPurposeTypeId"); 
>>> +                // party correctly created (not updated) and contactMechtype provided?
>>> +                if (newPartyId != null && addParty && UtilValidate.isNotEmpty(currentContactMechTypeId)) {
>>> +                                        
>>> +                    // fill maps and check changes
>>> +                    Map<String, Object> emailAddress = UtilMisc.toMap(
>>> +                            "contactMechTypeId", "EMAIL_ADDRESS", 
>>> +                            "userLogin", userLogin
>>> +                            );
>>> +                    Boolean emailAddressChanged = false;
>>> +                    if ("EMAIL_ADDRESS".equals(currentContactMechTypeId)) {
>>> +                        emailAddress.put("infoString", rec.get("emailAddress"));
>>> +                        emailAddressChanged = lastEmailAddress == null || !lastEmailAddress.equals(rec.get("emailAddress"));
>>> +                        lastEmailAddress = rec.get("emailAddress");
>>> +                    }
>>> +                    
>>> +                    Map<String, Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
>>> +                    Boolean postalAddressChanged = false;
>>> +                    if ("POSTAL_ADDRESS".equals(currentContactMechTypeId)) {
>>> +                        postalAddress.put("address1", rec.get("address1"));
>>> +                        postalAddress.put("address2", rec.get("address2"));
>>> +                           postalAddress.put("city", rec.get("city"));
>>> +                        postalAddress.put("stateProvinceGeoId", rec.get("stateProvinceGeoId"));
>>> +                        postalAddress.put("countryGeoId", rec.get("countryGeoId"));
>>> +                        postalAddress.put("postalCode", rec.get("postalCode"));
>>> +                        postalAddressChanged =
>>> +                                lastAddress1 == null || !lastAddress1.equals(postalAddress.get("address1")) ||
>>> +                                lastAddress2 == null || !lastAddress2.equals(postalAddress.get("address2")) ||
>>> +                                lastCity == null || !lastCity.equals(postalAddress.get("city")) ||
>>> +                                lastCountryGeoId == null || !lastCountryGeoId.equals(postalAddress.get("countryGeoId"));
>>> +                        lastAddress1 = (String) postalAddress.get("address1");
>>> +                        lastAddress2 = (String) postalAddress.get("address2");
>>> +                        lastCity = (String) postalAddress.get("city");
>>> +                        lastCountryGeoId = (String) postalAddress.get("countryGeoId");
>>> +                    }                            
>>> +                            
>>> +                    Map<String, Object> telecomNumber = UtilMisc.toMap("userLogin", userLogin);
>>> +                    Boolean telecomNumberChanged = false;
>>> +                    if ("TELECOM_NUMBER".equals(currentContactMechTypeId)) {
>>> +                        telecomNumber.put("countryCode", rec.get("telCountryCode"));
>>> +                        telecomNumber.put("areaCode", rec.get("telAreaCode"));
>>> +                        telecomNumber.put("contactNumber", rec.get("telContactNumber"));
>>> +                        telecomNumberChanged = 
>>> +                                lastCountryCode == null || !lastCountryCode.equals(telecomNumber.get("countryCode")) ||
>>> +                                lastAreaCode == null || !lastAreaCode.equals(telecomNumber.get("areaCode")) ||
>>> +                                lastContactNumber == null || !lastContactNumber.equals(telecomNumber.get("contactNumber"));
>>> +                        lastCountryCode = (String) telecomNumber.get("countryCode");
>>> +                        lastAreaCode = (String) telecomNumber.get("areaCode");
>>> +                        lastContactNumber = (String) telecomNumber.get("contactNumber");
>>> +                    }
>>> +                    
>>> +                    Map<String, Object> partyContactMechPurpose = UtilMisc.toMap("partyId", newPartyId, "userLogin", userLogin);
>>> +                    Boolean partyContactMechPurposeChanged = false;
>>> +                    currentContactMechPurposeTypeId = rec.get("contactMechPurposeTypeId"); 
>>> +                    if (currentContactMechPurposeTypeId != null && ("TELECOM_NUMBER".equals(currentContactMechTypeId) || "POSTAL_ADDRESS".equals(currentContactMechTypeId) ||"EMAIL_ADDRESS".equals(currentContactMechTypeId))) {
>>> +                        partyContactMechPurpose.put("contactMechPurposeTypeId", currentContactMechPurposeTypeId);
>>> +                        partyContactMechPurposeChanged = (lastContactMechPurposeTypeId == null || !lastContactMechPurposeTypeId.equals(currentContactMechPurposeTypeId)) && !telecomNumberChanged && !postalAddressChanged && !emailAddressChanged;
>>> +                        Debug.logInfo("===================================last:" + lastContactMechPurposeTypeId + " current: " + currentContactMechPurposeTypeId + " t :" + telecomNumberChanged + " p: " + postalAddressChanged + " e: " + emailAddressChanged + " result: " + partyContactMechPurposeChanged, module); 
>>> +                    }
>>> +                    lastContactMechPurposeTypeId = currentContactMechPurposeTypeId;
>>> +                    
>>> +                    // update 
>>> +                    if (errMsgs.size() == 0) {
>>> +
>>> +                        if (postalAddressChanged) {
>>> +                            result = dispatcher.runSync("createPostalAddress", postalAddress);
>>> +                               newContactMechId = (String) result.get("contactMechId");
>>> +                            if (currentContactMechPurposeTypeId == null) {
>>> +                                currentContactMechPurposeTypeId = "GENERAL_LOCATION";
>>> +                            }
>>> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
>>> +                        }
>>> +
>>> +                        if (telecomNumberChanged) {
>>> +                            result = dispatcher.runSync("createTelecomNumber", telecomNumber);
>>> +                               newContactMechId = (String) result.get("contactMechId");
>>> +                            if (currentContactMechPurposeTypeId == null) {
>>> +                                currentContactMechPurposeTypeId= "PHONE_WORK";
>>> +                            }
>>> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
>>> +                        }
>>> +
>>> +                        if (emailAddressChanged) {
>>> +                            result = dispatcher.runSync("createContactMech", emailAddress);
>>> +                               newContactMechId = (String) result.get("contactMechId");
>>> +                            if (currentContactMechPurposeTypeId == null) {
>>> +                                currentContactMechPurposeTypeId = "PRIMARY_EMAIL";
>>> +                            }
>>> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
>>> +                        }
>>> +                        
>>> +                        if (partyContactMechPurposeChanged) {
>>> +                            partyContactMechPurpose.put("contactMechId", newContactMechId);
>>> +                            result = dispatcher.runSync("createPartyContactMechPurpose", partyContactMechPurpose);
>>> +                        }
>>> +                        
>>> +                    lastPartyId = currentPartyId;
>>> +                    errMsgs.addAll(newErrMsgs);
>>> +                    newErrMsgs = FastList.newInstance();
>>> +                    }
>>> +                }
>>> +
>>> +            }
>>> +            
>>> +        } 
>>> +        catch (GenericServiceException e) {
>>> +        Debug.logError(e, module);
>>> +            return ServiceUtil.returnError(e.getMessage());
>>> +        }
>>> +        
>>> +        catch (GenericEntityException e) {
>>> +                Debug.logError(e, module);
>>> +                return ServiceUtil.returnError(e.getMessage());
>>> +        }
>>> +    
>>> +        catch (IOException e) {
>>> +        Debug.logError(e, module);
>>> +            return ServiceUtil.returnError(e.getMessage());
>>> +        }
>>> +        
>>> +        if (errMsgs.size() > 0) {
>>> +            return ServiceUtil.returnError(errMsgs);
>>> +        }
>>> +
>>> +        result = ServiceUtil.returnSuccess(partiesCreated + " new parties created");
>>> +        return result;
>>> +    }
>>> }
>>> 
>>> Modified: ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml (original)
>>> +++ ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml Fri Jul 26 07:00:28 2013
>>> @@ -906,6 +906,22 @@ under the License.
>>>        <response name="success" type="view" value="FindAddressMatch"/>
>>>    </request-map>
>>> 
>>> +    <!-- Import export -->
>>> +    <request-map uri="ImportExport">
>>> +        <security https="true" auth="true"/>
>>> +        <response name="success" type="view" value="ImportExport"/>
>>> +    </request-map>
>>> +    <request-map uri="ExportPartyCsv.csv">
>>> +        <security https="true" auth="true"/>
>>> +        <response name="success" type="view" value="PartyExportCsv"/>
>>> +    </request-map>
>>> +    <request-map uri="uploadParty">
>>> +        <security auth="true" https="true"/>
>>> +        <event invoke="importParty" path="" type="service"/>
>>> +        <response name="success" type="request" value="ImportExport"/>
>>> +        <response name="error" type="view" value="ImportExport"/>
>>> +    </request-map>
>>> +
>>>   <!-- ================ SimpleContent Requests ================= -->
>>> 
>>>    <request-map uri="ViewSimpleContent">
>>> @@ -1352,6 +1368,10 @@ under the License.
>>> 
>>>    <view-map name="AddressMatchMap" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#AddressMatchMap"/>
>>>    <view-map name="FindAddressMatch" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#FindAddressMatch"/>
>>> +
>>> +    <view-map name="ImportExport" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#ImportExport"/>
>>> +    <view-map name="PartyExportCsv" type="screencsv" page="component://party/widget/partymgr/PartyScreens.xml#PartyExportCsv" content-type="text/csv" encoding="none"/>
>>> +
>>>    <view-map name="EditPartyContents" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#EditPartyContents"/>
>>>    <view-map name="editCarrierAccount" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#editCarrierAccount"/>
>>>    <view-map name="partyInvitation" type="screen" page="component://party/widget/partymgr/PartyInvitationScreens.xml#FindPartyInvitations"/>
>>> 
>>> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml (original)
>>> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml Fri Jul 26 07:00:28 2013
>>> @@ -1198,4 +1198,56 @@ under the License.
>>>            </hyperlink>
>>>        </field>
>>>    </form>
>>> +
>>> +    <form name="ExportParty" type="single" target="ExportPartyCsv.csv" title="" >
>>> +        <field name="partyId" tooltip="blank for all"><lookup target-form-name="LookupPartyName"/></field>
>>> +        <field name="submitButton" title="${uiLabelMap.CommonSubmit}"><submit button-type="button"/></field>
>>> +    </form>
>>> +
>>> +    <form name="ExportPartyCsv" list-name="listIt" target="" title="" type="list" view-size="99999"
>>> +        odd-row-style="alternate-row" header-row-style="header-row-2" default-table-style="basic-table hover-bar" paginate="false">
>>> +        <actions>
>>> +            <entity-condition entity-name="PartyExport">
>>> +                <condition-list combine="and">
>>> +                    <condition-list combine="or">
>>> +                        <condition-expr field-name="roleTypeId" value="CUSTOMER" operator="equals"/>
>>> +                        <condition-expr field-name="roleTypeId" value="SUPPLIER" operator="equals"/>
>>> +                        <condition-expr field-name="roleTypeId" value="EMPLOYEE" operator="equals"/>
>>> +                    </condition-list>
>>> +                    <condition-expr field-name="statusId" value="PARTY_DISABLED" operator="not-equals"/>
>>> +                    <condition-expr field-name="partyId" from-field="partyId" operator="equals" value="${parameters.partyId}" ignore-if-empty="true"/>
>>> +                </condition-list>
>>> +                <order-by field-name="partyId"/>
>>> +            </entity-condition>
>>> +        </actions>
>>> +        <field name="partyId" title="partyId"><display/></field>
>>> +        <field name="preferredCurrencyUomId" title="preferredCurrencyUomId"><display/></field>
>>> +        <field name="groupName" title="groupName"><display/></field>
>>> +        <field name="firstName" title="firstName"><display/></field>
>>> +        <field name="middleName" title="middleName"><display/></field>
>>> +        <field name="lastName" title="lastName"><display/></field>
>>> +        <field name="companyPartyId" title="companyPartyId"><display/></field>
>>> +        <field name="companyName" title="companyName"><display/></field>
>>> +        <field name="roleTypeId" title="roleTypeId"><display/></field>
>>> +        <field name="contactMechPurposeTypeId" title="contactMechPurposeTypeId"><display/></field>
>>> +        <field name="contactMechTypeId" title="contactMechTypeId"><display/></field>
>>> +        <field name="emailAddress" title="emailAddress"><display/></field>
>>> +        <field name="telCountryCode" title="telCountryCode"><display/></field>
>>> +        <field name="telAreaCode" title="telAreaCode"><display/></field>
>>> +        <field name="telContactNumber" title="telContactNumber"><display/></field>
>>> +        <field name="address1" title="address1"><display/></field>
>>> +        <field name="address2" title="address2"><display/></field>
>>> +        <field name="city" title="city"><display/></field>
>>> +        <field name="stateProvinceGeoId" title="stateProvinceGeoId"><display/></field>
>>> +        <field name="postalCode" title="postalCode"><display/></field>
>>> +        <field name="countryGeoId" title="countryGeoId"><display/></field>
>>> +    </form>
>>> +    
>>> +    <form name="ImportParty" type="upload" target="uploadParty" title="" >
>>> +        <field name="uploadedFile"><file/></field>
>>> +        <field name="submitButton" title="${uiLabelMap.CommonUpload}"><submit button-type="button"/></field>
>>> +    </form>
>>> +    
>>> +
>>> +    
>>> </forms>
>>> 
>>> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml (original)
>>> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml Fri Jul 26 07:00:28 2013
>>> @@ -35,6 +35,7 @@
>>>        </menu-item>
>>>        <menu-item name="addrmap" title="${uiLabelMap.PageTitleAddressMatchMap}"><link target="addressMatchMap"/></menu-item>
>>>        <menu-item name="partyinv" title="${uiLabelMap.PartyInvitation}"><link target="partyInvitation"/></menu-item>
>>> +        <menu-item name="importexport" title="${uiLabelMap.CommonImportExport}"><link target="ImportExport"/></menu-item>
>>>    </menu>
>>> 
>>>    <menu name="ProfileTabBar" extends="CommonTabBarMenu" extends-resource="component://common/widget/CommonMenus.xml"
>>> 
>>> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml
>>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>>> ==============================================================================
>>> --- ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml (original)
>>> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml Fri Jul 26 07:00:28 2013
>>> @@ -1302,4 +1302,41 @@ under the License.
>>>            </widgets>
>>>        </section>
>>>    </screen>
>>> +    <screen name="ImportExport">
>>> +        <section>
>>> +            <actions>
>>> +                <set field="titleProperty" value="CommonImportExport"/>
>>> +                <set field="headerItem" value="importexport"/>
>>> +            </actions>
>>> +            <widgets>
>>> +                <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
>>> +                    <decorator-section name="body">
>>> +                        <screenlet title="${uiLabelMap.PartyParty} ${uiLabelMap.CommonImportExport} ID Name, single role (employee, customer, supplier) and contactmechs">
>>> +                            <container style="lefthalf">
>>> +                                <label style="h2">${uiLabelMap.CommonImport}</label>
>>> +                                <include-form name="ImportParty" location="component://party/widget/partymgr/PartyForms.xml"/>
>>> +                            </container>
>>> +                            <container style="righthalf">
>>> +                                <label style="h2">${uiLabelMap.CommonExport}</label>
>>> +                                <include-form name="ExportParty" location="component://party/widget/partymgr/PartyForms.xml"/>
>>> +                            </container>
>>> +                         </screenlet>
>>> +                    </decorator-section>
>>> +                </decorator-screen>
>>> +            </widgets>
>>> +        </section>
>>> +    </screen>
>>> +    <screen name="PartyExportCsv">
>>> +        <section>
>>> +            <actions>
>>> +                <property-map resource="CommonUiLabels" map-name="uiLabelMap" global="true"/>
>>> +                <property-map resource="AccountingUiLabels" map-name="uiLabelMap" global="true"/>
>>> +                <set field="organizationPartyId" from-field="parameters.organizationPartyId"/>
>>> +            </actions>
>>> +            <widgets>
>>> +                <include-form name="ExportPartyCsv" location="component://party/widget/partymgr/PartyForms.xml"/>           
>>> +            </widgets>
>>> +        </section>
>>> +    </screen>
>>> +    
>>> </screens>
>>> 
>>> 
> 
>

Re: svn commit: r1507200 - in /ofbiz/trunk/applications/party: ./ data/ entitydef/ servicedef/ src/org/ofbiz/party/party/ webapp/partymgr/WEB-INF/ widget/partymgr/

Posted by Scott Gray <sc...@hotwaxmedia.com>.
> I replaced by
> Map<String, Object> postalAddress = new HashMap<String, Object>();
> postalAddress.put("userLogin", userLogin);

The correct approach is:
Map<String, Object> postalAddress = UtilMisc.<String, Object>toMap("userLogin", userLogin);

Regards
Scott

On 27/07/2013, at 8:48 PM, Jacques Le Roux wrote:

> Hi Hans,
> 
> There is an issue with this commit. It does not compile on trunk demo nor in my local copy/
> I wonder though 
> why Buildbot did not detect it (certainly it uses a more recent jdk version);
> and also why my IDE (Eclipse) does not detect it (I guess because I use 1.7 complying 1.6 to internally build);
> and also why this fails, because the same scheme is successfully used elsewhere in code.
> 
> The demo compilers (mine for ant is is jdk 1.6 22, ) say:
> 
> classes:
>  [javac16] Compiling 11 source files to /home/ofbiz/trunk/applications/party/build/classes
>  [javac16] /home/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java:2097: incompatible types
>  [javac16] found   : java.util.Map<java.lang.String,org.ofbiz.entity.GenericValue>
>  [javac16] required: java.util.Map<java.lang.String,java.lang.Object>
>  [javac16]                     Map<String, Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
>  [javac16]                                                                       ^
>  [javac16] /home/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java:2117: incompatible types
>  [javac16] found   : java.util.Map<java.lang.String,org.ofbiz.entity.GenericValue>
>  [javac16] required: java.util.Map<java.lang.String,java.lang.Object>
>  [javac16]                     Map<String, Object> telecomNumber = UtilMisc.toMap("userLogin", userLogin);
>  [javac16]                                                                       ^
>  [javac16] 2 errors
> 
> BUILD FAILED
> /home/ofbiz/trunk/build.xml:206: The following error occurred while executing this line:
> /home/ofbiz/trunk/applications/build.xml:67: The following error occurred while executing this line:
> /home/ofbiz/trunk/macros.xml:39: The following error occurred while executing this line:
> /home/ofbiz/trunk/common.xml:91: Compile failed; see the compiler error output for details.
> 
> Total time: 1 minute 2 seconds
> $ java -version
> java version "1.6.0_26"
> Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
> Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
> 
> 
> Of course replacing by
>    java.util.Map<java.lang.String,java.lang.Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
> as the compilers suggest does not help. 
> 
> I replaced by
> Map<String, Object> postalAddress = new HashMap<String, Object>();
> postalAddress.put("userLogin", userLogin);
> 
> And it worked, this must be investigated... I guess it's related with how UtilMisc.toMap() works. But still, looking at it it's quite weird, enough for me on that today...
> 
> Hans, I guess your jdk version compiles? Do you use a 1.6 version? Which one? Please let us know, thanks!
> 
> I restarted the trunk demo
> 
> Jacques
> 
> 
> ----- Original Message ----- 
> From: <ha...@apache.org>
> To: <co...@ofbiz.apache.org>
> Sent: Friday, July 26, 2013 9:00 AM
> Subject: svn commit: r1507200 - in /ofbiz/trunk/applications/party: ./ data/ entitydef/ servicedef/ src/org/ofbiz/party/party/ webapp/partymgr/WEB-INF/ widget/partymgr/
> 
> 
>> Author: hansbak
>> Date: Fri Jul 26 07:00:28 2013
>> New Revision: 1507200
>> 
>> URL: http://svn.apache.org/r1507200
>> Log:
>> add a csv party import and export function to the party component
>> 
>> Modified:
>>   ofbiz/trunk/applications/party/build.xml
>>   ofbiz/trunk/applications/party/data/PartyTypeData.xml
>>   ofbiz/trunk/applications/party/entitydef/entitymodel.xml
>>   ofbiz/trunk/applications/party/servicedef/services.xml
>>   ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java
>>   ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml
>>   ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml
>>   ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml
>>   ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml
>> 
>> Modified: ofbiz/trunk/applications/party/build.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/build.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/build.xml (original)
>> +++ ofbiz/trunk/applications/party/build.xml Fri Jul 26 07:00:28 2013
>> @@ -32,6 +32,7 @@ under the License.
>>    <path id="local.class.path">
>>        <!--<fileset dir="${lib.dir}" includes="*.jar"/>-->
>>        <fileset dir="../../framework/base/lib" includes="*.jar"/>
>> +        <fileset dir="../../framework/base/lib/commons" includes="*.jar"/>
>>        <fileset dir="../../framework/base/lib/j2eespecs" includes="*.jar"/>
>>        <fileset dir="../../framework/base/build/lib" includes="*.jar"/>
>>        <fileset dir="../../framework/entity/lib" includes="*.jar"/>
>> 
>> Modified: ofbiz/trunk/applications/party/data/PartyTypeData.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/data/PartyTypeData.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/data/PartyTypeData.xml (original)
>> +++ ofbiz/trunk/applications/party/data/PartyTypeData.xml Fri Jul 26 07:00:28 2013
>> @@ -441,4 +441,6 @@ under the License.
>>    <Enumeration description="Organization party" enumCode="" enumId="ORGANIZATION_PARTY" sequenceId="01" enumTypeId="GLOBAL_PREFERENCES"/>
>>    <Enumeration description="Visual Theme" enumCode="" enumId="VISUAL_THEME" sequenceId="02" enumTypeId="GLOBAL_PREFERENCES"/>
>> 
>> +    <PartyIdentificationType partyIdentificationTypeId="PARTY_IMPORT" description="Original ID in the system where this record was imported from"/>
>> +
>> </entity-engine-xml>
>> 
>> Modified: ofbiz/trunk/applications/party/entitydef/entitymodel.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/entitydef/entitymodel.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/entitydef/entitymodel.xml (original)
>> +++ ofbiz/trunk/applications/party/entitydef/entitymodel.xml Fri Jul 26 07:00:28 2013
>> @@ -2929,4 +2929,80 @@ under the License.
>>            <key-map field-name="partyId"/>
>>        </relation>
>>    </extend-entity>
>> +    <view-entity entity-name="PartyExport" package-name="org.ofbiz.accounting.reports">
>> +        <member-entity entity-alias="PRT" entity-name="Party"/>
>> +        <member-entity entity-alias="GRP" entity-name="PartyGroup"/>
>> +        <member-entity entity-alias="PER" entity-name="Person"/>
>> +        <member-entity entity-alias="PR" entity-name="PartyRelationship"/>
>> +        <member-entity entity-alias="CGRP" entity-name="PartyGroup"/>
>> +        <member-entity entity-alias="PRL" entity-name="PartyRole"/>
>> +        <member-entity entity-alias="PCM" entity-name="PartyContactMech"/>
>> +        <member-entity entity-alias="PCP" entity-name="PartyContactMechPurpose"/>
>> +        <member-entity entity-alias="CM" entity-name="ContactMech"/>
>> +        <member-entity entity-alias="TN" entity-name="TelecomNumber"/>
>> +        <member-entity entity-alias="PA" entity-name="PostalAddress"/>
>> +        <alias entity-alias="PRT" name="partyId" />
>> +        <alias entity-alias="PRT" name="statusId" />
>> +        <alias entity-alias="PRT" name="preferredCurrencyUomId" />
>> +        <alias entity-alias="GRP" name="groupName"/>
>> +        <alias entity-alias="PER" name="firstName"/>
>> +        <alias entity-alias="PER" name="middleName"/>
>> +        <alias entity-alias="PER" name="lastName"/>
>> +        <alias entity-alias="PR" name="companyPartyId" field="partyIdFrom"/>
>> +        <alias entity-alias="CGRP" name="companyName" field="groupName"/>
>> +        <alias entity-alias="PRL" name="roleTypeId"/>
>> +        <alias entity-alias="CM" name="contactMechTypeId"/>
>> +        <alias entity-alias="PCP" name="contactMechPurposeTypeId"/>
>> +        <alias entity-alias="CM" name="emailAddress" field="infoString"/>
>> +        <alias entity-alias="TN" name="telCountryCode" field="countryCode"/>
>> +        <alias entity-alias="TN" name="telAreaCode"  field="areaCode"/>
>> +        <alias entity-alias="TN" name="telContactNumber" field="contactNumber"/>
>> +        <alias entity-alias="PA" name="address1"/>
>> +        <alias entity-alias="PA" name="address2"/>
>> +        <alias entity-alias="PA" name="city"/>
>> +        <alias entity-alias="PA" name="stateProvinceGeoId"/>
>> +        <alias entity-alias="PA" name="postalCode"/>
>> +        <alias entity-alias="PA" name="countryGeoId"/>
>> +        <view-link entity-alias="PRT" rel-entity-alias="GRP" rel-optional="true">
>> +            <key-map field-name="partyId"/>
>> +        </view-link>
>> +        <view-link entity-alias="PRT" rel-entity-alias="PER" rel-optional="true">
>> +            <key-map field-name="partyId"/>
>> +        </view-link>
>> +        <view-link entity-alias="PRT" rel-entity-alias="PR" rel-optional="true">
>> +            <key-map field-name="partyId" rel-field-name="partyIdTo"/>
>> +            <entity-condition>
>> +                <condition-list combine="and">
>> +                    <condition-expr field-name="roleTypeIdFrom" entity-alias="PR" value="ACCOUNT"/>
>> +                    <condition-expr field-name="partyRelationshipTypeId" entity-alias="PR" value="EMPLOYMENT"/>
>> +                </condition-list>
>> +            </entity-condition>
>> +        </view-link>
>> +        <view-link entity-alias="PR" rel-entity-alias="CGRP" rel-optional="true">
>> +            <key-map field-name="partyIdFrom" rel-field-name="partyId"/>
>> +        </view-link>
>> +        <view-link entity-alias="PRT" rel-entity-alias="PRL" rel-optional="true">
>> +            <key-map field-name="partyId"/>
>> +        </view-link>
>> +        <view-link entity-alias="PRT" rel-entity-alias="PCM" rel-optional="true">
>> +            <key-map field-name="partyId"/>
>> +            <entity-condition filter-by-date="true"/>
>> +        </view-link>
>> +        <view-link entity-alias="PCM" rel-entity-alias="PA" rel-optional="true">
>> +            <key-map field-name="contactMechId"/>
>> +        </view-link>
>> +        <view-link entity-alias="PCM" rel-entity-alias="CM" rel-optional="true">
>> +            <key-map field-name="contactMechId"/>
>> +        </view-link>
>> +        <view-link entity-alias="PCM" rel-entity-alias="TN" rel-optional="true">
>> +            <key-map field-name="contactMechId"/>
>> +        </view-link>
>> +        <view-link entity-alias="PCM" rel-entity-alias="PCP" rel-optional="true">
>> +            <key-map field-name="contactMechId"/>
>> +            <key-map field-name="partyId"/>
>> +            <entity-condition filter-by-date="true"/>
>> +        </view-link>
>> +    </view-entity>
>> +    
>> +    
>> </entitymodel>
>> 
>> Modified: ofbiz/trunk/applications/party/servicedef/services.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/servicedef/services.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/servicedef/services.xml (original)
>> +++ ofbiz/trunk/applications/party/servicedef/services.xml Fri Jul 26 07:00:28 2013
>> @@ -1355,4 +1355,12 @@ under the License.
>>        <attribute name="userLoginId" type="String" mode="IN" optional="false"/>
>>        <attribute name="productStoreId" type="String" mode="IN" optional="false"/>
>>    </service>
>> +    
>> +    <service name="importParty" engine="java"
>> +        location="org.ofbiz.party.party.PartyServices" invoke="importParty" auth="true">
>> +        <description>Import an party with related main role, company and contact info in csv format, will ignore parties already entered</description>
>> +        <permission-service service-name="partyGroupPermissionCheck" main-action="CREATE"/>
>> +        <attribute mode="IN" name="uploadedFile" type="java.nio.ByteBuffer" optional="true" />
>> +    </service>
>> +    
>> </services>
>> 
>> Modified: ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java (original)
>> +++ ofbiz/trunk/applications/party/src/org/ofbiz/party/party/PartyServices.java Fri Jul 26 07:00:28 2013
>> @@ -24,12 +24,18 @@ import java.util.Collection;
>> import java.util.List;
>> import java.util.Locale;
>> import java.util.Map;
>> +import java.io.BufferedReader;
>> +import java.io.IOException;
>> +import java.io.StringReader;
>> import java.nio.ByteBuffer;
>> import java.nio.charset.Charset;
>> 
>> import javolution.util.FastList;
>> import javolution.util.FastMap;
>> 
>> +import org.apache.commons.csv.CSVFormat;
>> +import org.apache.commons.csv.CSVRecord;
>> +import org.apache.commons.csv.CSVFormat.CSVFormatBuilder;
>> import org.ofbiz.base.util.Debug;
>> import org.ofbiz.base.util.UtilDateTime;
>> import org.ofbiz.base.util.UtilGenerics;
>> @@ -1850,4 +1856,353 @@ public class PartyServices {
>>        return result;
>>    }
>> 
>> +    public static Map<String, Object> importParty(DispatchContext dctx, Map<String, Object> context) {
>> +        Delegator delegator = dctx.getDelegator();
>> +        LocalDispatcher dispatcher = dctx.getDispatcher();
>> +        GenericValue userLogin = (GenericValue) context.get("userLogin");
>> +        ByteBuffer fileBytes = (ByteBuffer) context.get("uploadedFile");
>> +        String encoding = System.getProperty("file.encoding");
>> +        String csvString = Charset.forName(encoding).decode(fileBytes).toString();
>> +        final BufferedReader csvReader = new BufferedReader(new StringReader(csvString));
>> +        final CSVFormatBuilder builder = CSVFormat.newBuilder(',').withQuoteChar('"').withHeader();
>> +        CSVFormat fmt = builder.build();
>> +        List<String> errMsgs = FastList.newInstance();
>> +        List<String> newErrMsgs = FastList.newInstance();
>> +        String lastPartyId = null;        // last partyId read from the csv file
>> +        String currentPartyId = null;     // current partyId from the csv file
>> +        String newPartyId = null;        // new to create/update partyId in the system
>> +        String newCompanyPartyId = null;
>> +        int partiesCreated = 0;
>> +        Map<String, Object> result = null;
>> +        String newContactMechId = null;
>> +        String currentContactMechTypeId = null;
>> +
>> +        String lastAddress1 = null;
>> +        String lastAddress2 = null;
>> +        String lastCity = null;
>> +        String lastCountryGeoId = null;
>> +
>> +        String lastEmailAddress = null;
>> +
>> +        String lastCountryCode = null;
>> +        String lastAreaCode = null;
>> +        String lastContactNumber = null;
>> +        
>> +        String lastContactMechPurposeTypeId = null;
>> +        String currentContactMechPurposeTypeId = null;
>> +        
>> +        Boolean addParty = false; // when modify party, contact mech not added again
>> +        
>> +        if (fileBytes == null) {
>> +            return ServiceUtil.returnError("Uploaded file data not found");
>> +        }
>> +        
>> +        try {
>> +            for(final CSVRecord rec : fmt.parse(csvReader)) {
>> +                if (UtilValidate.isNotEmpty(rec.get("partyId"))) {
>> +                    currentPartyId =  rec.get("partyId");
>> +                }
>> +                if (lastPartyId == null || !currentPartyId.equals(lastPartyId)) {
>> +                    newPartyId = null;
>> +                    currentContactMechPurposeTypeId = null;
>> +                    lastAddress1 = null;
>> +                    lastAddress2 = null;
>> +                    lastCity = null;
>> +                    lastCountryGeoId = null;
>> +
>> +                    lastEmailAddress = null;
>> +
>> +                    lastCountryCode = null;
>> +                    lastAreaCode = null;
>> +                    lastContactNumber = null;
>> +                    
>> +                    // party validation
>> +                    List <GenericValue> currencyCheck = delegator.findByAnd("Uom", UtilMisc.toMap("abbreviation", rec.get("preferredCurrencyUomId"), "uomTypeId", "CURRENCY_MEASURE"), null, false);
>> +                    if (UtilValidate.isNotEmpty(rec.get("preferredCurrencyUomId")) && currencyCheck.size() == 0) {
>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "Currency code not found for: " + rec.get("preferredCurrencyUomId"));
>> +                    }
>> +
>> +                    if (UtilValidate.isEmpty(rec.get("roleTypeId"))) {
>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": Mandatory roletype is missing, possible values: CUSTOMER, SUPPLIER, EMPLOYEE and more....");
>> +                    } else if (delegator.findOne("RoleType", UtilMisc.<String, Object>toMap("roleTypeId", rec.get("roleTypeId")), true) == null) {
>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": RoletypeId is not valid: " + rec.get("roleTypeId") );
>> +                    }
>> +
>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) &&
>> +                            delegator.findOne("ContactMechType", true, UtilMisc.toMap("contactMechTypeId", rec.get("contactMechTypeId"))) == null) {
>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + " contactMechTypeId code not found for: " + rec.get("contactMechTypeId"));
>> +                    }
>> +                    
>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechPurposeTypeId")) &&
>> +                            delegator.findOne("ContactMechPurposeType", true, UtilMisc.toMap("contactMechPurposeTypeId", rec.get("contactMechPurposeTypeId"))) == null) {
>> +                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "contactMechPurposeTypeId code not found for: " + rec.get("contactMechPurposeTypeId"));
>> +                    }
>> +                    
>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "POSTAL_ADDRESS".equals(rec.get("contactMechTypeId"))) {
>> +                        if (UtilValidate.isEmpty(rec.get("countryGeoId"))) {
>> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "Country code missing");
>> +                        } else {
>> +                            List <GenericValue> countryCheck = delegator.findByAnd("Geo", UtilMisc.toMap("geoTypeId", "COUNTRY", "abbreviation", rec.get("countryGeoId")), null, false);
>> +                            if (countryCheck.size() == 0) {
>> +                                newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " Invalid Country code: " + rec.get("countryGeoId"));
>> +                            }
>> +                        }
>> +
>> +                        if (UtilValidate.isEmpty(rec.get("city"))) {
>> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + "City name is missing");
>> +                        } 
>> +
>> +                        if (UtilValidate.isNotEmpty(rec.get("stateProvinceGeoId"))) {
>> +                            List <GenericValue> stateCheck = delegator.findByAnd("Geo", UtilMisc.toMap("geoTypeId", "STATE", "abbreviation", rec.get("stateProvinceGeoId")), null, false);
>> +                            if (stateCheck.size() == 0) {
>> +                                newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " Invalid stateProvinceGeoId code: " + rec.get("countryGeoId"));
>> +                            }
>> +                        }
>> +                    }
>> +
>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "TELECOM_NUMBER".equals(rec.get("contactMechTypeId"))) {
>> +                        if (UtilValidate.isEmpty(rec.get("telAreaCode")) && UtilValidate.isEmpty(rec.get("telAreaCode"))) {
>> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " telephone number missing");
>> +                        }
>> +                    }
>> +          
>> +                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "EMAIL_ADDRESS".equals(rec.get("contactMechTypeId"))) {
>> +                        if (UtilValidate.isEmpty(rec.get("emailAddress"))) {
>> +                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " email address missing");
>> +                        }
>> +                    }
>> +          
>> +                    if (errMsgs.size() == 0) {
>> +                        List <GenericValue> partyCheck = delegator.findByAnd("PartyIdentification", UtilMisc.toMap("partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId")), null, false);
>> +                        addParty = partyCheck.size() == 0;
>> +                        if (!addParty) { // update party
>> +                            newPartyId = EntityUtil.getFirst(partyCheck).getString("partyId");
>> +                            
>> +                            if (UtilValidate.isNotEmpty(rec.get("groupName"))) {
>> +                                Map<String, Object> partyGroup = UtilMisc.toMap(
>> +                                        "partyId", newPartyId,
>> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
>> +                                        "groupName", rec.get("groupName"),
>> +                                        "userLogin", userLogin
>> +                                        );                   
>> +                                result = dispatcher.runSync("updatePartyGroup", partyGroup);
>> +                            } else { // person
>> +                                Map<String, Object> person = UtilMisc.toMap(
>> +                                        "partyId", newPartyId,
>> +                                        "firstName", rec.get("firstName"),
>> +                                        "middleName", rec.get("midleName"),
>> +                                        "lastName", rec.get("lastName"),
>> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
>> +                                        "userLogin", userLogin
>> +                                        );                   
>> +                                result = dispatcher.runSync("updatePerson", person);
>> +                            }
>> +                            
>> +                        } else { // create new party
>> +                            if (UtilValidate.isNotEmpty(rec.get("groupName"))) {
>> +                                Map<String, Object> partyGroup = UtilMisc.toMap(
>> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
>> +                                        "groupName", rec.get("groupName"),
>> +                                        "userLogin", userLogin,
>> +                                        "statusId", "PARTY_ENABLED"
>> +                                        );                   
>> +                                result = dispatcher.runSync("createPartyGroup", partyGroup);
>> +                            } else { // person
>> +                                Map<String, Object> person = UtilMisc.toMap(
>> +                                        "firstName", rec.get("firstName"),
>> +                                        "middleName", rec.get("midleName"),
>> +                                        "lastName", rec.get("lastName"),
>> +                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
>> +                                        "statusId", "PARTY_ENABLED",
>> +                                        "userLogin", userLogin
>> +                                        );                   
>> +                                result = dispatcher.runSync("createPerson", person);
>> +                            }
>> +                            newPartyId = (String) result.get("partyId");
>> +
>> +                            Map<String, Object> partyIdentification = UtilMisc.toMap(
>> +                                "partyId", newPartyId,
>> +                                "partyIdentificationTypeId", "PARTY_IMPORT", 
>> +                                "idValue", rec.get("partyId"),
>> +                                "userLogin", userLogin
>> +                                );
>> +
>> +                            result = dispatcher.runSync("createPartyIdentification", partyIdentification);
>> +
>> +                            Map<String, Object> partyRole = UtilMisc.toMap(
>> +                                    "partyId", newPartyId,
>> +                                    "roleTypeId", rec.get("roleTypeId"), 
>> +                                    "userLogin", userLogin
>> +                                    );
>> +                            dispatcher.runSync("createPartyRole", partyRole);
>> +
>> +                            if (UtilValidate.isNotEmpty(rec.get("companyPartyId"))) {
>> +                                List <GenericValue> companyCheck = delegator.findByAnd("PartyIdentification", UtilMisc.toMap("partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId")), null, false);
>> +                                if (companyCheck.size() == 0) { // update party group
>> +                                    // company does not exist so create
>> +                                    Map<String, Object> companyPartyGroup = UtilMisc.toMap(
>> +                                        "partyId", newCompanyPartyId, 
>> +                                        "statusId", "PARTY_ENABLED",
>> +                                        "userLogin", userLogin
>> +                                        );                   
>> +                                    result = dispatcher.runSync("createPartyGroup", companyPartyGroup);
>> +                                    newCompanyPartyId = (String) result.get("partyId");
>> +                                } else {
>> +                                    newCompanyPartyId = EntityUtil.getFirst(companyCheck).getString("partyId");
>> +                                }
>> +
>> +                                Map<String, Object> companyRole = UtilMisc.toMap(
>> +                                        "partyId", newCompanyPartyId,
>> +                                        "roleTypeId", "ACCOUNT", 
>> +                                        "userLogin", userLogin
>> +                                        );
>> +                                dispatcher.runSync("createPartyRole", companyRole);
>> +                                
>> +                                // company exist, so create link
>> +                                Map<String, Object> partyRelationship = UtilMisc.toMap(
>> +                                    "partyIdTo", newPartyId,
>> +                                    "partyIdFrom", newCompanyPartyId,
>> +                                    "roleTypeIdFrom", "ACCOUNT",
>> +                                    "partyRelationshipTypeId", "EMPLOYMENT",
>> +                                    "userLogin", userLogin
>> +                                    );                   
>> +                                result = dispatcher.runSync("createPartyRelationship", partyRelationship);
>> +                            }
>> +                        }
>> +                        Debug.logInfo(" =========================================================party created id: " + newPartyId, module);
>> +                        partiesCreated++;
>> +                    } else {
>> +                        errMsgs.addAll(newErrMsgs);
>> +                        newErrMsgs = FastList.newInstance();
>> +                    }
>> +                }
>> +                
>> +                currentContactMechTypeId = rec.get("contactMechTypeId");
>> +                currentContactMechPurposeTypeId = rec.get("contactMechPurposeTypeId"); 
>> +                // party correctly created (not updated) and contactMechtype provided?
>> +                if (newPartyId != null && addParty && UtilValidate.isNotEmpty(currentContactMechTypeId)) {
>> +                                        
>> +                    // fill maps and check changes
>> +                    Map<String, Object> emailAddress = UtilMisc.toMap(
>> +                            "contactMechTypeId", "EMAIL_ADDRESS", 
>> +                            "userLogin", userLogin
>> +                            );
>> +                    Boolean emailAddressChanged = false;
>> +                    if ("EMAIL_ADDRESS".equals(currentContactMechTypeId)) {
>> +                        emailAddress.put("infoString", rec.get("emailAddress"));
>> +                        emailAddressChanged = lastEmailAddress == null || !lastEmailAddress.equals(rec.get("emailAddress"));
>> +                        lastEmailAddress = rec.get("emailAddress");
>> +                    }
>> +                    
>> +                    Map<String, Object> postalAddress = UtilMisc.toMap("userLogin", userLogin);
>> +                    Boolean postalAddressChanged = false;
>> +                    if ("POSTAL_ADDRESS".equals(currentContactMechTypeId)) {
>> +                        postalAddress.put("address1", rec.get("address1"));
>> +                        postalAddress.put("address2", rec.get("address2"));
>> +                           postalAddress.put("city", rec.get("city"));
>> +                        postalAddress.put("stateProvinceGeoId", rec.get("stateProvinceGeoId"));
>> +                        postalAddress.put("countryGeoId", rec.get("countryGeoId"));
>> +                        postalAddress.put("postalCode", rec.get("postalCode"));
>> +                        postalAddressChanged =
>> +                                lastAddress1 == null || !lastAddress1.equals(postalAddress.get("address1")) ||
>> +                                lastAddress2 == null || !lastAddress2.equals(postalAddress.get("address2")) ||
>> +                                lastCity == null || !lastCity.equals(postalAddress.get("city")) ||
>> +                                lastCountryGeoId == null || !lastCountryGeoId.equals(postalAddress.get("countryGeoId"));
>> +                        lastAddress1 = (String) postalAddress.get("address1");
>> +                        lastAddress2 = (String) postalAddress.get("address2");
>> +                        lastCity = (String) postalAddress.get("city");
>> +                        lastCountryGeoId = (String) postalAddress.get("countryGeoId");
>> +                    }                            
>> +                            
>> +                    Map<String, Object> telecomNumber = UtilMisc.toMap("userLogin", userLogin);
>> +                    Boolean telecomNumberChanged = false;
>> +                    if ("TELECOM_NUMBER".equals(currentContactMechTypeId)) {
>> +                        telecomNumber.put("countryCode", rec.get("telCountryCode"));
>> +                        telecomNumber.put("areaCode", rec.get("telAreaCode"));
>> +                        telecomNumber.put("contactNumber", rec.get("telContactNumber"));
>> +                        telecomNumberChanged = 
>> +                                lastCountryCode == null || !lastCountryCode.equals(telecomNumber.get("countryCode")) ||
>> +                                lastAreaCode == null || !lastAreaCode.equals(telecomNumber.get("areaCode")) ||
>> +                                lastContactNumber == null || !lastContactNumber.equals(telecomNumber.get("contactNumber"));
>> +                        lastCountryCode = (String) telecomNumber.get("countryCode");
>> +                        lastAreaCode = (String) telecomNumber.get("areaCode");
>> +                        lastContactNumber = (String) telecomNumber.get("contactNumber");
>> +                    }
>> +                    
>> +                    Map<String, Object> partyContactMechPurpose = UtilMisc.toMap("partyId", newPartyId, "userLogin", userLogin);
>> +                    Boolean partyContactMechPurposeChanged = false;
>> +                    currentContactMechPurposeTypeId = rec.get("contactMechPurposeTypeId"); 
>> +                    if (currentContactMechPurposeTypeId != null && ("TELECOM_NUMBER".equals(currentContactMechTypeId) || "POSTAL_ADDRESS".equals(currentContactMechTypeId) ||"EMAIL_ADDRESS".equals(currentContactMechTypeId))) {
>> +                        partyContactMechPurpose.put("contactMechPurposeTypeId", currentContactMechPurposeTypeId);
>> +                        partyContactMechPurposeChanged = (lastContactMechPurposeTypeId == null || !lastContactMechPurposeTypeId.equals(currentContactMechPurposeTypeId)) && !telecomNumberChanged && !postalAddressChanged && !emailAddressChanged;
>> +                        Debug.logInfo("===================================last:" + lastContactMechPurposeTypeId + " current: " + currentContactMechPurposeTypeId + " t :" + telecomNumberChanged + " p: " + postalAddressChanged + " e: " + emailAddressChanged + " result: " + partyContactMechPurposeChanged, module); 
>> +                    }
>> +                    lastContactMechPurposeTypeId = currentContactMechPurposeTypeId;
>> +                    
>> +                    // update 
>> +                    if (errMsgs.size() == 0) {
>> +
>> +                        if (postalAddressChanged) {
>> +                            result = dispatcher.runSync("createPostalAddress", postalAddress);
>> +                               newContactMechId = (String) result.get("contactMechId");
>> +                            if (currentContactMechPurposeTypeId == null) {
>> +                                currentContactMechPurposeTypeId = "GENERAL_LOCATION";
>> +                            }
>> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
>> +                        }
>> +
>> +                        if (telecomNumberChanged) {
>> +                            result = dispatcher.runSync("createTelecomNumber", telecomNumber);
>> +                               newContactMechId = (String) result.get("contactMechId");
>> +                            if (currentContactMechPurposeTypeId == null) {
>> +                                currentContactMechPurposeTypeId= "PHONE_WORK";
>> +                            }
>> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
>> +                        }
>> +
>> +                        if (emailAddressChanged) {
>> +                            result = dispatcher.runSync("createContactMech", emailAddress);
>> +                               newContactMechId = (String) result.get("contactMechId");
>> +                            if (currentContactMechPurposeTypeId == null) {
>> +                                currentContactMechPurposeTypeId = "PRIMARY_EMAIL";
>> +                            }
>> +                            dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId, "contactMechId", newContactMechId, "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
>> +                        }
>> +                        
>> +                        if (partyContactMechPurposeChanged) {
>> +                            partyContactMechPurpose.put("contactMechId", newContactMechId);
>> +                            result = dispatcher.runSync("createPartyContactMechPurpose", partyContactMechPurpose);
>> +                        }
>> +                        
>> +                    lastPartyId = currentPartyId;
>> +                    errMsgs.addAll(newErrMsgs);
>> +                    newErrMsgs = FastList.newInstance();
>> +                    }
>> +                }
>> +
>> +            }
>> +            
>> +        } 
>> +        catch (GenericServiceException e) {
>> +        Debug.logError(e, module);
>> +            return ServiceUtil.returnError(e.getMessage());
>> +        }
>> +        
>> +        catch (GenericEntityException e) {
>> +                Debug.logError(e, module);
>> +                return ServiceUtil.returnError(e.getMessage());
>> +        }
>> +    
>> +        catch (IOException e) {
>> +        Debug.logError(e, module);
>> +            return ServiceUtil.returnError(e.getMessage());
>> +        }
>> +        
>> +        if (errMsgs.size() > 0) {
>> +            return ServiceUtil.returnError(errMsgs);
>> +        }
>> +
>> +        result = ServiceUtil.returnSuccess(partiesCreated + " new parties created");
>> +        return result;
>> +    }
>> }
>> 
>> Modified: ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml (original)
>> +++ ofbiz/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml Fri Jul 26 07:00:28 2013
>> @@ -906,6 +906,22 @@ under the License.
>>        <response name="success" type="view" value="FindAddressMatch"/>
>>    </request-map>
>> 
>> +    <!-- Import export -->
>> +    <request-map uri="ImportExport">
>> +        <security https="true" auth="true"/>
>> +        <response name="success" type="view" value="ImportExport"/>
>> +    </request-map>
>> +    <request-map uri="ExportPartyCsv.csv">
>> +        <security https="true" auth="true"/>
>> +        <response name="success" type="view" value="PartyExportCsv"/>
>> +    </request-map>
>> +    <request-map uri="uploadParty">
>> +        <security auth="true" https="true"/>
>> +        <event invoke="importParty" path="" type="service"/>
>> +        <response name="success" type="request" value="ImportExport"/>
>> +        <response name="error" type="view" value="ImportExport"/>
>> +    </request-map>
>> +
>>   <!-- ================ SimpleContent Requests ================= -->
>> 
>>    <request-map uri="ViewSimpleContent">
>> @@ -1352,6 +1368,10 @@ under the License.
>> 
>>    <view-map name="AddressMatchMap" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#AddressMatchMap"/>
>>    <view-map name="FindAddressMatch" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#FindAddressMatch"/>
>> +
>> +    <view-map name="ImportExport" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#ImportExport"/>
>> +    <view-map name="PartyExportCsv" type="screencsv" page="component://party/widget/partymgr/PartyScreens.xml#PartyExportCsv" content-type="text/csv" encoding="none"/>
>> +
>>    <view-map name="EditPartyContents" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#EditPartyContents"/>
>>    <view-map name="editCarrierAccount" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#editCarrierAccount"/>
>>    <view-map name="partyInvitation" type="screen" page="component://party/widget/partymgr/PartyInvitationScreens.xml#FindPartyInvitations"/>
>> 
>> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml (original)
>> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyForms.xml Fri Jul 26 07:00:28 2013
>> @@ -1198,4 +1198,56 @@ under the License.
>>            </hyperlink>
>>        </field>
>>    </form>
>> +
>> +    <form name="ExportParty" type="single" target="ExportPartyCsv.csv" title="" >
>> +        <field name="partyId" tooltip="blank for all"><lookup target-form-name="LookupPartyName"/></field>
>> +        <field name="submitButton" title="${uiLabelMap.CommonSubmit}"><submit button-type="button"/></field>
>> +    </form>
>> +
>> +    <form name="ExportPartyCsv" list-name="listIt" target="" title="" type="list" view-size="99999"
>> +        odd-row-style="alternate-row" header-row-style="header-row-2" default-table-style="basic-table hover-bar" paginate="false">
>> +        <actions>
>> +            <entity-condition entity-name="PartyExport">
>> +                <condition-list combine="and">
>> +                    <condition-list combine="or">
>> +                        <condition-expr field-name="roleTypeId" value="CUSTOMER" operator="equals"/>
>> +                        <condition-expr field-name="roleTypeId" value="SUPPLIER" operator="equals"/>
>> +                        <condition-expr field-name="roleTypeId" value="EMPLOYEE" operator="equals"/>
>> +                    </condition-list>
>> +                    <condition-expr field-name="statusId" value="PARTY_DISABLED" operator="not-equals"/>
>> +                    <condition-expr field-name="partyId" from-field="partyId" operator="equals" value="${parameters.partyId}" ignore-if-empty="true"/>
>> +                </condition-list>
>> +                <order-by field-name="partyId"/>
>> +            </entity-condition>
>> +        </actions>
>> +        <field name="partyId" title="partyId"><display/></field>
>> +        <field name="preferredCurrencyUomId" title="preferredCurrencyUomId"><display/></field>
>> +        <field name="groupName" title="groupName"><display/></field>
>> +        <field name="firstName" title="firstName"><display/></field>
>> +        <field name="middleName" title="middleName"><display/></field>
>> +        <field name="lastName" title="lastName"><display/></field>
>> +        <field name="companyPartyId" title="companyPartyId"><display/></field>
>> +        <field name="companyName" title="companyName"><display/></field>
>> +        <field name="roleTypeId" title="roleTypeId"><display/></field>
>> +        <field name="contactMechPurposeTypeId" title="contactMechPurposeTypeId"><display/></field>
>> +        <field name="contactMechTypeId" title="contactMechTypeId"><display/></field>
>> +        <field name="emailAddress" title="emailAddress"><display/></field>
>> +        <field name="telCountryCode" title="telCountryCode"><display/></field>
>> +        <field name="telAreaCode" title="telAreaCode"><display/></field>
>> +        <field name="telContactNumber" title="telContactNumber"><display/></field>
>> +        <field name="address1" title="address1"><display/></field>
>> +        <field name="address2" title="address2"><display/></field>
>> +        <field name="city" title="city"><display/></field>
>> +        <field name="stateProvinceGeoId" title="stateProvinceGeoId"><display/></field>
>> +        <field name="postalCode" title="postalCode"><display/></field>
>> +        <field name="countryGeoId" title="countryGeoId"><display/></field>
>> +    </form>
>> +    
>> +    <form name="ImportParty" type="upload" target="uploadParty" title="" >
>> +        <field name="uploadedFile"><file/></field>
>> +        <field name="submitButton" title="${uiLabelMap.CommonUpload}"><submit button-type="button"/></field>
>> +    </form>
>> +    
>> +
>> +    
>> </forms>
>> 
>> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml (original)
>> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyMenus.xml Fri Jul 26 07:00:28 2013
>> @@ -35,6 +35,7 @@
>>        </menu-item>
>>        <menu-item name="addrmap" title="${uiLabelMap.PageTitleAddressMatchMap}"><link target="addressMatchMap"/></menu-item>
>>        <menu-item name="partyinv" title="${uiLabelMap.PartyInvitation}"><link target="partyInvitation"/></menu-item>
>> +        <menu-item name="importexport" title="${uiLabelMap.CommonImportExport}"><link target="ImportExport"/></menu-item>
>>    </menu>
>> 
>>    <menu name="ProfileTabBar" extends="CommonTabBarMenu" extends-resource="component://common/widget/CommonMenus.xml"
>> 
>> Modified: ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml?rev=1507200&r1=1507199&r2=1507200&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml (original)
>> +++ ofbiz/trunk/applications/party/widget/partymgr/PartyScreens.xml Fri Jul 26 07:00:28 2013
>> @@ -1302,4 +1302,41 @@ under the License.
>>            </widgets>
>>        </section>
>>    </screen>
>> +    <screen name="ImportExport">
>> +        <section>
>> +            <actions>
>> +                <set field="titleProperty" value="CommonImportExport"/>
>> +                <set field="headerItem" value="importexport"/>
>> +            </actions>
>> +            <widgets>
>> +                <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
>> +                    <decorator-section name="body">
>> +                        <screenlet title="${uiLabelMap.PartyParty} ${uiLabelMap.CommonImportExport} ID Name, single role (employee, customer, supplier) and contactmechs">
>> +                            <container style="lefthalf">
>> +                                <label style="h2">${uiLabelMap.CommonImport}</label>
>> +                                <include-form name="ImportParty" location="component://party/widget/partymgr/PartyForms.xml"/>
>> +                            </container>
>> +                            <container style="righthalf">
>> +                                <label style="h2">${uiLabelMap.CommonExport}</label>
>> +                                <include-form name="ExportParty" location="component://party/widget/partymgr/PartyForms.xml"/>
>> +                            </container>
>> +                         </screenlet>
>> +                    </decorator-section>
>> +                </decorator-screen>
>> +            </widgets>
>> +        </section>
>> +    </screen>
>> +    <screen name="PartyExportCsv">
>> +        <section>
>> +            <actions>
>> +                <property-map resource="CommonUiLabels" map-name="uiLabelMap" global="true"/>
>> +                <property-map resource="AccountingUiLabels" map-name="uiLabelMap" global="true"/>
>> +                <set field="organizationPartyId" from-field="parameters.organizationPartyId"/>
>> +            </actions>
>> +            <widgets>
>> +                <include-form name="ExportPartyCsv" location="component://party/widget/partymgr/PartyForms.xml"/>           
>> +            </widgets>
>> +        </section>
>> +    </screen>
>> +    
>> </screens>
>> 
>>