Merged with trunk 890168.


git-svn-id: https://svn.apache.org/repos/asf/ofbiz/branches/addbirt@890174 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/applications/order/config/OrderUiLabels.xml b/applications/order/config/OrderUiLabels.xml
index f713b32..8257822 100644
--- a/applications/order/config/OrderUiLabels.xml
+++ b/applications/order/config/OrderUiLabels.xml
@@ -4913,7 +4913,7 @@
         <value xml:lang="de">Rechnung von Akteur</value>
         <value xml:lang="en">Bill From Party</value>
         <value xml:lang="es">Participante que factura</value>
-        <value xml:lang="fr">Acteur débité</value>
+        <value xml:lang="fr">Acteur crédité</value>
         <value xml:lang="it">Fattura Dal Soggetto</value>
         <value xml:lang="nl">Facturerende relatie</value>
         <value xml:lang="ro">Factura de la Subiect</value>
@@ -4926,7 +4926,7 @@
         <value xml:lang="de">Rechnung an Akteur</value>
         <value xml:lang="en">Bill To Party</value>
         <value xml:lang="es">Participante a quien se factura</value>
-        <value xml:lang="fr">Acteur crédité</value>
+        <value xml:lang="fr">Acteur débité</value>
         <value xml:lang="it">Fattura Al Soggetto</value>
         <value xml:lang="nl">Factuur-relatie</value>
         <value xml:lang="ro">Factura la Subiect</value>
diff --git a/applications/order/ofbiz-component.xml b/applications/order/ofbiz-component.xml
index 0e68f87..e4bfb25 100644
--- a/applications/order/ofbiz-component.xml
+++ b/applications/order/ofbiz-component.xml
@@ -48,6 +48,7 @@
     <service-resource type="eca" loader="main" location="servicedef/secas.xml"/>
 
     <test-suite loader="main" location="testdef/OrderTest.xml"/>
+    <test-suite loader="main" location="testdef/quotetests.xml"/>
 
     <webapp name="order"
         title="Order"
diff --git a/applications/order/script/org/ofbiz/order/quote/QuoteServices.xml b/applications/order/script/org/ofbiz/order/quote/QuoteServices.xml
index c301e94..7b656c7 100644
--- a/applications/order/script/org/ofbiz/order/quote/QuoteServices.xml
+++ b/applications/order/script/org/ofbiz/order/quote/QuoteServices.xml
@@ -872,12 +872,10 @@
             <add-error><fail-message message="ERROR: QuoteWorkEffort [${parameters.quoteId}][${parameters.workEffortId}] already exists."/></add-error>
             <check-errors/>
         </if-not-empty>
-        <if-empty field="quoteWorkEffort.quoteId">
-            <set-nonpk-fields map="parameters" value-field="lookupMap"/>
-            <create-value value-field="lookupMap"/>
-            <field-to-result field="lookupMap.quoteId"/>
-            <field-to-result field="lookupMap.workEffortId"/>
-        </if-empty>
+        <set-nonpk-fields map="parameters" value-field="lookupMap"/>
+        <create-value value-field="lookupMap"/>
+        <field-to-result field="lookupMap.quoteId" result-name="quoteId"/>
+        <field-to-result field="lookupMap.workEffortId" result-name="workEffortId"/>
     </simple-method>
     <simple-method method-name="deleteQuoteWorkEffort" short-description="Delete a QuoteWorkEffort">
         <make-value entity-name="QuoteWorkEffort" value-field="lookupMap"/>
diff --git a/applications/order/script/org/ofbiz/order/test/QuoteTests.xml b/applications/order/script/org/ofbiz/order/test/QuoteTests.xml
new file mode 100644
index 0000000..1192ce1
--- /dev/null
+++ b/applications/order/script/org/ofbiz/order/test/QuoteTests.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/simple-methods.xsd">
+
+    <simple-method method-name="testCreateQuoteWorkEffort" short-description="Test case for successfully creating a QuoteWorkEffort record." login-required="false">
+        <entity-one entity-name="UserLogin" value-field="serviceCtx.userLogin">
+            <field-map field-name="userLoginId" value="DemoRepStore"/>
+        </entity-one>
+        <set field="serviceCtx.quoteId" value="9000"/>
+        <set field="serviceCtx.workEffortId" value="9007"/>
+
+        <!-- Execute the service -->
+        <call-service service-name="createQuoteWorkEffort" in-map-name="serviceCtx">
+            <results-to-map map-name="serviceResult"/>
+        </call-service>
+
+        <!-- Confirm the service output parameters -->
+        <assert>
+            <if-compare-field field="serviceResult.quoteId" operator="equals" to-field="serviceCtx.quoteId"/>
+            <if-compare-field field="serviceResult.workEffortId" operator="equals" to-field="serviceCtx.workEffortId"/>
+        </assert>
+
+        <!-- Confirm the database changes -->
+        <entity-one value-field="quoteWorkEffort" entity-name="QuoteWorkEffort">
+            <field-map field-name="quoteId" from-field="serviceCtx.quoteId"/>
+            <field-map field-name="workEffortId" from-field="serviceCtx.workEffortId"/>
+        </entity-one>
+        <assert><not><if-empty field="quoteWorkEffort"/></not></assert>
+        <check-errors/>
+    </simple-method>
+    
+    <simple-method method-name="testCreateQuoteWorkEffortFail" 
+        short-description="Test case for unsuccessfully creating a QuoteWorkEffort record by attempting to use a quoteId and workEffortId that has already been used in an existing QuoteWorkEffortRecord." login-required="false">
+
+        <!-- Use to confirm nothing has changed at the end of the test -->
+        <set field="startTime" value="${date:nowTimestamp()}" type="Timestamp"/>
+
+        <entity-one entity-name="UserLogin" value-field="serviceCtx.userLogin">
+            <field-map field-name="userLoginId" value="DemoRepStore"/>
+        </entity-one>
+
+        <set field="serviceCtx.quoteId" value="9000"/>
+        <set field="serviceCtx.workEffortId" value="9007"/>
+
+        <!-- Execute the service, note break-on-error is false so that the test itself doesn't 
+             fail and we also need a separate transaction so our lookup below doesn't fail due to the rollback -->
+        <call-service service-name="createQuoteWorkEffort" in-map-name="serviceCtx" 
+            break-on-error="false" require-new-transaction="true">
+            <results-to-map map-name="serviceResult"/>
+        </call-service>
+        <!-- Clear these because break-on-error="false" doesn't seem to work as it should at the moment -->
+        <clear-field field="responseMessage"/>
+        <clear-field field="errorMessageList"/>
+
+        <!-- Confirm the service output parameters, in this case the presence of an error response -->
+        <assert><if-compare field="serviceResult.responseMessage" operator="equals" value="error"/></assert>
+
+        <!-- Confirm the database changes, in this case nothing should have changed -->
+        <entity-condition list="quoteWorkEfforts" entity-name="QuoteWorkEffort">
+            <condition-list>
+                <condition-expr field-name="lastUpdatedStamp" operator="greater-equals" from-field="startTime"/>
+                <condition-expr field-name="quoteId" from-field="serviceCtx.quoteId"/>
+                <condition-expr field-name="workEffortId" from-field="serviceCtx.workEffortId"/>
+            </condition-list>
+        </entity-condition>
+        <!--  Should be empty -->
+        <assert><if-empty field="quoteWorkEffort"/></assert>
+        <check-errors/>
+    </simple-method>
+
+    <simple-method method-name="testCreateWorkEffortAndQuoteWorkEffort" login-required="false"
+        short-description="Test case for calling createQuoteWorkEffort without a workEffortId which triggers an ECA to create the WorkEffort first">
+        <entity-one entity-name="UserLogin" value-field="serviceCtx.userLogin">
+            <field-map field-name="userLoginId" value="flexadmin"/>
+        </entity-one>
+        <!-- Use the bare minimum inputs necessary to create the work effort as we aren't testing that service, only that it plays well as an ECA -->
+        <set field="serviceCtx.currentStatusId" value="ROU_ACTIVE"/>
+        <set field="serviceCtx.workEffortName" value="Test WorkEffort"/>
+        <set field="serviceCtx.workEffortTypeId" value="ROUTING"/>
+        <set field="serviceCtx.quoteId" value="9000"/>
+
+        <call-service service-name="createQuoteWorkEffort" in-map-name="serviceCtx">
+            <results-to-map map-name="serviceResult"/>
+        </call-service>
+
+        <assert>
+            <and>
+                <if-compare-field field="serviceResult.quoteId" operator="equals" to-field="serviceCtx.quoteId"/>
+                <not><if-empty field="serviceResult.workEffortId"/></not>
+            </and>
+        </assert>
+        
+        <!-- Confirm that a matching WorkEffort was created -->
+        <entity-and list="workEfforts" entity-name="WorkEffort">
+            <field-map field-name="workEffortId" from-field="serviceResult.workEffortId"/>
+            <field-map field-name="currentStatusId" from-field="serviceCtx.currentStatusId"/>
+            <field-map field-name="workEffortName" from-field="serviceCtx.workEffortName"/>
+            <field-map field-name="workEffortTypeId" from-field="serviceCtx.workEffortTypeId"/>
+        </entity-and>
+        <assert>
+            <not><if-empty field="workEfforts"/></not>
+        </assert>
+
+        <entity-one value-field="quoteWorkEffort" entity-name="QuoteWorkEffort">
+            <field-map field-name="quoteId" from-field="serviceCtx.quoteId"/>
+            <field-map field-name="workEffortId" from-field="serviceResult.workEffortId"/>
+        </entity-one>
+        <check-errors/>
+    </simple-method>
+</simple-methods>
diff --git a/applications/order/servicedef/secas.xml b/applications/order/servicedef/secas.xml
index ad4eb92..3ebcab9 100644
--- a/applications/order/servicedef/secas.xml
+++ b/applications/order/servicedef/secas.xml
@@ -337,7 +337,7 @@
     </eca>
 
     <!-- WorkEffort -->
-    <eca service="createQuoteWorkEffort" event="invoke">
+    <eca service="createQuoteWorkEffort" event="in-validate">
         <condition field-name="workEffortId" operator="is-empty"/>
         <action service="createWorkEffort" mode="sync"/>
     </eca>
diff --git a/applications/order/servicedef/services_quote.xml b/applications/order/servicedef/services_quote.xml
index 865fe74..0ca49a0 100644
--- a/applications/order/servicedef/services_quote.xml
+++ b/applications/order/servicedef/services_quote.xml
@@ -187,6 +187,7 @@
         <auto-attributes mode="IN" include="nonpk" optional="true" entity-name="WorkEffort"/>
         <auto-attributes mode="INOUT" include="pk" optional="true" entity-name="WorkEffort"/>
         <override name="quoteId" optional="false"/>
+        <override name="workEffortId" optional="false"/>
     </service>
     <service name="deleteQuoteWorkEffort" default-entity-name="QuoteWorkEffort" engine="simple" auth="true"
             location="component://order/script/org/ofbiz/order/quote/QuoteServices.xml" invoke="deleteQuoteWorkEffort">
diff --git a/applications/order/testdef/data/QuoteTestData.xml b/applications/order/testdef/data/QuoteTestData.xml
new file mode 100644
index 0000000..866f30f
--- /dev/null
+++ b/applications/order/testdef/data/QuoteTestData.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<entity-engine-xml>
+    <Quote quoteId="9000" quoteTypeId="PRODUCT_QUOTE" partyId="DemoCustomer" issueDate="2009-12-11 12:00:00.000" statusId="QUO_CREATED" currencyUomId="USD" productStoreId="9000" salesChannelEnumId="EMAIL_SALES_CHANNEL" validFromDate="2009-12-11 12:00:00.000" quoteName="Most competitive quote ever"/>
+    <WorkEffort workEffortId="9007" workEffortTypeId="TASK" currentStatusId="PTS_CREATED" workEffortName="Quote WorkEffort"/>
+</entity-engine-xml>
\ No newline at end of file
diff --git a/applications/order/testdef/quotetests.xml b/applications/order/testdef/quotetests.xml
new file mode 100644
index 0000000..7fefab5
--- /dev/null
+++ b/applications/order/testdef/quotetests.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<test-suite suite-name="quotetests"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/test-suite.xsd">
+        
+    <test-case case-name="loadQuoteTestData">
+        <entity-xml action="load" entity-xml-url="component://order/testdef/data/QuoteTestData.xml"/>
+    </test-case>
+
+    <test-case case-name="testCreateQuoteWorkEffort">
+        <simple-method-test location="component://order/script/org/ofbiz/order/test/QuoteTests.xml" name="testCreateQuoteWorkEffort"/>
+    </test-case>
+
+    <test-case case-name="testCreateQuoteWorkEffortFail">
+        <simple-method-test location="component://order/script/org/ofbiz/order/test/QuoteTests.xml" name="testCreateQuoteWorkEffortFail"/>
+    </test-case>
+
+    <test-case case-name="testCreateWorkEffortAndQuoteWorkEffort">
+        <simple-method-test location="component://order/script/org/ofbiz/order/test/QuoteTests.xml" name="testCreateWorkEffortAndQuoteWorkEffort"/>
+    </test-case>
+</test-suite>
\ No newline at end of file
diff --git a/applications/order/webapp/ordermgr/order/orderReportBody.fo.ftl b/applications/order/webapp/ordermgr/order/orderReportBody.fo.ftl
index e9f6a38..b8d2829 100644
--- a/applications/order/webapp/ordermgr/order/orderReportBody.fo.ftl
+++ b/applications/order/webapp/ordermgr/order/orderReportBody.fo.ftl
@@ -20,7 +20,7 @@
     <#if orderHeader?has_content>
         <fo:table border-spacing="3pt">
 
-       <fo:table-column column-width="3.5in"/>
+       <fo:table-column column-width="4in"/>
        <fo:table-column column-width="1in"/>
        <fo:table-column column-width="1in"/>
        <fo:table-column column-width="1in"/>
@@ -28,9 +28,9 @@
        <fo:table-header>
            <fo:table-row>
                <fo:table-cell><fo:block font-weight="bold">${uiLabelMap.OrderProduct}</fo:block></fo:table-cell>
-               <fo:table-cell text-align="center"><fo:block font-weight="bold">${uiLabelMap.OrderQuantity}</fo:block></fo:table-cell>
-               <fo:table-cell text-align="center"><fo:block font-weight="bold">${uiLabelMap.OrderUnitList}</fo:block></fo:table-cell>
-               <fo:table-cell text-align="center"><fo:block font-weight="bold">${uiLabelMap.OrderSubTotal}</fo:block></fo:table-cell>
+               <fo:table-cell text-align="right"><fo:block font-weight="bold">${uiLabelMap.OrderQuantity}</fo:block></fo:table-cell>
+               <fo:table-cell text-align="right"><fo:block font-weight="bold">${uiLabelMap.OrderUnitList}</fo:block></fo:table-cell>
+               <fo:table-cell text-align="right"><fo:block font-weight="bold">${uiLabelMap.OrderSubTotal}</fo:block></fo:table-cell>
            </fo:table-row>
        </fo:table-header>
 
@@ -63,7 +63,7 @@
                        </fo:table-row>
                        <#if itemAdjustment != 0>
                        <fo:table-row>
-                        <fo:table-cell number-columns-spanned="2"><fo:block><fo:inline font-style="italic">${uiLabelMap.OrderAdjustments}</fo:inline>: <@ofbizCurrency amount=itemAdjustment isoCode=currencyUomId/></fo:block></fo:table-cell>
+                        <fo:table-cell number-columns-spanned="2"><fo:block text-indent="0.2in"><fo:inline font-style="italic">${uiLabelMap.OrderAdjustments}</fo:inline>: <@ofbizCurrency amount=itemAdjustment isoCode=currencyUomId/></fo:block></fo:table-cell>
                     </fo:table-row>
                     </#if>
            </#list>
diff --git a/applications/order/webapp/ordermgr/order/orderReportConditions.fo.ftl b/applications/order/webapp/ordermgr/order/orderReportConditions.fo.ftl
index 2126b1e..d3a196d 100644
--- a/applications/order/webapp/ordermgr/order/orderReportConditions.fo.ftl
+++ b/applications/order/webapp/ordermgr/order/orderReportConditions.fo.ftl
@@ -17,6 +17,38 @@
 under the License.
 -->
 <#escape x as x?xml>
+
+<#if shipGroups?exists && shipGroups.size() gt 1>
+    <fo:table border-spacing="3pt" space-before="0.3in" font-size="9pt">
+        <fo:table-column column-width="1in"/>
+        <fo:table-column column-width="1in"/>
+        <fo:table-column column-width="0.5in"/>
+        <fo:table-header>
+            <fo:table-row font-weight="bold">
+                <fo:table-cell><fo:block>${uiLabelMap.OrderShipGroup}</fo:block></fo:table-cell>
+                <fo:table-cell><fo:block>${uiLabelMap.OrderProduct}</fo:block></fo:table-cell>
+                <fo:table-cell text-align="right"><fo:block>${uiLabelMap.OrderQuantity}</fo:block></fo:table-cell>
+            </fo:table-row>
+        </fo:table-header>
+        <fo:table-body>
+            <#list shipGroups as shipGroup>
+                <#assign orderItemShipGroupAssocs = shipGroup.getRelated("OrderItemShipGroupAssoc")?if_exists>
+                <#if orderItemShipGroupAssocs?has_content>
+                    <#list orderItemShipGroupAssocs as shipGroupAssoc>
+                        <#assign orderItem = shipGroupAssoc.getRelatedOne("OrderItem")?if_exists>
+                        <fo:table-row>
+                            <fo:table-cell><fo:block>${shipGroup.shipGroupSeqId}</fo:block></fo:table-cell>
+                            <fo:table-cell><fo:block>${orderItem.productId?if_exists}</fo:block></fo:table-cell>
+                            <fo:table-cell text-align="right"><fo:block>${shipGroupAssoc.quantity?string.number}</fo:block></fo:table-cell>
+                        </fo:table-row>
+                    </#list>
+                </#if>
+            </#list>
+        </fo:table-body>
+    </fo:table>
+</#if>
+
+
 <fo:block space-after="40pt"/>
 <#if orderHeader.getString("orderTypeId") == "SALES_ORDER">
   <fo:block font-size="14pt" font-weight="bold" text-align="center">THANK YOU FOR YOUR PATRONAGE!</fo:block>
diff --git a/applications/order/webapp/ordermgr/order/orderReportContactMechs.fo.ftl b/applications/order/webapp/ordermgr/order/orderReportContactMechs.fo.ftl
index 79307e7..46f1631 100644
--- a/applications/order/webapp/ordermgr/order/orderReportContactMechs.fo.ftl
+++ b/applications/order/webapp/ordermgr/order/orderReportContactMechs.fo.ftl
@@ -17,137 +17,102 @@
 under the License.
 -->
 <#escape x as x?xml>
-       <fo:table border-spacing="3pt">
-          <fo:table-column column-width="3.75in"/>
-          <fo:table-column column-width="3.75in"/>
-          <fo:table-body>
-            <fo:table-row>    <#-- this part could use some improvement -->
 
-             <#assign createEmptyCell = true>
-             <#-- a special purchased from address for Purchase Orders -->
-             <#if orderHeader.getString("orderTypeId") == "PURCHASE_ORDER">
-             <#if supplierGeneralContactMechValueMap?exists>
-               <#assign contactMech = supplierGeneralContactMechValueMap.contactMech>
-               <#assign createEmptyCell = false>
-               <fo:table-cell>
-                 <fo:block>
-                     ${uiLabelMap.OrderPurchasedFrom}:
-                 </fo:block>
-                 <#assign postalAddress = supplierGeneralContactMechValueMap.postalAddress>
-                 <#if postalAddress?has_content>
-                   <#if postalAddress.toName?has_content><fo:block>${postalAddress.toName}</fo:block></#if>
-                   <#if postalAddress.attnName?has_content><fo:block>${postalAddress.attnName?if_exists}</fo:block></#if>
-                   <fo:block>${postalAddress.address1?if_exists}</fo:block>
-                   <#if postalAddress.address2?has_content><fo:block>${postalAddress.address2?if_exists}</fo:block></#if>
-                   <fo:block>
-                     <#assign stateGeo = (delegator.findOne("Geo", {"geoId", postalAddress.stateProvinceGeoId?if_exists}, false))?if_exists />
-                     ${postalAddress.city}<#if stateGeo?has_content>, ${stateGeo.geoName?if_exists}</#if> ${postalAddress.postalCode?if_exists}
-                   </fo:block>
-                   <fo:block>
-                     <#assign countryGeo = (delegator.findOne("Geo", {"geoId", postalAddress.countryGeoId?if_exists}, false))?if_exists />
-                     <#if countryGeo?has_content>${countryGeo.geoName?if_exists}</#if>
-                   </fo:block>
-                 </#if>
-               </fo:table-cell>
-             <#else>
-               <#-- here we just display the name of the vendor, since there is no address -->
-               <#assign createEmptyCell = false>
-               <fo:table-cell>
-                 <#assign vendorParty = orderReadHelper.getBillFromParty()>
-                 <fo:block>
-                   <fo:inline font-weight="bold">${uiLabelMap.OrderPurchasedFrom}:</fo:inline> ${Static['org.ofbiz.party.party.PartyHelper'].getPartyName(vendorParty)}
-                 </fo:block>
-               </fo:table-cell>
-             </#if>
-             </#if>
+<#if orderHeader.getString("orderTypeId") == "PURCHASE_ORDER">
+    <#if supplierGeneralContactMechValueMap?exists>
+        <#assign contactMech = supplierGeneralContactMechValueMap.contactMech>
+        <fo:block font-weight="bold">${uiLabelMap.OrderPurchasedFrom}:</fo:block>
+        <#assign postalAddress = supplierGeneralContactMechValueMap.postalAddress>
+        <#if postalAddress?has_content>
+            <fo:block text-indent="0.2in">
+                <#if postalAddress.toName?has_content><fo:block>${postalAddress.toName}</fo:block></#if>
+                <#if postalAddress.attnName?has_content><fo:block>${postalAddress.attnName?if_exists}</fo:block></#if>
+                <fo:block>${postalAddress.address1?if_exists}</fo:block>
+                <#if postalAddress.address2?has_content><fo:block>${postalAddress.address2?if_exists}</fo:block></#if>
+                <fo:block>
+                    <#assign stateGeo = (delegator.findOne("Geo", {"geoId", postalAddress.stateProvinceGeoId?if_exists}, false))?if_exists />
+                    ${postalAddress.city}<#if stateGeo?has_content>, ${stateGeo.geoName?if_exists}</#if> ${postalAddress.postalCode?if_exists}
+                </fo:block>
+                <fo:block>
+                    <#assign countryGeo = (delegator.findOne("Geo", {"geoId", postalAddress.countryGeoId?if_exists}, false))?if_exists />
+                    <#if countryGeo?has_content>${countryGeo.geoName?if_exists}</#if>
+                </fo:block>
+            </fo:block>                
+        </#if>
+    <#else>
+        <#-- here we just display the name of the vendor, since there is no address -->
+        <#assign vendorParty = orderReadHelper.getBillFromParty()>
+        <fo:block>
+            <fo:inline font-weight="bold">${uiLabelMap.OrderPurchasedFrom}:</fo:inline> ${Static['org.ofbiz.party.party.PartyHelper'].getPartyName(vendorParty)}
+        </fo:block>
+    </#if>
+</#if>
 
-             <#-- list all postal addresses of the order.  there should be just a billing and a shipping here. -->
-             <#list orderContactMechValueMaps as orderContactMechValueMap>
-               <#assign contactMech = orderContactMechValueMap.contactMech>
-               <#assign contactMechPurpose = orderContactMechValueMap.contactMechPurposeType>
-               <#if contactMech.contactMechTypeId == "POSTAL_ADDRESS">
-               <#assign postalAddress = orderContactMechValueMap.postalAddress>
-               <#assign createEmptyCell = false>
-               <fo:table-cell>
-                 <fo:block font-weight="bold">${contactMechPurpose.get("description",locale)}:</fo:block>
-                 <#if postalAddress?has_content>
-                   <#if postalAddress.toName?has_content><fo:block>${postalAddress.toName?if_exists}</fo:block></#if>
-                   <#if postalAddress.attnName?has_content><fo:block>${postalAddress.attnName?if_exists}</fo:block></#if>
-                   <fo:block>${postalAddress.address1?if_exists}</fo:block>
-                   <#if postalAddress.address2?has_content><fo:block>${postalAddress.address2?if_exists}</fo:block></#if>
-                   <fo:block>
-                     <#assign stateGeo = (delegator.findOne("Geo", {"geoId", postalAddress.stateProvinceGeoId?if_exists}, false))?if_exists />
-                     ${postalAddress.city}<#if stateGeo?has_content>, ${stateGeo.geoName?if_exists}</#if> ${postalAddress.postalCode?if_exists}
-                   </fo:block>
-                   <fo:block>
-                     <#assign countryGeo = (delegator.findOne("Geo", {"geoId", postalAddress.countryGeoId?if_exists}, false))?if_exists />
-                     <#if countryGeo?has_content>${countryGeo.geoName?if_exists}</#if>
-                   </fo:block>
-                 </#if>
-               </fo:table-cell>
-               </#if>
-             </#list>
-             <#-- The empty cell is required in order to fill the table-row element and avoid a validation error -->
-             <#if createEmptyCell>
-             <fo:table-cell></fo:table-cell>
-             </#if>
-            </fo:table-row>
-         </fo:table-body>
-       </fo:table>
-       <fo:block white-space-collapse="false"> </fo:block>
+<#-- list all postal addresses of the order.  there should be just a billing and a shipping here. -->
+<#list orderContactMechValueMaps as orderContactMechValueMap>
+    <#assign contactMech = orderContactMechValueMap.contactMech>
+    <#assign contactMechPurpose = orderContactMechValueMap.contactMechPurposeType>
+    <#if contactMech.contactMechTypeId == "POSTAL_ADDRESS">
+        <#assign postalAddress = orderContactMechValueMap.postalAddress>
+        <fo:block font-weight="bold">${contactMechPurpose.get("description",locale)}:</fo:block>
+        <fo:block text-indent="0.2in">
+            <#if postalAddress?has_content>
+                <#if postalAddress.toName?has_content><fo:block>${postalAddress.toName?if_exists}</fo:block></#if>
+                <#if postalAddress.attnName?has_content><fo:block>${postalAddress.attnName?if_exists}</fo:block></#if>
+                <fo:block>${postalAddress.address1?if_exists}</fo:block>
+                <#if postalAddress.address2?has_content><fo:block>${postalAddress.address2?if_exists}</fo:block></#if>
+                <fo:block>
+                    <#assign stateGeo = (delegator.findOne("Geo", {"geoId", postalAddress.stateProvinceGeoId?if_exists}, false))?if_exists />
+                    ${postalAddress.city}<#if stateGeo?has_content>, ${stateGeo.geoName?if_exists}</#if> ${postalAddress.postalCode?if_exists}
+                </fo:block>
+                <fo:block>
+                    <#assign countryGeo = (delegator.findOne("Geo", {"geoId", postalAddress.countryGeoId?if_exists}, false))?if_exists />
+                    <#if countryGeo?has_content>${countryGeo.geoName?if_exists}</#if>
+                </fo:block>
+            </#if>
+        </fo:block>
+    </#if>
+</#list>
 
-       <fo:table border-spacing="3pt">
-          <fo:table-column column-width="1.75in"/>
-          <fo:table-column column-width="4.25in"/>
+<fo:block space-after="0.2in"/>
 
-  <#-- payment info -->
-          <fo:table-body>
-           <#if orderPaymentPreferences?has_content>
-            <fo:table-row>
-                <fo:table-cell><fo:block font-weight="bold">${uiLabelMap.AccountingPaymentInformation}:</fo:block></fo:table-cell>
-                <fo:table-cell><fo:block>
-                      <#list orderPaymentPreferences as orderPaymentPreference>
-                         <#assign paymentMethodType = orderPaymentPreference.getRelatedOne("PaymentMethodType")?if_exists>
-                         <#if ((orderPaymentPreference != null) && (orderPaymentPreference.getString("paymentMethodTypeId") == "CREDIT_CARD") && (orderPaymentPreference.getString("paymentMethodId")?has_content))>
-                           <#assign creditCard = orderPaymentPreference.getRelatedOne("PaymentMethod").getRelatedOne("CreditCard")>
-                             ${Static["org.ofbiz.party.contact.ContactHelper"].formatCreditCard(creditCard)}
-                         <#else>
-                             ${paymentMethodType.get("description",locale)?if_exists}
-                         </#if>
-                      </#list>
-                      </fo:block>
-                 </fo:table-cell>
-            </fo:table-row>
-         </#if>
+<#if orderPaymentPreferences?has_content>
+    <fo:block font-weight="bold">${uiLabelMap.AccountingPaymentInformation}:</fo:block>
+    <#list orderPaymentPreferences as orderPaymentPreference>
+        <fo:block text-indent="0.2in">
+            <#assign paymentMethodType = orderPaymentPreference.getRelatedOne("PaymentMethodType")?if_exists>
+            <#if ((orderPaymentPreference != null) && (orderPaymentPreference.getString("paymentMethodTypeId") == "CREDIT_CARD") && (orderPaymentPreference.getString("paymentMethodId")?has_content))>
+                <#assign creditCard = orderPaymentPreference.getRelatedOne("PaymentMethod").getRelatedOne("CreditCard")>
+                ${Static["org.ofbiz.party.contact.ContactHelper"].formatCreditCard(creditCard)}
+            <#else>
+                ${paymentMethodType.get("description",locale)?if_exists}
+            </#if>
+        </fo:block>
+    </#list>
+</#if>
+<#if orderHeader.getString("orderTypeId") == "SALES_ORDER" && shipGroups?exists?has_content>
+    <fo:block font-weight="bold">${uiLabelMap.OrderShipmentInformation}:</fo:block>
+    <#list shipGroups as shipGroup>
+        <fo:block text-indent="0.2in">
+            <#if shipGroups.size() gt 1>${shipGroup.shipGroupSeqId} - </#if>
+            <#if (shipGroup.shipmentMethodTypeId)?exists>
+                ${(shipGroup.getRelatedOne("ShipmentMethodType").get("description", locale))?default(shipGroup.shipmentMethodTypeId)}
+            </#if>
+            <#if (shipGroup.shipAfterDate)?exists || (shipGroup.shipByDate)?exists>
+                <#if (shipGroup.shipAfterDate)?exists> - ${uiLabelMap.OrderShipAfterDate}: ${Static["org.ofbiz.base.util.UtilDateTime"].toDateString(shipGroup.shipAfterDate)}</#if><#if (shipGroup.shipByDate)?exists> - ${uiLabelMap.OrderShipBeforeDate}: ${Static["org.ofbiz.base.util.UtilDateTime"].toDateString(shipGroup.shipByDate)}</#if>
+            </#if>
+        </fo:block>
+    </#list>
+</#if>
 
-        <#-- shipping method.  currently not shown for PO's because we are not recording a shipping method for PO's in order entry -->
-           <#if orderHeader.getString("orderTypeId") == "SALES_ORDER">
-            <fo:table-row>
-               <fo:table-cell><fo:block font-weight="bold">${uiLabelMap.OrderShipmentInformation}:</fo:block></fo:table-cell>
-                  <fo:table-cell>
-                 <#if shipGroups?has_content>
-                   <#list shipGroups as shipGroup>
-                   <#-- TODO: List all full details of each ship group here -->
-                        <fo:block>
-                      <#if (shipGroup.shipmentMethodTypeId)?exists>
-                        ${(shipGroup.getRelatedOne("ShipmentMethodType").get("description", locale))?default(shipGroup.shipmentMethodTypeId)}
-                      </#if>
-                     </fo:block>
-                   </#list>
-                  </#if>
-               </fo:table-cell>
-             </fo:table-row>
-           </#if>
-       <#-- order terms information -->
-             <#if orderTerms?exists?has_content>
-             <fo:table-row>
-               <fo:table-cell><fo:block font-weight="bold">${uiLabelMap.OrderOrderTerms}: </fo:block></fo:table-cell>
-               <fo:table-cell white-space-collapse="false"><#list orderTerms as orderTerm><fo:block>${orderTerm.getRelatedOne("TermType").get("description",locale)} ${orderTerm.termValue?default("")} ${orderTerm.termDays?default("")} ${orderTerm.textValue?default("")}
-</fo:block></#list></fo:table-cell>
-             </fo:table-row>
-             </#if>
-          </fo:table-body>
-       </fo:table>
+<#if orderTerms?exists?has_content && orderTerms.size() gt 0>
+    <fo:block font-weight="bold">${uiLabelMap.OrderOrderTerms}:</fo:block>
+    <#list orderTerms as orderTerm>
+        <fo:block text-indent="0.2in">
+            ${orderTerm.getRelatedOne("TermType").get("description",locale)} ${orderTerm.termValue?default("")} ${orderTerm.termDays?default("")} ${orderTerm.textValue?default("")}
+        </fo:block>
+    </#list>
+</#if>
 
-<fo:block space-after="10pt"/>
+<fo:block space-after="0.2in"/>
 </#escape>
diff --git a/applications/order/webapp/ordermgr/return/returnLinks.ftl b/applications/order/webapp/ordermgr/return/returnLinks.ftl
index e8943a2..be361d6 100644
--- a/applications/order/webapp/ordermgr/return/returnLinks.ftl
+++ b/applications/order/webapp/ordermgr/return/returnLinks.ftl
@@ -42,7 +42,7 @@
             <#assign orderId = (Static["org.ofbiz.entity.util.EntityUtil"].getFirst(returnItems)).getString("orderId")/>
             <#assign shipGroupAssoc = Static["org.ofbiz.entity.util.EntityUtil"].getFirst(delegator.findByAnd("OrderItemShipGroupAssoc", {"orderId" : orderId}))/>
             <#assign shipGroup = delegator.findOne("OrderItemShipGroup", {"orderId" : orderId, "shipGroupSeqId" : shipGroupAssoc.shipGroupSeqId}, false)>
-            <#if shipGroup?exists>
+            <#if shipGroup?exists && shipGroup.shipmentMethodTypeId != "NO_SHIPPING">
               <#assign shipGroupShipment = Static["org.ofbiz.entity.util.EntityUtil"].getFirst(delegator.findByAnd("Shipment", {"primaryOrderId" : shipGroup.orderId, "primaryShipGroupSeqId" : shipGroup.shipGroupSeqId}))/>
               <#if shipGroupShipment?exists>
                 <#assign shipmentRouteSegment = Static["org.ofbiz.entity.util.EntityUtil"].getFirst(delegator.findByAnd("ShipmentRouteSegment", {"shipmentId" : shipGroupShipment.shipmentId}))>
diff --git a/applications/product/config/ProductUiLabels.xml b/applications/product/config/ProductUiLabels.xml
index b120c25..f236a7a 100644
--- a/applications/product/config/ProductUiLabels.xml
+++ b/applications/product/config/ProductUiLabels.xml
@@ -42,7 +42,7 @@
         <value xml:lang="es">OFBiz: Administrador de Almacén</value>
         <value xml:lang="fr">OFBiz: Gestion de stock</value>
         <value xml:lang="it">OFBiz: Gestione stabilimenti</value>
-        <value xml:lang="nl">OFBiz: Faciliteit Manager</value>		
+        <value xml:lang="nl">OFBiz: Faciliteit Manager</value>    
         <value xml:lang="ro">OFBiz: Gestiune Compartimente</value>
         <value xml:lang="ru">OFBiz: Управление объектами</value>
         <value xml:lang="th">OFBiz: การจัดการคลังสินค้า</value>
@@ -52,7 +52,7 @@
         <value xml:lang="en">Part of the Open For Business Family of Open Source Software</value>
         <value xml:lang="fr">Un module de la famille Open For Business, logiciel libre de gestion d'entreprise.</value>
         <value xml:lang="it">Part of the Open For Business Family of Open Source Software</value>
-        <value xml:lang="nl">Deel van de 'Open For Business' familie van open source software</value>		
+        <value xml:lang="nl">Deel van de 'Open For Business' familie van open source software</value>    
         <value xml:lang="zh">开源软件OFBiz的组成部分</value>
     </property>
     <property key="FacilityEstimatedShippingCharges">
@@ -4643,7 +4643,7 @@
         <value xml:lang="es">Elegir Categoría Principal</value>
         <value xml:lang="fr">Choix de la catégorie principale</value>
         <value xml:lang="it">Scegli Categoria Principale</value>
-        <value xml:lang="nl">Lijst van hoofdcategoriën</value>		
+        <value xml:lang="nl">Lijst van hoofdcategoriën</value>    
         <value xml:lang="ro">Alege Categoria Principala</value>
         <value xml:lang="ru">Выбр. корнев. категорию</value>
         <value xml:lang="th">เลือกหมวดหมู่ที่ได้รับความนิยม</value>
@@ -4751,7 +4751,7 @@
         <value xml:lang="es">Editar Categoría</value>
         <value xml:lang="fr">Modification de la catégorie</value>
         <value xml:lang="it">Mostra Categoria</value>
-        <value xml:lang="nl">Wijzig categorie</value>		
+        <value xml:lang="nl">Wijzig categorie</value>    
         <value xml:lang="ro">Afiseaza Categoria</value>
         <value xml:lang="ru">Редактировать категорию</value>
         <value xml:lang="th">แก้ไขหมวดหมู่</value>
@@ -4826,7 +4826,7 @@
         <value xml:lang="es">Editar Productos de una Categoría</value>
         <value xml:lang="fr">Modification des catégories</value>
         <value xml:lang="it">Aggiorna Categoria Prodotti</value>
-        <value xml:lang="nl">Wijzig categorieproducten</value>		
+        <value xml:lang="nl">Wijzig categorieproducten</value>    
         <value xml:lang="ro">Actualizeaza Categoria Produs</value>
         <value xml:lang="ru">Изменить категорию продуктов</value>
         <value xml:lang="th">แก้ไขหมวดหมู่สินค้า</value>
@@ -4838,7 +4838,7 @@
         <value xml:lang="es">Editar jerarquía de una Categoría</value>
         <value xml:lang="fr">Modification de la hiérarchie des catégorie</value>
         <value xml:lang="it">Aggiorna Categoria Arrivo</value>
-        <value xml:lang="nl">Wijzig categorie hiërarchie</value>		
+        <value xml:lang="nl">Wijzig categorie hiërarchie</value>    
         <value xml:lang="ro">Actualizeaza Categoria Sosire</value>
         <value xml:lang="ru">Изменить подчиненность категории</value>
         <value xml:lang="th">Edit Category Rollup</value>
@@ -5071,7 +5071,7 @@
         <value xml:lang="es">Editar Producto</value>
         <value xml:lang="fr">Modification de l'article</value>
         <value xml:lang="it">Aggiorna Prodotto</value>
-        <value xml:lang="nl">Wijzig product</value>		
+        <value xml:lang="nl">Wijzig product</value>    
         <value xml:lang="ro">Actualizeaza Produs</value>
         <value xml:lang="ru">Редактировать продукт</value>
         <value xml:lang="th">แก้ไขสินค้า</value>
@@ -5391,7 +5391,7 @@
         <value xml:lang="es">Editar Reglas de Precio de un Producto</value>
         <value xml:lang="fr">Modification des règles de prix des articles</value>
         <value xml:lang="it">Aggiorna Regole Prezzo Prodotto</value>
-        <value xml:lang="nl">Wijzig productprijsregels</value>		
+        <value xml:lang="nl">Wijzig productprijsregels</value>    
         <value xml:lang="ro">Actualizeaza Reguli Pret Produs</value>
         <value xml:lang="ru">Изменить правила назначения цены продукта</value>
         <value xml:lang="th">แก้ไขข้อกำหนดราคาสินค้า</value>
@@ -5901,7 +5901,7 @@
         <value xml:lang="es">Buscar Regla de Precios de Productos</value>
         <value xml:lang="fr">Recherche de règles de prix</value>
         <value xml:lang="it">Ricerca Regole Prezzo Prodotto</value>
-        <value xml:lang="nl">Zoek productprijsregels</value>		
+        <value xml:lang="nl">Zoek productprijsregels</value>    
         <value xml:lang="ro">Cauta Reguli Pret Produs</value>
         <value xml:lang="ru">Найти правила назначения цены продукта</value>
         <value xml:lang="th">ค้นหาสถานะราคาสินค้า</value>
@@ -6153,7 +6153,7 @@
         <value xml:lang="es">Buscar Producto y precio</value>
         <value xml:lang="fr">Consulter les prix d'un article</value>
         <value xml:lang="it">Ricerca Prodotti e Prezzi</value>
-        <value xml:lang="nl">Zoeken productprijs</value>		
+        <value xml:lang="nl">Zoeken productprijs</value>    
         <value xml:lang="ro">Cauta Produse si Preturi</value>
         <value xml:lang="ru">Искать продукт и цену</value>
         <value xml:lang="th">ค้นหาสินค้าและราคา</value>
@@ -6165,7 +6165,7 @@
         <value xml:lang="es">Buscar tienda de producto</value>
         <value xml:lang="fr">Consulter le centre de profit</value>
         <value xml:lang="it">Ricerca Negozi</value>
-        <value xml:lang="nl">Zoeken winkel</value>		
+        <value xml:lang="nl">Zoeken winkel</value>    
         <value xml:lang="ro">Cauta Magazine</value>
         <value xml:lang="ru">Искать склад продуктов</value>
         <value xml:lang="th">ค้นหาคลังสินค้า</value>
@@ -6951,7 +6951,7 @@
         <value xml:lang="es">Añadir Regla de Precios</value>
         <value xml:lang="fr">Ajouter des règles de prix</value>
         <value xml:lang="it">Aggiungi Regole Prezzo</value>
-        <value xml:lang="nl">Toevoegen prijsregel</value>		
+        <value xml:lang="nl">Toevoegen prijsregel</value>    
         <value xml:lang="ro">Adauga Reguli Pret</value>
         <value xml:lang="ru">Добавить правило</value>
         <value xml:lang="th">เพิ่มข้อบังคับราคา</value>
@@ -7121,7 +7121,7 @@
         <value xml:lang="de">Resultate hinzufügen zu</value>
         <value xml:lang="en">Add Results To</value>
         <value xml:lang="es">Añadir resultados a</value>
-        <value xml:lang="fr">Ajout de résultats à</value>
+        <value xml:lang="fr">Ajout de résultats à la</value>
         <value xml:lang="it">Aggiungi Risultati A</value>
         <value xml:lang="ro">Adauga Rezultate La</value>
         <value xml:lang="ru">Добавить результаты к</value>
@@ -7397,7 +7397,7 @@
         <value xml:lang="es">Palabra clave alterna para la Enciclopedia</value>
         <value xml:lang="fr">Thésaurus de mots clés de remplacement</value>
         <value xml:lang="it">Alternare Chiave Dizionario</value>
-        <value xml:lang="nl">Alternieve trefwoordsynoniemen</value>		
+        <value xml:lang="nl">Alternieve trefwoordsynoniemen</value>    
         <value xml:lang="ro">Alternare Cheie Dictionar</value>
         <value xml:lang="ru">Словарь альтернативных ключевых слов</value>
         <value xml:lang="th">Alternate KeyWord Thesaurus</value>
@@ -7812,7 +7812,7 @@
         <value xml:lang="es">Creación Automática de Palabras Clave para todos los Productos</value>
         <value xml:lang="fr">Création automatique de mots-clés pour tout article</value>
         <value xml:lang="it">Creazione Automatica Chiavi per Tutti i Prodotti</value>
-        <value xml:lang="nl">Automatisch aanmaken trefwoorden voor alle producten</value>		
+        <value xml:lang="nl">Automatisch aanmaken trefwoorden voor alle producten</value>    
         <value xml:lang="ro">Creatie Automatica Chei pentru Toate Produsele </value>
         <value xml:lang="ru">Автоматически создать ключевые слова для всех продуктов</value>
         <value xml:lang="th">สร้างคีย์เวิร์ดอัตโนมัติสำหรับสินค้าทั้งหมด</value>
@@ -7893,7 +7893,7 @@
         <value xml:lang="es">Regresar a Editar Categoría</value>
         <value xml:lang="fr">Revenir à l'édition des catégories</value>
         <value xml:lang="it">Torna all'Aggiornamento della Categoria</value>
-        <value xml:lang="nl">Terug naar wijzigen categorie</value>		
+        <value xml:lang="nl">Terug naar wijzigen categorie</value>    
         <value xml:lang="ro">Intoarcete la Actualizarea Categoriei</value>
         <value xml:lang="ru">Обратно к редактированию категории</value>
         <value xml:lang="th">กลับไปยังการแก้ไขหมวดหมู่</value>
@@ -8033,7 +8033,7 @@
         <value xml:lang="es">Examinar Catálogos</value>
         <value xml:lang="fr">Consulter les catalogues</value>
         <value xml:lang="it">Mostra Cataloghi</value>
-		<value xml:lang="nl">Blader door catalogi</value>
+    <value xml:lang="nl">Blader door catalogi</value>
         <value xml:lang="ro">Afiseaza Catalog</value>
         <value xml:lang="ru">Каталоги</value>
         <value xml:lang="th">แสดงหมวดหมู่</value>
@@ -8219,7 +8219,7 @@
         <value xml:lang="es">Página Principal de Administración de Catálogos</value>
         <value xml:lang="fr">Gestion des articles - Page Principale -</value>
         <value xml:lang="it">Pagina Principale Amministrazione Cataloghi</value>
-        <value xml:lang="nl">Hoofdpagina catalogusbeheer</value>		
+        <value xml:lang="nl">Hoofdpagina catalogusbeheer</value>    
         <value xml:lang="ro">Pagina Principala Administratie Cataloage</value>
         <value xml:lang="ru">Главная страница администрирования каталога</value>
         <value xml:lang="th">หน้าหลักการจัดการหมวดหมู่</value>
@@ -8251,7 +8251,7 @@
         <value xml:lang="es">Lista detallada de Catálogos</value>
         <value xml:lang="fr">Liste des catalogues</value>
         <value xml:lang="it">Lista Dettaglio Catalogo</value>
-        <value xml:lang="nl">Lijst van catalogi</value>		
+        <value xml:lang="nl">Lijst van catalogi</value>    
         <value xml:lang="ro">Lista Detaliu Catalog</value>
         <value xml:lang="ru">Список каталогов</value>
         <value xml:lang="th">รายการรายละเอียดหมวดหมู่</value>
@@ -8285,7 +8285,7 @@
         <value xml:lang="es">Adplicación de Administración de Catálogos</value>
         <value xml:lang="fr">Application de gestion des articles</value>
         <value xml:lang="it">Applicazione Gestione Cataloghi</value>
-        <value xml:lang="nl">Catalogus Manager</value>		
+        <value xml:lang="nl">Catalogus Manager</value>    
         <value xml:lang="ro">Aplicatie Gestiune Catalog</value>
         <value xml:lang="ru">Управление каталогом продуктов</value>
         <value xml:lang="th">โปรแกรมประยุกต์การจัดการหมวดหมู่</value>
@@ -8308,7 +8308,7 @@
         <value xml:lang="es">Nombre de Catálogo</value>
         <value xml:lang="fr">Nom du catalogue</value>
         <value xml:lang="it">Nome Catalogo</value>
-        <value xml:lang="nl">Catalogusnaam</value>		
+        <value xml:lang="nl">Catalogusnaam</value>    
         <value xml:lang="ro">Nume Catalog</value>
         <value xml:lang="ru">Имя каталога</value>
         <value xml:lang="th">ชื่อหมวดหมู่</value>
@@ -8320,7 +8320,7 @@
         <value xml:lang="es">Nombre de Catálogo [Código]</value>
         <value xml:lang="fr">Catalogue ; Nom ; [Réf.]</value>
         <value xml:lang="it">Nome Catalogo [Codice]</value>
-        <value xml:lang="nl">Catalogusnaam [ID]</value>		
+        <value xml:lang="nl">Catalogusnaam [ID]</value>    
         <value xml:lang="ro">Nume Catalog [Cod]</value>
         <value xml:lang="ru">Имя каталога [Код]</value>
         <value xml:lang="th">ชื่อหมวดหมู่ [รหัส]</value>
@@ -8486,7 +8486,7 @@
         <value xml:lang="es">Productos de esta Categoría</value>
         <value xml:lang="fr">Articles appartenant à cette catégorie</value>
         <value xml:lang="it">Prodotti per questa categoria</value>
-        <value xml:lang="nl">Producten in deze categorie</value>		
+        <value xml:lang="nl">Producten in deze categorie</value>    
         <value xml:lang="ro">Produse pentru aceasta categorie</value>
         <value xml:lang="ru">Продукты из категории</value>
         <value xml:lang="th">สินค้าจากหมวดหมู่นี้
@@ -8738,7 +8738,7 @@
         <value xml:lang="es">Elegir Categoría principal</value>
         <value xml:lang="fr">Choisir une catégorie supérieure</value>
         <value xml:lang="it">Scegli Categoria Principale</value>
-        <value xml:lang="nl">Lijst van hoofdcategoriën</value>		
+        <value xml:lang="nl">Lijst van hoofdcategoriën</value>    
         <value xml:lang="ro">Alege Categorii Principale</value>
         <value xml:lang="ru">Категория верх. уровня</value>
         <value xml:lang="th">เลือกหมวดหมู่</value>
@@ -8920,7 +8920,7 @@
         <value xml:lang="es">Configuraciones</value>
         <value xml:lang="fr">Configurations</value>
         <value xml:lang="it">Configurazioni</value>
-        <value xml:lang="nl">Configuraties</value>		
+        <value xml:lang="nl">Configuraties</value>    
         <value xml:lang="ro">Configuratii</value>
         <value xml:lang="ru">Конфигурации</value>
         <value xml:lang="th">ตัวเลือก</value>
@@ -9255,7 +9255,7 @@
         <value xml:lang="es">Crear nuevo Catálogo</value>
         <value xml:lang="fr">Création d'un nouveau catalogue</value>
         <value xml:lang="it">Creare Nuovo Catalogo</value>
-        <value xml:lang="nl">Aanmaken nieuwe catalogus</value>		
+        <value xml:lang="nl">Aanmaken nieuwe catalogus</value>    
         <value xml:lang="ro">Creare Nou Catalog</value>
         <value xml:lang="ru">Новый каталог</value>
         <value xml:lang="th">สร้างหมวดหมู่ใหม่</value>
@@ -9267,7 +9267,7 @@
         <value xml:lang="es">Crear nueva Categoría</value>
         <value xml:lang="fr">Création d'une nouvelle catégorie</value>
         <value xml:lang="it">Creare nuova categoria</value>
-        <value xml:lang="nl">Aanmaken nieuwe categorie</value>		
+        <value xml:lang="nl">Aanmaken nieuwe categorie</value>    
         <value xml:lang="ro">Creare Noua Categorie</value>
         <value xml:lang="ru">Новая категория</value>
         <value xml:lang="th">สร้างหมวดหมู่ใหม่</value>
@@ -9341,7 +9341,7 @@
         <value xml:lang="es">Crear nuevo Producto</value>
         <value xml:lang="fr">Création d'un nouvel article</value>
         <value xml:lang="it">Creare Nuovo Prodotto</value>
-        <value xml:lang="nl">Aanmaken nieuw product</value>		
+        <value xml:lang="nl">Aanmaken nieuw product</value>    
         <value xml:lang="ro">Creare Nou Produs</value>
         <value xml:lang="ru">Новый продукт</value>
         <value xml:lang="th">สร้างสินค้าใหม่</value>
@@ -9386,7 +9386,7 @@
         <value xml:lang="es">Crear Nueva Tienda de Productos</value>
         <value xml:lang="fr">Création d'un nouveau centre de profit</value>
         <value xml:lang="it">Creare Nuovo Negozio</value>
-        <value xml:lang="nl">Aanmaken nieuwe winkel</value>		
+        <value xml:lang="nl">Aanmaken nieuwe winkel</value>    
         <value xml:lang="ro">Creare Nou Magazin</value>
         <value xml:lang="ru">Создать новый склад</value>
         <value xml:lang="th">สร้างคลังสินค้าใหม่</value>
@@ -9990,7 +9990,7 @@
         <value xml:lang="es">Editar Catálogo</value>
         <value xml:lang="fr">Modification du catalogue</value>
         <value xml:lang="it">Aggiorna Catalogo</value>
-        <value xml:lang="nl">Wijzig catalogus</value>		
+        <value xml:lang="nl">Wijzig catalogus</value>    
         <value xml:lang="ro">Actualizeaza Catalog</value>
         <value xml:lang="ru">Редактировать</value>
         <value xml:lang="th">แก้ไขหมวดหมู่</value>
@@ -10002,7 +10002,7 @@
         <value xml:lang="es">Editar Catálogo con Código</value>
         <value xml:lang="fr">Modification de catalogue avec sa référence</value>
         <value xml:lang="it">Aggiorna Catalogo con Codice Catalogo</value>
-        <value xml:lang="nl">Wijzigen catalogus met [ID]</value>		
+        <value xml:lang="nl">Wijzigen catalogus met [ID]</value>    
         <value xml:lang="ro">Actualizeaza Catalog cu Cod Catalog</value>
         <value xml:lang="ru">Редактировать каталог с кодом</value>
         <value xml:lang="th">แก้ไขหมวดหมู่ด้วยรหัสหมวดหมู่</value>
@@ -10014,7 +10014,7 @@
         <value xml:lang="es">Editar Categoría</value>
         <value xml:lang="fr">Modification de la catégorie</value>
         <value xml:lang="it">Aggiorna Categoria</value>
-        <value xml:lang="nl">Wijzig categorie</value>		
+        <value xml:lang="nl">Wijzig categorie</value>    
         <value xml:lang="ro">Actualizeaza Categoria</value>
         <value xml:lang="ru">Редактировать</value>
         <value xml:lang="th">แก้ไขหมวดหมู่</value>
@@ -10026,7 +10026,7 @@
         <value xml:lang="es">Editar Categoría con Código</value>
         <value xml:lang="fr">Modification de la catégorie avec sa référence</value>
         <value xml:lang="it">Aggiorna Categoria con Codice Categoria</value>
-        <value xml:lang="nl">Wijzigen categorie met [ID]</value>		
+        <value xml:lang="nl">Wijzigen categorie met [ID]</value>    
         <value xml:lang="ro">Actualizeaza Categoria cu Cod Categorie</value>
         <value xml:lang="ru">Редактировать категорию с кодом</value>
         <value xml:lang="th">แก้ไขหมวดหมู่ด้วยรหัสหมวดหมู่</value>
@@ -10115,7 +10115,7 @@
         <value xml:lang="es">Editar Producto</value>
         <value xml:lang="fr">Modification de l'article</value>
         <value xml:lang="it">Aggiorna Prodotto</value>
-        <value xml:lang="nl">Wijzig product</value>		
+        <value xml:lang="nl">Wijzig product</value>    
         <value xml:lang="ro">Actualizeaza Produs</value>
         <value xml:lang="ru">Редактировать</value>
         <value xml:lang="th">แก้ไขสินค้า</value>
@@ -10145,7 +10145,7 @@
         <value xml:lang="es">Editar Producto con Código</value>
         <value xml:lang="fr">Modification de l'article de référence</value>
         <value xml:lang="it">Aggiorna Prodotto con Codice Prodotto</value>
-        <value xml:lang="nl">Wijzigen product met [ID]</value>		
+        <value xml:lang="nl">Wijzigen product met [ID]</value>    
         <value xml:lang="ro">Actualizeaza Produs cu Cod Produs</value>
         <value xml:lang="ru">Редактировать продукт с кодом</value>
         <value xml:lang="th">แก้ไขสินค้าด้วยรหัสสินค้า</value>
@@ -10576,7 +10576,7 @@
         <value xml:lang="de">Resultate ablaufen lassen von</value>
         <value xml:lang="en">Expire Results From</value>
         <value xml:lang="es">Expirar resultados desde</value>
-        <value xml:lang="fr">Supprimer les résultats à partir de</value>
+        <value xml:lang="fr">Supprimer les résultats à partir de (dans la)</value>
         <value xml:lang="it">Risultati Scaduti Da</value>
         <value xml:lang="ro">Resultate Expirate De la ProductExplodeOrderItems=Exploadeaza Linie Comanda</value>
         <value xml:lang="ru">Устаревание результатов из</value>
@@ -10930,7 +10930,7 @@
         <value xml:lang="es">Carga rápida del Catálogo en el caché</value>
         <value xml:lang="fr">Chargement rapide d'article dans le cache</value>
         <value xml:lang="it">Caricamento Veloce Catalogo nella Cache</value>
-        <value xml:lang="nl">Catalogus in cache laden</value>		
+        <value xml:lang="nl">Catalogus in cache laden</value>    
         <value xml:lang="ro">Incarcare Rapida Catalog in Cache</value>
         <value xml:lang="ru">Быстрая загрузка каталога в кэш</value>
         <value xml:lang="th">Fast Load Catalog into Cache</value>
@@ -11020,7 +11020,7 @@
         <value xml:lang="es">Características</value>
         <value xml:lang="fr">Caractéristiques</value>
         <value xml:lang="it">Caratteristiche</value>
-        <value xml:lang="nl">Kenmerken</value>		
+        <value xml:lang="nl">Kenmerken</value>    
         <value xml:lang="ro">Caracteristici</value>
         <value xml:lang="ru">Особенности</value>
         <value xml:lang="th">ลักษณะ</value>
@@ -11144,7 +11144,7 @@
         <value xml:lang="es">Características</value>
         <value xml:lang="fr">Caractéristiques</value>
         <value xml:lang="it">Caratteristiche</value>
-        <value xml:lang="nl">Kenmerken</value> 		
+        <value xml:lang="nl">Kenmerken</value>     
         <value xml:lang="ro">Caracteristica</value>
         <value xml:lang="ru">Особенности</value>
         <value xml:lang="th">ลักษณะ</value>
@@ -11221,7 +11221,7 @@
         <value xml:lang="es">Buscar producto</value>
         <value xml:lang="fr">Recherche d'un article</value>
         <value xml:lang="it">Ricerca Prodotto</value>
-        <value xml:lang="nl">Zoek product</value>		
+        <value xml:lang="nl">Zoek product</value>    
         <value xml:lang="ro">Cauta Produs</value>
         <value xml:lang="ru">Искать</value>
         <value xml:lang="th">ค้นหาสินค้า</value>
@@ -11233,7 +11233,7 @@
         <value xml:lang="es">Buscar producto con Código</value>
         <value xml:lang="fr">Recherche d'un article avec sa référence</value>
         <value xml:lang="it">Ricerca Prodotto con Valore Codice</value>
-        <value xml:lang="nl">Zoeken product met [ID]</value>		
+        <value xml:lang="nl">Zoeken product met [ID]</value>    
         <value xml:lang="ro">Cauta Produs cu Valoare Cod</value>
         <value xml:lang="ru">Искать продукт с кодом</value>
         <value xml:lang="th">ค้นหาสินค้าด้วยค่ารหัส</value>
@@ -11501,7 +11501,7 @@
         <value xml:lang="es">Regla Global de precios</value>
         <value xml:lang="fr">Règle globale de prix</value>
         <value xml:lang="it">Regola Globale Prezzi</value>
-        <value xml:lang="nl">Algemene prijsregel</value>		
+        <value xml:lang="nl">Algemene prijsregel</value>    
         <value xml:lang="ro">Regula Globala Pret</value>
         <value xml:lang="ru">Глобальное правило ценообразования</value>
         <value xml:lang="th">ข้อบังคับราคาโดยรวม</value>
@@ -11513,7 +11513,7 @@
         <value xml:lang="es">Reglas Globales de precios</value>
         <value xml:lang="fr">Règles globales de prix</value>
         <value xml:lang="it">Regole Globali Prezzi</value>
-        <value xml:lang="nl">Algemene prijsregels</value>		
+        <value xml:lang="nl">Algemene prijsregels</value>    
         <value xml:lang="ro">Regula Globala Preturi</value>
         <value xml:lang="ru">Глобальные правила ценообразования</value>
         <value xml:lang="th">ข้อบังคับราคาโดยรวม</value>
@@ -13782,7 +13782,7 @@
         <value xml:lang="es">Nuevo catálogo</value>
         <value xml:lang="fr">Nouveau catalogue</value>
         <value xml:lang="it">Nuovo Catalogo Prodotti</value>
-        <value xml:lang="nl">Nieuwe productcatalogus</value>		
+        <value xml:lang="nl">Nieuwe productcatalogus</value>    
         <value xml:lang="ro">Nou Catalog Produse</value>
         <value xml:lang="ru">Новый каталог</value>
         <value xml:lang="th">หมวดหมู่สินค้าใหม่</value>
@@ -14221,7 +14221,7 @@
         <value xml:lang="es">No se encontraron reglas de precio</value>
         <value xml:lang="fr">Règles de prix non trouvées</value>
         <value xml:lang="it">Nessuna Regola Prezzo trovata</value>
-        <value xml:lang="nl">Geen prijsregels gevonden</value>		
+        <value xml:lang="nl">Geen prijsregels gevonden</value>    
         <value xml:lang="ro">Nici-o regula de Pret Gasita ProductNoProductsInCategory=Nici-un produs in categorie</value>
         <value xml:lang="ru">Не найдены правила ценообразования</value>
         <value xml:lang="th">ไม่พบข้อบังคับราคา</value>
@@ -15816,7 +15816,7 @@
         <value xml:lang="es">Nombre de la regla de precio [CÓDIGO]</value>
         <value xml:lang="fr">Nom de la règle de prix [réf]</value>
         <value xml:lang="it">Nome Regola Prezzo [Codice]</value>
-        <value xml:lang="nl">Naam prijsregel [ID]</value>		
+        <value xml:lang="nl">Naam prijsregel [ID]</value>    
         <value xml:lang="ro">Nume Regula Pret [Cod]</value>
         <value xml:lang="ru">Имя правила ценообразования [Код]</value>
         <value xml:lang="th">ชื่อข้อกำหนดราคา [รหัส]</value>
@@ -15828,7 +15828,7 @@
         <value xml:lang="es">Reglas de precio</value>
         <value xml:lang="fr">Règles de prix</value>
         <value xml:lang="it">Regole Prezzo</value>
-        <value xml:lang="nl">Prijsregels</value>		
+        <value xml:lang="nl">Prijsregels</value>    
         <value xml:lang="ro">Regula Pret</value>
         <value xml:lang="ru">Ценообразование</value>
         <value xml:lang="th">ข้อกำหนดราคา</value>
@@ -15983,7 +15983,7 @@
         <value xml:lang="es">Lista de catálogos de productos</value>
         <value xml:lang="fr">Liste des catalogues</value>
         <value xml:lang="it">Lista Cataloghi Prodotto</value>
-        <value xml:lang="nl">Lijst van catalogi</value>		
+        <value xml:lang="nl">Lijst van catalogi</value>    
         <value xml:lang="ro">Lista Cataloage Produs</value>
         <value xml:lang="ru">Список продуктовых каталогов</value>
         <value xml:lang="th">รายการหมวดหมู่สินค้า</value>
@@ -16383,7 +16383,7 @@
         <value xml:lang="es">Lista de tiendas de productos</value>
         <value xml:lang="fr">Liste des centres de profit</value>
         <value xml:lang="it">Lista Negozi</value>
-        <value xml:lang="nl">Lijst van winkels</value>		
+        <value xml:lang="nl">Lijst van winkels</value>    
         <value xml:lang="ro">Lista Magazin</value>
         <value xml:lang="ru">Список складов</value>
         <value xml:lang="th">รายการคลังสินค้า</value>
@@ -16605,7 +16605,7 @@
         <value xml:lang="es">Promociones</value>
         <value xml:lang="fr">Promotions</value>
         <value xml:lang="it">Promozioni</value>
-        <value xml:lang="nl">Promoties</value>		
+        <value xml:lang="nl">Promoties</value>    
         <value xml:lang="ro">Promotii</value>
         <value xml:lang="ru">Акции</value>
         <value xml:lang="th">โปรโมชัน</value>
@@ -17170,7 +17170,7 @@
         <value xml:lang="es">Crear rápido Virtuales a partir de variantes</value>
         <value xml:lang="fr">Créer rapidement un article virtuel depuis des variantes</value>
         <value xml:lang="it">Creazione Veloce Virtuali da Varianti</value>
-        <value xml:lang="nl">Aanmaken virtuele producten van variantproducten</value>		
+        <value xml:lang="nl">Aanmaken virtuele producten van variantproducten</value>    
         <value xml:lang="ro">Creare Rapida Virtuala de Variante</value>
         <value xml:lang="ru">Быстро создать виртуальный из вариантов</value>
         <value xml:lang="th">สร้างทั้งหมดจากการเปลี่ยนแปลงอย่างรวดเร็ว</value>
@@ -17591,7 +17591,7 @@
         <value xml:lang="de">Resultate entfernen von</value>
         <value xml:lang="en">Remove Results From</value>
         <value xml:lang="es">Quitar resultados desde</value>
-        <value xml:lang="fr">Supprimer les résultats de</value>
+        <value xml:lang="fr">Supprimer les résultats de la</value>
         <value xml:lang="it">Rimuovi i Risultati da</value>
         <value xml:lang="ro">Sterge Rezultatele de la </value>
         <value xml:lang="ru">Удалить результаты от</value>
@@ -17954,7 +17954,7 @@
         <value xml:lang="es">Revisiones</value>
         <value xml:lang="fr">Approbations</value>
         <value xml:lang="it">Recensioni</value>
-        <value xml:lang="nl">Klantbeoordelingen</value>		
+        <value xml:lang="nl">Klantbeoordelingen</value>    
         <value xml:lang="ro">Recenzii</value>
         <value xml:lang="ru">Отзывы</value>
         <value xml:lang="th">ตรวจสอบ</value>
@@ -17986,7 +17986,7 @@
         <value xml:lang="es">Jerarquía</value>
         <value xml:lang="fr">Hiérarchie</value>
         <value xml:lang="it">Gerarchia</value>
-        <value xml:lang="nl">Hiërarchie</value>		
+        <value xml:lang="nl">Hiërarchie</value>    
         <value xml:lang="ro">Sosire</value>
         <value xml:lang="ru">Иерархия</value>
         <value xml:lang="th">Rollup</value>
@@ -18297,7 +18297,7 @@
         <value xml:lang="es">Buscar Productos</value>
         <value xml:lang="fr">Rechercher l'article</value>
         <value xml:lang="it">Ricerca Prodotti</value>
-        <value xml:lang="nl">Zoeken producten</value>		
+        <value xml:lang="nl">Zoeken producten</value>    
         <value xml:lang="ro">Cauta Produse </value>
         <value xml:lang="ru">Поиск продуктов</value>
         <value xml:lang="th">ค้นหาสินค้า</value>
@@ -19130,7 +19130,7 @@
         <value xml:lang="es">Envío</value>
         <value xml:lang="fr">Expédition</value>
         <value xml:lang="it">Metodi di Spedizione</value>
-        <value xml:lang="nl">Verzendmethoden</value>		
+        <value xml:lang="nl">Verzendmethoden</value>    
         <value xml:lang="ru">Поставки</value>
         <value xml:lang="th">การขนส่ง</value>
         <value xml:lang="zh">送货</value>
@@ -19575,7 +19575,7 @@
         <value xml:lang="es">Nombre de tienda [código]</value>
         <value xml:lang="fr">Nom du centre de profit [réf]</value>
         <value xml:lang="it">Nome Negozio [Codice]</value>
-        <value xml:lang="nl">Naam winkel [ID]</value>		
+        <value xml:lang="nl">Naam winkel [ID]</value>    
         <value xml:lang="ro">Nume Magazin [Cod]</value>
         <value xml:lang="ru">Имя склада [Код]</value>
         <value xml:lang="th">ชื่อคลังสินค้า [รหัส]</value>
@@ -19649,7 +19649,7 @@
         <value xml:lang="es">Tiendas</value>
         <value xml:lang="fr">Centres de profit</value>
         <value xml:lang="it">Negozi</value>
-        <value xml:lang="nl">Winkels</value>		
+        <value xml:lang="nl">Winkels</value>    
         <value xml:lang="ro">Magazine</value>
         <value xml:lang="ru">Торговые точки</value>
         <value xml:lang="th">คลังสินค้า</value>
@@ -19803,7 +19803,7 @@
         <value xml:lang="es">Suscripciones</value>
         <value xml:lang="fr">Abonnements</value>
         <value xml:lang="it">Abbonamenti</value>
-        <value xml:lang="nl">Abonnementen</value>		
+        <value xml:lang="nl">Abonnementen</value>    
         <value xml:lang="ro">Abonamente</value>
         <value xml:lang="ru">Подписки</value>
         <value xml:lang="th">การสั่งซื้อ</value>
@@ -20083,7 +20083,7 @@
         <value xml:lang="es">Tesauro</value>
         <value xml:lang="fr">Thésaurus</value>
         <value xml:lang="it">Sinonimi</value>
-        <value xml:lang="nl">Trefwoord synoniemen</value>		
+        <value xml:lang="nl">Trefwoord synoniemen</value>    
         <value xml:lang="ro">Sinonime</value>
         <value xml:lang="ru">Словари</value>
         <value xml:lang="th">สารานุกรม</value>
diff --git a/framework/service/src/org/ofbiz/service/eca/ServiceEcaUtil.java b/framework/service/src/org/ofbiz/service/eca/ServiceEcaUtil.java
index 115b725..eb76ac8 100644
--- a/framework/service/src/org/ofbiz/service/eca/ServiceEcaUtil.java
+++ b/framework/service/src/org/ofbiz/service/eca/ServiceEcaUtil.java
@@ -57,6 +57,10 @@
     }
 
     public static void readConfig() {
+        // Only proceed if the cache hasn't already been populated, caller should be using reloadConfig() in that situation
+        if (UtilValidate.isNotEmpty(ecaCache)) {
+            return;
+        }
         Element rootElement = null;
         try {
             rootElement = ServiceConfigUtil.getXmlRootElement();
diff --git a/framework/webslinger/lib/webslinger-base-invoker-20091211-3897-7ab22baea4b6.jar b/framework/webslinger/lib/webslinger-base-invoker-20091211-3897-7ab22baea4b6.jar
deleted file mode 100644
index 1ae3084..0000000
--- a/framework/webslinger/lib/webslinger-base-invoker-20091211-3897-7ab22baea4b6.jar
+++ /dev/null
Binary files differ
diff --git a/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java b/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java
index 9799213..747bcff 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java
@@ -176,7 +176,6 @@
                     //expandCollapseLink.setText("&nbsp;+&nbsp;");

                     currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");

                     expandCollapseLink.setStyle("collapsed");

-                    expandCollapseLink.setText(" ");

                     StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));

                     String trailName = node.getModelTree().getTrailName(context);

                     if (target.indexOf("?") < 0) {

@@ -196,7 +195,6 @@
                     currentNodeTrailPiped = "";

                 }

                 expandCollapseLink.setStyle("expanded");

-                expandCollapseLink.setText(" ");

                 StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));

                 String trailName = node.getModelTree().getTrailName(context);

                 if (target.indexOf("?") < 0) {

@@ -213,7 +211,6 @@
         } else if (!hasChildren) {

             context.put("processChildren", Boolean.FALSE);

             expandCollapseLink.setStyle("leafnode");

-            expandCollapseLink.setText(" ");

             renderLink(writer, context, expandCollapseLink);

         }

     }

diff --git a/framework/widget/templates/htmlTreeMacroLibrary.ftl b/framework/widget/templates/htmlTreeMacroLibrary.ftl
index 79d43d1..5e69b4f 100644
--- a/framework/widget/templates/htmlTreeMacroLibrary.ftl
+++ b/framework/widget/templates/htmlTreeMacroLibrary.ftl
@@ -53,7 +53,7 @@
 <#if name?has_content> name="${name}"</#if><#rt/>

 <#if title?has_content> title="${title}"</#if><#rt/>

 <#if targetWindow?has_content> target="${targetWindow}</#if> href="${linkUrl}"><#rt/>

-<#if imgStr?has_content>${imgStr}<#else><#if linkText?has_content>${linkText}</#if></#if></a><#rt/>

+<#if imgStr?has_content>${imgStr}<#elseif linkText?has_content/>${linkText}<#else/>&nbsp;</#if></a><#rt/>

 </#macro>

 

 <#macro renderImage src id style wid hgt border alt urlString>

diff --git a/specialpurpose/pos/data/DemoRetail.xml b/specialpurpose/pos/data/DemoRetail.xml
index 5179e30..2a035fb 100644
--- a/specialpurpose/pos/data/DemoRetail.xml
+++ b/specialpurpose/pos/data/DemoRetail.xml
@@ -77,7 +77,9 @@
 
 
     <!-- use this one when the scheduled PUSH service is enabled
-    <PosTerminal posTerminalId="pos-1" facilityId="MyRetailStore" pushEntitySyncId="5505"/>
+    <PosTerminal posTerminalId="pos-1" terminalName="Pos Terminal 1" facilityId="MyRetailStore" pushEntitySyncId="5505"/>
+    <PosTerminal posTerminalId="pos-2" terminalName="Pos Terminal 2" facilityId="MyRetailStore" pushEntitySyncId="5505"/>
+    <PosTerminal posTerminalId="pos-3" terminalName="Pos Terminal 3" facilityId="MyRetailStore" pushEntitySyncId="5505"/>
     -->
 
     <!-- use this one when the scheduled PUSH service is not enabled -->
diff --git a/specialpurpose/pos/src/org/ofbiz/pos/PosTransaction.java b/specialpurpose/pos/src/org/ofbiz/pos/PosTransaction.java
index 50ab221..ced1576 100644
--- a/specialpurpose/pos/src/org/ofbiz/pos/PosTransaction.java
+++ b/specialpurpose/pos/src/org/ofbiz/pos/PosTransaction.java
@@ -433,7 +433,7 @@
             Delegator delegator = cart.getDelegator();
             GenericValue product = null;
             product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
-            if ("AGGREGATED".equals(product.getString("productTypeId"))) {
+            if (UtilValidate.isNotEmpty(product) && "AGGREGATED".equals(product.getString("productTypeId"))) {
                 return true;
             }
         } catch (GenericEntityException e) {
@@ -492,7 +492,7 @@
             GenericValue product = null;
             ProductConfigWrapper pcw = null;
             product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
-            if ("AGGREGATED".equals(product.getString("productTypeId"))) {
+            if (UtilValidate.isNotEmpty(product) && "AGGREGATED".equals(product.getString("productTypeId"))) {
                 // if it's an aggregated item, load the configwrapper and set to defaults
                 pcw = new ProductConfigWrapper(delegator, session.getDispatcher(), productId, null, null, null, null, null, null);
                 pcw.setDefaultConfig();
@@ -1715,7 +1715,7 @@
             svcCtx.put("userLogin", userLogin);
             svcCtx.put("lastName", name);
             svcCtx.put("firstName", ""); // Needed by service createPersonAndUserLogin
-            if (UtilValidate.isNotEmpty(email) && UtilValidate.isNotEmpty(card)) {
+            if (UtilValidate.isNotEmpty(email) && UtilValidate.isNotEmpty(phone)) {
                 svcCtx.put("userLoginId", email);
                 svcCtx.put("currentPassword", phone);
                 svcCtx.put("currentPasswordVerify", phone);
diff --git a/specialpurpose/pos/src/org/ofbiz/pos/event/ManagerEvents.java b/specialpurpose/pos/src/org/ofbiz/pos/event/ManagerEvents.java
index 3317664..dffe309 100644
--- a/specialpurpose/pos/src/org/ofbiz/pos/event/ManagerEvents.java
+++ b/specialpurpose/pos/src/org/ofbiz/pos/event/ManagerEvents.java
@@ -42,6 +42,8 @@
 import org.ofbiz.entity.condition.EntityCondition;
 import org.ofbiz.entity.condition.EntityExpr;
 import org.ofbiz.entity.condition.EntityOperator;
+import org.ofbiz.entity.transaction.GenericTransactionException;
+import org.ofbiz.entity.transaction.TransactionUtil;
 import org.ofbiz.entity.util.EntityListIterator;
 import org.ofbiz.guiapp.xui.XuiSession;
 import org.ofbiz.pos.PosTransaction;
@@ -478,52 +480,75 @@
         BigDecimal othTotal = ZERO;
         BigDecimal total = ZERO;
 
-        Delegator delegator = pos.getSession().getDelegator();
-        List<EntityExpr> exprs = UtilMisc.toList(EntityCondition.makeCondition("originFacilityId", EntityOperator.EQUALS, trans.getFacilityId()),
-                EntityCondition.makeCondition("terminalId", EntityOperator.EQUALS, trans.getTerminalId()));
-        EntityListIterator eli = null;
-
+        boolean beganTransaction = false;
         try {
-            eli = delegator.find("OrderHeaderAndPaymentPref", EntityCondition.makeCondition(exprs, EntityOperator.AND), null, null, null, null);
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-        }
-
-        Timestamp dayStart = state.getTimestamp("openedDate");
-        Timestamp dayEnd = state.getTimestamp("closedDate");
-        if (dayEnd == null) {
-            dayEnd = UtilDateTime.nowTimestamp();
-        }
-
-        if (eli != null) {
-            GenericValue ohpp;
-            while (((ohpp = (GenericValue) eli.next()) != null)) {
-                Timestamp orderDate = ohpp.getTimestamp("orderDate");
-                if (orderDate.after(dayStart) && orderDate.before(dayEnd)) {
-                    String pmt = ohpp.getString("paymentMethodTypeId");
-                    BigDecimal amt = ohpp.getBigDecimal("maxAmount");
-
-                    if ("CASH".equals(pmt)) {
-                        cashTotal = cashTotal.add(amt);
-                    } else  if ("PERSONAL_CHECK".equals(pmt)) {
-                        checkTotal = checkTotal.add(amt);
-                    } else if ("GIFT_CARD".equals(pmt)) {
-                        gcTotal = gcTotal.add(amt);
-                    } else if ("CREDIT_CARD".equals(pmt)) {
-                        ccTotal = ccTotal.add(amt);
-                    } else {
-                        othTotal = othTotal.add(amt);
+            beganTransaction = TransactionUtil.begin();
+        
+            Delegator delegator = pos.getSession().getDelegator();
+            List<EntityExpr> exprs = UtilMisc.toList(EntityCondition.makeCondition("originFacilityId", EntityOperator.EQUALS, trans.getFacilityId()),
+                    EntityCondition.makeCondition("terminalId", EntityOperator.EQUALS, trans.getTerminalId()));
+            EntityListIterator eli = null;
+    
+            try {
+                eli = delegator.find("OrderHeaderAndPaymentPref", EntityCondition.makeCondition(exprs, EntityOperator.AND), null, null, null, null);
+            } catch (GenericEntityException e) {
+                Debug.logError(e, module);
+            }
+    
+            Timestamp dayStart = state.getTimestamp("openedDate");
+            Timestamp dayEnd = state.getTimestamp("closedDate");
+            if (dayEnd == null) {
+                dayEnd = UtilDateTime.nowTimestamp();
+            }
+    
+            if (eli != null) {
+                GenericValue ohpp;
+                while (((ohpp = (GenericValue) eli.next()) != null)) {
+                    Timestamp orderDate = ohpp.getTimestamp("orderDate");
+                    if (orderDate.after(dayStart) && orderDate.before(dayEnd)) {
+                        String pmt = ohpp.getString("paymentMethodTypeId");
+                        BigDecimal amt = ohpp.getBigDecimal("maxAmount");
+    
+                        if ("CASH".equals(pmt)) {
+                            cashTotal = cashTotal.add(amt);
+                        } else  if ("PERSONAL_CHECK".equals(pmt)) {
+                            checkTotal = checkTotal.add(amt);
+                        } else if ("GIFT_CARD".equals(pmt)) {
+                            gcTotal = gcTotal.add(amt);
+                        } else if ("CREDIT_CARD".equals(pmt)) {
+                            ccTotal = ccTotal.add(amt);
+                        } else {
+                            othTotal = othTotal.add(amt);
+                        }
+                        total = total.add(amt);
                     }
-                    total = total.add(amt);
+                }
+    
+                try {
+                    eli.close();
+                } catch (GenericEntityException e) {
+                    Debug.logWarning(e, "Trouble closing ELI", module);
+                    pos.showDialog("dialog/error/exception", e.getMessage());                    
                 }
             }
-
+        } catch (GenericTransactionException e) {
+            Debug.logError(e, module);
             try {
-                eli.close();
-            } catch (GenericEntityException e) {
-                Debug.logWarning(e, "Trouble closing ELI", module);
+                TransactionUtil.rollback(beganTransaction, e.getMessage(), e);
+            } catch (GenericTransactionException e2) {
+                Debug.logError(e2, "Unable to rollback transaction", module);
+                pos.showDialog("dialog/error/exception", e2.getMessage());
+            }
+            pos.showDialog("dialog/error/exception", e.getMessage());
+        } finally {
+            try {
+                TransactionUtil.commit(beganTransaction);
+            } catch (GenericTransactionException e) {
+                Debug.logError(e, "Unable to commit transaction", module);
+                pos.showDialog("dialog/error/exception", e.getMessage());
             }
         }
+            
 
         Map<String, String> reportMap = FastMap.newInstance();
         String reportTemplate = "totals.txt";