You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by jo...@apache.org on 2007/02/14 09:05:53 UTC

svn commit: r507431 - in /ofbiz/trunk/applications/product: config/ script/org/ofbiz/product/category/ script/org/ofbiz/product/product/ servicedef/ webapp/catalog/WEB-INF/ webapp/catalog/category/ widget/catalog/

Author: jonesde
Date: Wed Feb 14 00:05:53 2007
New Revision: 507431

URL: http://svn.apache.org/viewvc?view=rev&rev=507431
Log:
Applied patch from Ashish in Jira #OFBIZ-717; also did a number of cleanups and reorganized product service defs to group better; changed this to use the category permission service (was using the product one, and patch had a new product permission service instead of using the existing one, which now has a permission-service style wrapper around it

Modified:
    ofbiz/trunk/applications/product/config/ProductUiLabels.properties
    ofbiz/trunk/applications/product/script/org/ofbiz/product/category/CategoryServices.xml
    ofbiz/trunk/applications/product/script/org/ofbiz/product/product/ProductServices.xml
    ofbiz/trunk/applications/product/servicedef/services.xml
    ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml
    ofbiz/trunk/applications/product/webapp/catalog/category/CategoryForms.xml
    ofbiz/trunk/applications/product/webapp/catalog/category/CategoryTabBar.ftl
    ofbiz/trunk/applications/product/widget/catalog/CategoryScreens.xml

Modified: ofbiz/trunk/applications/product/config/ProductUiLabels.properties
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/config/ProductUiLabels.properties?view=diff&rev=507431&r1=507430&r2=507431
==============================================================================
--- ofbiz/trunk/applications/product/config/ProductUiLabels.properties (original)
+++ ofbiz/trunk/applications/product/config/ProductUiLabels.properties Wed Feb 14 00:05:53 2007
@@ -104,6 +104,7 @@
 PageTitleEditProductCatalogParties=Edit Product Catalog Parties
 PageTitleEditProductCatalogStores=Edit Product Catalog Stores
 PageTitleEditProductCategories=Edit Product Categories
+PageTitleEditProductCategoryLink=Edit Product Category Link
 PageTitleEditProductConfigs=Edit Product Configs
 PageTitleEditProductContent=Edit Product Content
 PageTitleEditProductCosts=Edit Product Costs
@@ -363,6 +364,7 @@
 ProductCategoryContent=Content
 ProductCategoryId=Category ID
 ProductCategoryImageUrl=Category Image URL
+ProductCategoryLinks=Links
 ProductCategoryMembers=Category Members
 ProductCategoryNotFoundforCategoryID=Category not found for Category ID
 ProductCategoryPage=Category Page
@@ -704,6 +706,7 @@
 ProductLine=Line
 ProductLinkOneImageUrl=Link One Image URL
 ProductLinkTwoImageUrl=Link Two Image URL
+ProductLinkTypeEnumId = Link Type Enum
 ProductListPrice=List Price
 ProductLoadingCatalogCaches=Loading Catalog Caches
 ProductLocaleString=Locale String
@@ -912,6 +915,7 @@
 ProductPartyFreeShipping=The Party ID for Free Shipping actions is Carrier Party ID to give free shipping for (if blank any Carrier Parties may receive free shipping).
 ProductPaymentTypes=Payment Types
 ProductPercent=percent
+ProductPermissionError=Security Error\: to run ${resourceDescription} you must have the CATALOG_${mainAction} or CATALOG_ADMIN permission
 ProductPersons=persons
 ProductPerUnitPrice=Per Unit Price
 ProductPhoneNumbers=Phone Numbers

Modified: ofbiz/trunk/applications/product/script/org/ofbiz/product/category/CategoryServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/script/org/ofbiz/product/category/CategoryServices.xml?view=diff&rev=507431&r1=507430&r2=507431
==============================================================================
--- ofbiz/trunk/applications/product/script/org/ofbiz/product/category/CategoryServices.xml (original)
+++ ofbiz/trunk/applications/product/script/org/ofbiz/product/category/CategoryServices.xml Wed Feb 14 00:05:53 2007
@@ -697,7 +697,6 @@
         </iterate>
         <field-to-result field-name="hasPermission"/>
         <field-to-result field-name="failMessage"/>
-                
     </simple-method>
     
     <simple-method method-name="duplicateProductCategory" short-description="Duplicate a ProductCategory">
@@ -811,4 +810,32 @@
         <find-by-primary-key entity-name="ProductCategoryAttribute" map-name="lookupPKMap" value-name="ProductCategoryAttributeInstance"/>
         <remove-value value-name="ProductCategoryAttributeInstance"/>
     </simple-method>
+    
+
+    <!-- ProductCategoryLink Create/Update/Delete"-->
+    <simple-method method-name="createProductCategoryLink" short-description="create a ProductCategoryLink">
+        <make-value entity-name="ProductCategoryLink" value-name="newEntity"/>
+        <set-pk-fields map-name="parameters" value-name="newEntity"/>
+        <if-empty field-name="parameters.linkSeqId">
+            <make-next-seq-id value-name="newEntity" seq-field-name="linkSeqId"/> <!-- this finds the next sub-sequence ID -->
+            <set from-field="linkSeqId" field="newEntity.linkSeqId"/>
+        </if-empty>    
+        <if-empty field-name="newEntity.fromDate">
+            <now-timestamp-to-env env-name="newEntity.fromDate"/>
+        </if-empty>
+        <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
+        <create-value value-name="newEntity"/>  
+    </simple-method>   
+    
+    <simple-method method-name="updateProductCategoryLink" short-description="update a ProductCategoryLink">
+        <entity-one entity-name="ProductCategoryLink" value-name="lookedUpValue"/>
+        <set-nonpk-fields value-name="lookedUpValue" map-name="parameters"/>
+        <store-value value-name="lookedUpValue"/>
+    </simple-method>
+    
+    <simple-method method-name="deleteProductCategoryLink" short-description="delete a ProductCategoryLink">        
+        <entity-one entity-name="ProductCategoryLink" value-name="lookedUpValue"/>
+        <remove-value value-name="lookedUpValue"/>
+    </simple-method>
+        
 </simple-methods>

Modified: ofbiz/trunk/applications/product/script/org/ofbiz/product/product/ProductServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/script/org/ofbiz/product/product/ProductServices.xml?view=diff&rev=507431&r1=507430&r2=507431
==============================================================================
--- ofbiz/trunk/applications/product/script/org/ofbiz/product/product/ProductServices.xml (original)
+++ ofbiz/trunk/applications/product/script/org/ofbiz/product/product/ProductServices.xml Wed Feb 14 00:05:53 2007
@@ -481,52 +481,6 @@
         <remove-value value-name="lookedUpValue"/>
     </simple-method>
 
-    <!-- a method to centralize product security code, meant to be called in-line with
-        call-simple-method, and the checkAction and callingMethodName attributes should be in the method context -->
-    <simple-method method-name="checkProductRelatedPermission" short-description="Check Product Related Permission">
-        <if-empty field-name="callingMethodName">
-            <set value="this operation" field="callingMethodName"/>
-        </if-empty>
-        <if-empty field-name="checkAction">
-            <set value="UPDATE" field="checkAction"/>
-        </if-empty>
-
-        <!-- find all role-categories that this product is a member of -->
-        <if>
-            <condition>
-                <not><if-has-permission permission="CATALOG" action="_${checkAction}"/></not>
-            </condition>
-            <then>
-                <set from-field="parameters.productId" field="lookupRoleCategoriesMap.productId"/>
-                <set from-field="userLogin.partyId" field="lookupRoleCategoriesMap.partyId"/>
-                <set value="LTD_ADMIN" field="lookupRoleCategoriesMap.roleTypeId"/>
-                <find-by-and entity-name="ProductCategoryMemberAndRole" map-name="lookupRoleCategoriesMap" list-name="roleCategories"/>
-                <filter-list-by-date list-name="roleCategories" valid-date-name="nowTimestamp"/>
-                <filter-list-by-date list-name="roleCategories" valid-date-name="nowTimestamp" from-field-name="roleFromDate" thru-field-name="roleThruDate"/>
-            </then>
-        </if>
-        <if>
-            <condition>
-                <not>
-                    <or>
-                        <if-has-permission permission="CATALOG" action="_${checkAction}"/>
-                        <and>
-                            <if-has-permission permission="CATALOG_ROLE" action="_${checkAction}"/>
-                            <not><if-empty field-name="roleCategories"/></not>
-                        </and>
-                        <and>
-                            <not><if-empty field-name="alternatePermissionRoot"/></not>
-                            <if-has-permission permission="${alternatePermissionRoot}" action="_${checkAction}"/>
-                        </and>
-                    </or>
-                </not>
-            </condition>
-            <then>
-                <add-error><fail-message message="Security Error: to run ${callingMethodName} you must have the CATALOG_${checkAction} or CATALOG_ADMIN permission or have the CATALOG_ROLE_${checkAction} permission and be associated with a category containing this product."/></add-error>
-            </then>
-        </if>
-    </simple-method>
-
     <simple-method method-name="createProductReview" short-description="Create a ProductReview">
         <make-value value-name="newEntity" entity-name="ProductReview"/>
         <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
@@ -562,9 +516,11 @@
         <call-simple-method method-name="updateProductWithReviewRatingAvg"/>
     </simple-method>
     <simple-method method-name="updateProductReview" short-description="Update ProductReview">
-        <check-permission permission="CATALOG" action="_UPDATE"><fail-message message="Security Error: to run updateProductReview you must have the CATALOG_UPDATE or CATALOG_ADMIN permission"/></check-permission>
+        <set value="updateProductReview" field="callingMethodName"/>
+        <set value="UPDATE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
-
+        
         <make-value value-name="lookupPKMap" entity-name="ProductReview"/>
         <set-pk-fields map-name="parameters" value-name="lookupPKMap"/>
         <find-by-primary-key map-name="lookupPKMap" value-name="lookedUpValue"/>
@@ -716,9 +672,9 @@
 
     <!-- for managing product to product associations -->
     <simple-method method-name="createProductAssoc" short-description="Create an association between two products"> 
-        <check-permission permission="CATALOG" action="_CREATE">
-            <fail-message message="Security Error: to create a product association requires the CATALOG_CREATE or CATALOG_ADMIN permission"/>
-        </check-permission>
+        <set value="createProductAssoc" field="callingMethodName"/>
+        <set value="CREATE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
 
         <make-value value-name="newEntity" entity-name="ProductAssoc"/>
@@ -728,11 +684,11 @@
         <create-value value-name="newEntity"/>
     </simple-method>
     <simple-method method-name="updateProductAssoc" short-description="Update an association between two products">
-        <check-permission permission="CATALOG" action="_UPDATE">
-            <fail-message message="Security Error: to update a product association requires the CATALOG_UPDATE or CATALOG_ADMIN permission"/>
-        </check-permission>
+        <set value="updateProductAssoc" field="callingMethodName"/>
+        <set value="UPDATE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
-
+        
         <make-value value-name="lookupPKMap" entity-name="ProductAssoc"/>
         <set-pk-fields map-name="parameters" value-name="lookupPKMap"/>
         <find-by-primary-key entity-name="ProductAssoc" map-name="lookupPKMap" value-name="productAssocInstance"/>
@@ -740,11 +696,11 @@
         <store-value value-name="productAssocInstance"/>
     </simple-method>
     <simple-method method-name="deleteProductAssoc" short-description="Delete an association between two products">
-        <check-permission permission="CATALOG" action="_DELETE">
-            <fail-message message="Security Error: to delete a product association requires the CATALOG_DELETE or CATALOG_ADMIN permission"/>
-        </check-permission>
+        <set value="deleteProductAssoc" field="callingMethodName"/>
+        <set value="DELETE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
-
+        
         <make-value value-name="lookupPKMap" entity-name="ProductAssoc"/>
         <set-pk-fields map-name="parameters" value-name="lookupPKMap"/>
         <find-by-primary-key entity-name="ProductAssoc" map-name="lookupPKMap" value-name="productAssocInstance"/>
@@ -753,11 +709,11 @@
 
     <!-- Create/Update/Delete Product Maint Record -->
     <simple-method method-name="createProductMaint" short-description="Create an Product Maintenance">
-        <check-permission permission="CATALOG" action="_CREATE">
-            <alt-permission permission="CATALOG_ROLE" action="_CREATE"/>
-            <fail-message message="Security Error: to run createProductMaint you must have the CATALOG_CREATE or CATALOG_ADMIN permission, or the limited CATALOG_ROLE_CREATE permission"/>
-        </check-permission>        
+        <set value="createProductMaint" field="callingMethodName"/>
+        <set value="CREATE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
+        
         <make-value value-name="newEntity" entity-name="ProductMaint"/>
         <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
         <set-pk-fields map-name="parameters" value-name="newEntity"/>
@@ -766,54 +722,122 @@
         <create-value value-name="newEntity"/>
     </simple-method>
     <simple-method method-name="updateProductMaint" short-description="Update an existing Product Maintenance">
-        <check-permission permission="CATALOG" action="_UPDATE">
-            <alt-permission permission="CATALOG_ROLE" action="_UPDATE"/>
-            <fail-message message="Security Error: to run updateProductMaint you must have the CATALOG_UPDATE or CATALOG_ADMIN permission, or the limited CATALOG_ROLE_UPDATE permission"/>
-        </check-permission>        
+        <set value="updateProductMaint" field="callingMethodName"/>
+        <set value="UPDATE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
+
         <entity-one entity-name="ProductMaint" value-name="lookedUpValue"/>
         <set-nonpk-fields map-name="parameters" value-name="lookedUpValue"/>
         <store-value value-name="lookedUpValue"/>
     </simple-method>
     <simple-method method-name="deleteProductMaint" short-description="Delete Product Maint from PRODUCT_MAINT">
-        <check-permission permission="CATALOG" action="_DELETE">
-            <alt-permission permission="CATALOG_ROLE" action="_DELETE"/>
-            <fail-message message="Security Error: to run deleteProductMaint you must have the CATALOG_DELETE or CATALOG_ADMIN permission, or the limited CATALOG_ROLE_UPDATE permission"/>
-        </check-permission>        
+        <set value="deleteProductMaint" field="callingMethodName"/>
+        <set value="DELETE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
+
         <entity-one entity-name="ProductMaint" value-name="lookedUpValue"/>
         <remove-value value-name="lookedUpValue"/>
     </simple-method>
     <!-- Create/Update/Delete Product Meter Record -->
     <simple-method method-name="createProductMeter" short-description="Create an Product Meter">
-        <check-permission permission="CATALOG" action="_CREATE">
-            <alt-permission permission="CATALOG_ROLE" action="_CREATE"/>
-            <fail-message message="Security Error: to run createProductMeter you must have the CATALOG_CREATE or CATALOG_ADMIN permission, or the limited CATALOG_ROLE_CREATE permission"/>
-        </check-permission>        
+        <set value="createProductMeter" field="callingMethodName"/>
+        <set value="CREATE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
+
         <make-value value-name="newEntity" entity-name="ProductMeter"/>
         <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
         <set-pk-fields map-name="parameters" value-name="newEntity"/>
         <create-value value-name="newEntity"/>
     </simple-method>
     <simple-method method-name="updateProductMeter" short-description="Update an existing Product Meter">
-        <check-permission permission="CATALOG" action="_UPDATE">
-            <alt-permission permission="CATALOG_ROLE" action="_UPDATE"/>
-            <fail-message message="Security Error: to run updateProductMeter you must have the CATALOG_UPDATE or CATALOG_ADMIN permission, or the limited CATALOG_ROLE_UPDATE permission"/>
-        </check-permission>        
+        <set value="updateProductMeter" field="callingMethodName"/>
+        <set value="UPDATE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
+
         <entity-one entity-name="ProductMeter" value-name="lookedUpValue"/>
         <set-nonpk-fields map-name="parameters" value-name="lookedUpValue"/>
         <store-value value-name="lookedUpValue"/>
     </simple-method>
     <simple-method method-name="deleteProductMeter" short-description="Delete an existing Product Meter">
-        <check-permission permission="CATALOG" action="_DELETE">
-            <alt-permission permission="CATALOG_ROLE" action="_DELETE"/>
-            <fail-message message="Security Error: to run deleteProductMeter you must have the CATALOG_DELETE or CATALOG_ADMIN permission, or the limited CATALOG_ROLE_UPDATE permission"/>
-        </check-permission>        
+        <set value="deleteProductMeter" field="callingMethodName"/>
+        <set value="DELETE" field="checkAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
         <check-errors/>
+        
         <entity-one entity-name="ProductMeter" value-name="lookedUpValue"/>
         <remove-value value-name="lookedUpValue"/>
     </simple-method>
     
+    <!-- a method to centralize product security code, meant to be called in-line with
+        call-simple-method, and the checkAction and callingMethodName attributes should be in the method context -->
+    <simple-method method-name="checkProductRelatedPermission" short-description="Check Product Related Permission">
+        <if-empty field-name="callingMethodName">
+            <set value="this operation" field="callingMethodName"/>
+        </if-empty>
+        <if-empty field-name="checkAction">
+            <set value="UPDATE" field="checkAction"/>
+        </if-empty>
+        
+        <!-- find all role-categories that this product is a member of -->
+        <if>
+            <condition>
+                <not><if-has-permission permission="CATALOG" action="_${checkAction}"/></not>
+            </condition>
+            <then>
+                <set from-field="parameters.productId" field="lookupRoleCategoriesMap.productId"/>
+                <set from-field="userLogin.partyId" field="lookupRoleCategoriesMap.partyId"/>
+                <set value="LTD_ADMIN" field="lookupRoleCategoriesMap.roleTypeId"/>
+                <find-by-and entity-name="ProductCategoryMemberAndRole" map-name="lookupRoleCategoriesMap" list-name="roleCategories"/>
+                <filter-list-by-date list-name="roleCategories" valid-date-name="nowTimestamp"/>
+                <filter-list-by-date list-name="roleCategories" valid-date-name="nowTimestamp" from-field-name="roleFromDate" thru-field-name="roleThruDate"/>
+            </then>
+        </if>
+        <if>
+            <condition>
+                <not>
+                    <or>
+                        <if-has-permission permission="CATALOG" action="_${checkAction}"/>
+                        <and>
+                            <if-has-permission permission="CATALOG_ROLE" action="_${checkAction}"/>
+                            <not><if-empty field-name="roleCategories"/></not>
+                        </and>
+                        <and>
+                            <not><if-empty field-name="alternatePermissionRoot"/></not>
+                            <if-has-permission permission="${alternatePermissionRoot}" action="_${checkAction}"/>
+                        </and>
+                    </or>
+                </not>
+            </condition>
+            <then>
+                <add-error><fail-message message="Security Error: to run ${callingMethodName} you must have the CATALOG_${checkAction} or CATALOG_ADMIN permission or have the CATALOG_ROLE_${checkAction} permission and be associated with a category containing this product."/></add-error>
+            </then>
+        </if>
+    </simple-method>
+    <simple-method method-name="productGenericPermission" short-description="Main permission logic">
+        <set field="mainAction" from-field="parameters.mainAction"/>
+        <if-empty field-name="mainAction">
+            <add-error><fail-message message="In the permission-service element for the productGenericPermission service the main-action attribute was missing but is required"/></add-error>
+            <check-errors/>
+        </if-empty>
+
+        <set field="callingMethodName" from-field="parameters.resourceDescription"/>
+        <set field="checkAction" from-field="parameters.mainAction"/>
+        <call-simple-method method-name="checkProductRelatedPermission"/>
+        
+        <if-empty field-name="error_list">
+            <set field="hasPermission" type="Boolean" value="true"/>
+            <field-to-result field-name="hasPermission"/>
+
+            <else>
+                <property-to-field resource="ProductUiLabels" property="ProductPermissionError" field-name="failMessage"/>
+                <set field="hasPermission" type="Boolean" value="false"/>
+                <field-to-result field-name="hasPermission"/>
+                <field-to-result field-name="failMessage"/>
+            </else>
+        </if-empty>
+    </simple-method>
 </simple-methods>

Modified: ofbiz/trunk/applications/product/servicedef/services.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/services.xml?view=diff&rev=507431&r1=507430&r2=507431
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/services.xml Wed Feb 14 00:05:53 2007
@@ -24,7 +24,9 @@
     <vendor>OFBiz</vendor>
     <version>1.0</version>
 
+    <!-- ======================================== -->
     <!-- Product Services -->
+    <!-- ======================================== -->
     <service name="interfaceProduct" default-entity-name="Product" engine="interface" location="" invoke="">
         <auto-attributes include="nonpk" mode="IN" optional="true">
             <exclude field-name="createdDate"/>
@@ -286,7 +288,201 @@
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
 
+    <!-- Product content services -->
+    <service name="createProductContent" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="createProductContent" auth="true">
+        <description>Add Content To Product</description>
+        <auto-attributes include="pk" mode="INOUT" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <auto-attributes entity-name="Content" include="nonpk" mode="IN" optional="true"/>
+        <override name="fromDate" optional="true" />
+        <!--<override name="contentId" optional="true" mode="INOUT" />-->
+    </service>
+    <service name="updateProductContent" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="updateProductContent" auth="true">
+        <description>Update Content To Product</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <auto-attributes entity-name="Content" include="nonpk" mode="IN" optional="true"/>
+    </service>
+    <service name="removeProductContent" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="removeProductContent" auth="true">
+        <description>Remove Content From Product</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+    </service>
+    <service name="createEmailContentForProduct" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="createEmailContentForProduct" auth="true">
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <auto-attributes mode="IN" entity-name="Content" optional="true"/>
+        <attribute name="subject" type="String" mode="IN" optional="false"/>
+        <attribute name="plainBody" type="String" mode="IN" optional="false"/>
+        <attribute name="htmlBody" type="String" mode="IN" optional="true"/>
+        <override name="contentId" optional="true" mode="INOUT"/>
+    </service>
+    <service name="updateEmailContentForProduct" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="updateEmailContentForProduct" auth="true">
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <auto-attributes entity-name="Content" include="nonpk" mode="IN" optional="true"/>
+        <attribute name="subjectDataResourceId" type="String" mode="IN" optional="true"/>
+        <attribute name="subject" type="String" mode="IN" optional="true"/>
+        <attribute name="plainBodyDataResourceId" type="String" mode="IN" optional="true"/>
+        <attribute name="plainBody" type="String" mode="IN" optional="true"/>
+        <attribute name="htmlBodyDataResourceId" type="String" mode="IN" optional="true"/>
+        <attribute name="htmlBody" type="String" mode="IN" optional="true"/>
+    </service>
+    <service name="createDownloadContentForProduct" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="createDownloadContentForProduct" auth="true">
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <auto-attributes mode="IN" entity-name="Content" optional="true"/>
+        <attribute name="file" type="String" mode="IN" optional="false"/>
+        <override name="contentId" optional="true"/>
+    </service>
+    <service name="updateDownloadContentForProduct" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="updateDownloadContentForProduct" auth="true">
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <auto-attributes mode="IN" entity-name="Content" optional="true"/>
+        <attribute name="fileDataResourceId" type="String" mode="IN" optional="true"/>
+        <attribute name="file" type="String" mode="IN" optional="true"/>
+    </service>
+    
+    <service name="createSimpleTextContentForProduct" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="createSimpleTextContentForProduct" auth="true">
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <auto-attributes entity-name="Content" include="nonpk" mode="IN" optional="true"/>
+        <attribute name="text" type="String" mode="IN" optional="false"/>
+        <override name="contentId" optional="true"/>
+        <override name="fromDate" optional="true"/>
+    </service>
+    <service name="updateSimpleTextContentForProduct" default-entity-name="ProductContent" engine="simple"
+        location="org/ofbiz/product/product/ProductContentServices.xml" invoke="updateSimpleTextContentForProduct" auth="true">
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <auto-attributes mode="IN" entity-name="Content" optional="true"/>
+        <attribute name="textDataResourceId" type="String" mode="IN" optional="true"/>
+        <attribute name="text" type="String" mode="IN" optional="true"/>
+    </service>
+    
+    <!-- SupplierProduct Services -->
+    <service name="createSupplierProduct" default-entity-name="SupplierProduct" engine="simple"
+        location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="createSupplierProduct" auth="true">
+        <description>Create a new SupplierProduct record</description>
+        <required-permissions join-type="AND">
+            <check-permission permission="CATALOG" action="_CREATE"/>
+        </required-permissions>
+        <auto-attributes mode="IN" include="pk" optional="false"/>
+        <auto-attributes mode="IN" include="nonpk" optional="true"/>
+        <override name="supplierProductId" optional="false"/>
+        <override name="lastPrice" optional="false"/>
+    </service>
+    <service name="updateSupplierProduct" default-entity-name="SupplierProduct" engine="simple"
+        location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="updateSupplierProduct" auth="true">
+        <description>Update a SupplierProduct record</description>
+        <required-permissions join-type="AND">
+            <check-permission permission="CATALOG" action="_UPDATE"/>
+        </required-permissions>
+        <auto-attributes mode="IN" include="pk" optional="false"/>
+        <auto-attributes mode="IN" include="nonpk" optional="true"/>
+    </service>
+    <service name="removeSupplierProduct" default-entity-name="SupplierProduct" engine="simple"
+        location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="removeSupplierProduct" auth="true">
+        <description>Remove a SupplierProduct record</description>
+        <required-permissions join-type="AND">
+            <check-permission permission="CATALOG" action="_DELETE"/>
+        </required-permissions>
+        <auto-attributes mode="IN" include="pk" optional="false"/>
+    </service>
+    
+    <!-- supplier product feature services -->
+    <service name="createSupplierProductFeature" default-entity-name="SupplierProductFeature" engine="simple"
+        location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="createSupplierProductFeature" auth="true">
+        <description>Create a new SupplierProductFeature record</description>
+        <required-permissions join-type="AND">
+            <check-permission permission="CATALOG" action="_CREATE"/>
+        </required-permissions>
+        <auto-attributes mode="IN" include="pk" optional="false"/>
+        <auto-attributes mode="IN" include="nonpk" optional="true"/>
+    </service>
+    <service name="updateSupplierProductFeature" default-entity-name="SupplierProductFeature" engine="simple"
+        location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="updateSupplierProductFeature" auth="true">
+        <description>Update a SupplierProduct record</description>
+        <required-permissions join-type="AND">
+            <check-permission permission="CATALOG" action="_UPDATE"/>
+        </required-permissions>
+        <auto-attributes mode="IN" include="pk" optional="false"/>
+        <auto-attributes mode="IN" include="nonpk" optional="true"/>
+    </service>
+    <service name="removeSupplierProductFeature" default-entity-name="SupplierProductFeature" engine="simple"
+        location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="removeSupplierProductFeature" auth="true">
+        <description>Remove a SupplierProduct record</description>
+        <required-permissions join-type="AND">
+            <check-permission permission="CATALOG" action="_DELETE"/>
+        </required-permissions>
+        <auto-attributes mode="IN" include="pk" optional="false"/>
+    </service>
+    <service name="getSupplierProductFeatures" engine="simple"
+        location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="getSupplierProductFeatures">
+        <description>Finds a list of SupplierProductFeature entities based on the productFeatureId.
+            If a partyId is given, only product feature information for that supplier party is returned.</description>
+        <attribute name="productFeatureId" type="String" mode="IN" optional="false"/>
+        <attribute name="partyId" type="String" mode="IN" optional="true"/>
+        <attribute name="supplierProductFeatures" type="java.util.List" mode="OUT" optional="false"/>
+    </service>
+    
+    <service name="createProductMaint" default-entity-name="ProductMaint" engine="simple"
+        location="org/ofbiz/product/product/ProductServices.xml" invoke="createProductMaint" auth="true">
+        <description>Create a ProductMaint</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <override name="productMaintSeqId" mode="OUT"/> <!-- make this OUT rather than IN, we will automatically generate the next sub-sequence ID -->        
+    </service>
+    <service name="updateProductMaint" default-entity-name="ProductMaint" engine="simple"
+        location="org/ofbiz/product/product/ProductServices.xml" invoke="updateProductMaint" auth="true">
+        <description>Update a ProductMaint</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+    </service>
+    <service name="deleteProductMaint" default-entity-name="ProductMaint" engine="simple"
+        location="org/ofbiz/product/product/ProductServices.xml" invoke="deleteProductMaint" auth="true">
+        <description>Delete a ProductMaint</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+    </service>
+    <service name="createProductMeter" default-entity-name="ProductMeter" engine="simple"
+        location="org/ofbiz/product/product/ProductServices.xml" invoke="createProductMeter" auth="true">
+        <description>Create a ProductMeter</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+    </service>
+    <service name="updateProductMeter" default-entity-name="ProductMeter" engine="simple"
+        location="org/ofbiz/product/product/ProductServices.xml" invoke="updateProductMeter" auth="true">
+        <description>Update a ProductMeter</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+    </service>
+    <service name="deleteProductMeter" default-entity-name="ProductMeter" engine="simple"
+        location="org/ofbiz/product/product/ProductServices.xml" invoke="deleteProductMeter" auth="true">
+        <description>Delete a ProductMeter</description>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+    </service>
+    <service name="createCommunicationEventProduct" engine="simple"
+        location="org/ofbiz/product/communication/CommunicationEventServices.xml" invoke="createCommunicationEventProduct" auth="true">
+        <description>Create a Communication Event Product</description>
+        <auto-attributes entity-name="CommunicationEventProduct" include="pk" mode="IN" optional="false"/>
+    </service>
+    <service name="removeCommunicationEventProduct" engine="simple"
+        location="org/ofbiz/product/communication/CommunicationEventServices.xml" invoke="removeCommunicationEventProduct" auth="true">
+        <description>Remove a Communication Event Product</description>
+        <auto-attributes entity-name="CommunicationEventProduct" include="pk" mode="IN" optional="false"/>
+    </service>
+
+    <!-- ======================================== -->
     <!-- Product Catalog Services -->
+    <!-- ======================================== -->
     <service name="createProdCatalog" default-entity-name="ProdCatalog" engine="simple"
                 location="org/ofbiz/product/catalog/CatalogServices.xml" invoke="createProdCatalog" auth="true">
         <description>Create a ProdCatalog</description>
@@ -346,7 +542,9 @@
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
 
+    <!-- ======================================== -->
     <!-- Product Category Services -->
+    <!-- ======================================== -->
     <service name="createProductCategory" default-entity-name="ProductCategory" engine="simple"
                 location="org/ofbiz/product/category/CategoryServices.xml" invoke="createProductCategory" auth="true">
         <description>Create an ProductCategory</description>
@@ -523,95 +721,42 @@
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
     
-    <service name="duplicateCategoryEntities" engine="simple"
-                location="org/ofbiz/product/category/CategoryServices.xml" invoke="duplicateCategoryEntities" auth="true">
-        <description>Duplicates a named entity from one productCategoryId to another</description>
-        <attribute name="productCategoryId" type="String" mode="IN" optional="false"/>
-        <attribute name="productCategoryIdTo" type="String" mode="IN" optional="false"/>
-        <attribute name="entityName" type="String" mode="IN" optional="false"/>
-        <attribute name="validDate" type="Timestamp" mode="IN" optional="true"/>
-    </service>
-
-
-    <!-- Product content services -->
-    <service name="createProductContent" default-entity-name="ProductContent" engine="simple"
-                location="org/ofbiz/product/product/ProductContentServices.xml" invoke="createProductContent" auth="true">
-        <description>Add Content To Product</description>
-        <auto-attributes include="pk" mode="INOUT" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <auto-attributes entity-name="Content" include="nonpk" mode="IN" optional="true"/>
-        <override name="fromDate" optional="true" />
-        <!--<override name="contentId" optional="true" mode="INOUT" />-->
-    </service>
-    <service name="updateProductContent" default-entity-name="ProductContent" engine="simple"
-                location="org/ofbiz/product/product/ProductContentServices.xml" invoke="updateProductContent" auth="true">
-        <description>Update Content To Product</description>
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <auto-attributes entity-name="Content" include="nonpk" mode="IN" optional="true"/>
-    </service>
-    <service name="removeProductContent" default-entity-name="ProductContent" engine="simple"
-                location="org/ofbiz/product/product/ProductContentServices.xml" invoke="removeProductContent" auth="true">
-        <description>Remove Content From Product</description>
+    <!-- Product Category Link Services --> 
+    <service name="createProductCategoryLink" default-entity-name="ProductCategoryLink" engine="simple"
+            location="org/ofbiz/product/category/CategoryServices.xml" 
+            invoke="createProductCategoryLink" auth="true">
+        <description>Create a ProductCategoryLink</description>
+        <permission-service service-name="checkCategoryRelatedPermissionService" main-action="CREATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <override name="fromDate" optional="true" />        
+        <override name="linkSeqId" optional="true" />        
     </service>
-    <service name="createEmailContentForProduct" default-entity-name="ProductContent" engine="simple"
-            location="org/ofbiz/product/product/ProductContentServices.xml" invoke="createEmailContentForProduct" auth="true">
+    <service name="updateProductCategoryLink" default-entity-name="ProductCategoryLink" engine="simple"
+            location="org/ofbiz/product/category/CategoryServices.xml" 
+            invoke="updateProductCategoryLink" auth="true">
+        <description>Update a ProductCategoryLink</description>
+        <permission-service service-name="checkCategoryRelatedPermissionService" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <auto-attributes mode="IN" entity-name="Content" optional="true"/>
-        <attribute name="subject" type="String" mode="IN" optional="false"/>
-        <attribute name="plainBody" type="String" mode="IN" optional="false"/>
-        <attribute name="htmlBody" type="String" mode="IN" optional="true"/>
-        <override name="contentId" optional="true" mode="INOUT"/>
     </service>
-    <service name="updateEmailContentForProduct" default-entity-name="ProductContent" engine="simple"
-            location="org/ofbiz/product/product/ProductContentServices.xml" invoke="updateEmailContentForProduct" auth="true">
+    <service name="deleteProductCategoryLink" default-entity-name="ProductCategoryLink" engine="simple"
+            location="org/ofbiz/product/category/CategoryServices.xml" 
+            invoke="deleteProductCategoryLink" auth="true">
+        <description>Delete a ProductCategoryLink</description>
+        <permission-service service-name="checkCategoryRelatedPermissionService" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <auto-attributes entity-name="Content" include="nonpk" mode="IN" optional="true"/>
-        <attribute name="subjectDataResourceId" type="String" mode="IN" optional="true"/>
-        <attribute name="subject" type="String" mode="IN" optional="true"/>
-        <attribute name="plainBodyDataResourceId" type="String" mode="IN" optional="true"/>
-        <attribute name="plainBody" type="String" mode="IN" optional="true"/>
-        <attribute name="htmlBodyDataResourceId" type="String" mode="IN" optional="true"/>
-        <attribute name="htmlBody" type="String" mode="IN" optional="true"/>
     </service>
-    <service name="createDownloadContentForProduct" default-entity-name="ProductContent" engine="simple"
-            location="org/ofbiz/product/product/ProductContentServices.xml" invoke="createDownloadContentForProduct" auth="true">
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <auto-attributes mode="IN" entity-name="Content" optional="true"/>
-        <attribute name="file" type="String" mode="IN" optional="false"/>
-        <override name="contentId" optional="true"/>
-    </service>
-    <service name="updateDownloadContentForProduct" default-entity-name="ProductContent" engine="simple"
-            location="org/ofbiz/product/product/ProductContentServices.xml" invoke="updateDownloadContentForProduct" auth="true">
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <auto-attributes mode="IN" entity-name="Content" optional="true"/>
-        <attribute name="fileDataResourceId" type="String" mode="IN" optional="true"/>
-        <attribute name="file" type="String" mode="IN" optional="true"/>
+    
+    <service name="duplicateCategoryEntities" engine="simple"
+                location="org/ofbiz/product/category/CategoryServices.xml" invoke="duplicateCategoryEntities" auth="true">
+        <description>Duplicates a named entity from one productCategoryId to another</description>
+        <attribute name="productCategoryId" type="String" mode="IN" optional="false"/>
+        <attribute name="productCategoryIdTo" type="String" mode="IN" optional="false"/>
+        <attribute name="entityName" type="String" mode="IN" optional="false"/>
+        <attribute name="validDate" type="Timestamp" mode="IN" optional="true"/>
     </service>
 
-    <service name="createSimpleTextContentForProduct" default-entity-name="ProductContent" engine="simple"
-            location="org/ofbiz/product/product/ProductContentServices.xml" invoke="createSimpleTextContentForProduct" auth="true">
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <auto-attributes entity-name="Content" include="nonpk" mode="IN" optional="true"/>
-        <attribute name="text" type="String" mode="IN" optional="false"/>
-        <override name="contentId" optional="true"/>
-        <override name="fromDate" optional="true"/>
-    </service>
-    <service name="updateSimpleTextContentForProduct" default-entity-name="ProductContent" engine="simple"
-            location="org/ofbiz/product/product/ProductContentServices.xml" invoke="updateSimpleTextContentForProduct" auth="true">
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <auto-attributes mode="IN" entity-name="Content" optional="true"/>
-        <attribute name="textDataResourceId" type="String" mode="IN" optional="true"/>
-        <attribute name="text" type="String" mode="IN" optional="true"/>
-    </service>
 
     <!-- Category content services -->
     <service name="createCategoryContent" default-entity-name="ProductCategoryContent" engine="simple"
@@ -667,72 +812,6 @@
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
 
-    <!-- SupplierProduct Services -->
-    <service name="createSupplierProduct" default-entity-name="SupplierProduct" engine="simple"
-            location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="createSupplierProduct" auth="true">
-        <description>Create a new SupplierProduct record</description>
-        <required-permissions join-type="AND">
-            <check-permission permission="CATALOG" action="_CREATE"/>
-        </required-permissions>
-        <auto-attributes mode="IN" include="pk" optional="false"/>
-        <auto-attributes mode="IN" include="nonpk" optional="true"/>
-        <override name="supplierProductId" optional="false"/>
-        <override name="lastPrice" optional="false"/>
-    </service>
-    <service name="updateSupplierProduct" default-entity-name="SupplierProduct" engine="simple"
-            location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="updateSupplierProduct" auth="true">
-        <description>Update a SupplierProduct record</description>
-        <required-permissions join-type="AND">
-            <check-permission permission="CATALOG" action="_UPDATE"/>
-        </required-permissions>
-        <auto-attributes mode="IN" include="pk" optional="false"/>
-        <auto-attributes mode="IN" include="nonpk" optional="true"/>
-    </service>
-    <service name="removeSupplierProduct" default-entity-name="SupplierProduct" engine="simple"
-            location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="removeSupplierProduct" auth="true">
-        <description>Remove a SupplierProduct record</description>
-        <required-permissions join-type="AND">
-            <check-permission permission="CATALOG" action="_DELETE"/>
-        </required-permissions>
-        <auto-attributes mode="IN" include="pk" optional="false"/>
-    </service>
-
-    <!-- supplier product feature services -->
-    <service name="createSupplierProductFeature" default-entity-name="SupplierProductFeature" engine="simple"
-            location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="createSupplierProductFeature" auth="true">
-        <description>Create a new SupplierProductFeature record</description>
-        <required-permissions join-type="AND">
-            <check-permission permission="CATALOG" action="_CREATE"/>
-        </required-permissions>
-        <auto-attributes mode="IN" include="pk" optional="false"/>
-        <auto-attributes mode="IN" include="nonpk" optional="true"/>
-    </service>
-    <service name="updateSupplierProductFeature" default-entity-name="SupplierProductFeature" engine="simple"
-            location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="updateSupplierProductFeature" auth="true">
-        <description>Update a SupplierProduct record</description>
-        <required-permissions join-type="AND">
-            <check-permission permission="CATALOG" action="_UPDATE"/>
-        </required-permissions>
-        <auto-attributes mode="IN" include="pk" optional="false"/>
-        <auto-attributes mode="IN" include="nonpk" optional="true"/>
-    </service>
-    <service name="removeSupplierProductFeature" default-entity-name="SupplierProductFeature" engine="simple"
-            location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="removeSupplierProductFeature" auth="true">
-        <description>Remove a SupplierProduct record</description>
-        <required-permissions join-type="AND">
-            <check-permission permission="CATALOG" action="_DELETE"/>
-        </required-permissions>
-        <auto-attributes mode="IN" include="pk" optional="false"/>
-    </service>
-    <service name="getSupplierProductFeatures" engine="simple"
-            location="org/ofbiz/product/supplier/SupplierProductServices.xml" invoke="getSupplierProductFeatures">
-        <description>Finds a list of SupplierProductFeature entities based on the productFeatureId.
-        If a partyId is given, only product feature information for that supplier party is returned.</description>
-        <attribute name="productFeatureId" type="String" mode="IN" optional="false"/>
-        <attribute name="partyId" type="String" mode="IN" optional="true"/>
-        <attribute name="supplierProductFeatures" type="java.util.List" mode="OUT" optional="false"/>
-    </service>
-    
     <!-- Customer driven (customers are suppliers) digital download product services -->
     <service name="createCustomerDigitalDownloadProduct" auth="true" engine="simple"
         location="org/ofbiz/product/product/CustomerDigitalDownloadServices.xml" invoke="createCustomerDigitalDownloadProduct">
@@ -949,57 +1028,16 @@
         </description>
         <attribute type="String" mode="IN" name="inventoryItemId" optional="false"/>
     </service>
-    <service name="createProductMaint" default-entity-name="ProductMaint" engine="simple"
-                location="org/ofbiz/product/product/ProductServices.xml" invoke="createProductMaint" auth="true">
-        <description>Create a ProductMaint</description>
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <override name="productMaintSeqId" mode="OUT"/> <!-- make this OUT rather than IN, we will automatically generate the next sub-sequence ID -->        
-    </service>
-    <service name="updateProductMaint" default-entity-name="ProductMaint" engine="simple"
-                location="org/ofbiz/product/product/ProductServices.xml" invoke="updateProductMaint" auth="true">
-        <description>Update a ProductMaint</description>
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-    </service>
-    <service name="deleteProductMaint" default-entity-name="ProductMaint" engine="simple"
-                location="org/ofbiz/product/product/ProductServices.xml" invoke="deleteProductMaint" auth="true">
-        <description>Delete a ProductMaint</description>
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-    </service>
-    <service name="createProductMeter" default-entity-name="ProductMeter" engine="simple"
-                location="org/ofbiz/product/product/ProductServices.xml" invoke="createProductMeter" auth="true">
-        <description>Create a ProductMeter</description>
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-    </service>
-    <service name="updateProductMeter" default-entity-name="ProductMeter" engine="simple"
-                location="org/ofbiz/product/product/ProductServices.xml" invoke="updateProductMeter" auth="true">
-        <description>Update a ProductMeter</description>
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-        <auto-attributes include="nonpk" mode="IN" optional="true"/>
-    </service>
-    <service name="deleteProductMeter" default-entity-name="ProductMeter" engine="simple"
-                location="org/ofbiz/product/product/ProductServices.xml" invoke="deleteProductMeter" auth="true">
-        <description>Delete a ProductMeter</description>
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-    </service>
-    <service name="createCommunicationEventProduct" engine="simple"
-            location="org/ofbiz/product/communication/CommunicationEventServices.xml" invoke="createCommunicationEventProduct" auth="true">
-        <description>Create a Communication Event Product</description>
-        <auto-attributes entity-name="CommunicationEventProduct" include="pk" mode="IN" optional="false"/>
-    </service>
-    <service name="removeCommunicationEventProduct" engine="simple"
-            location="org/ofbiz/product/communication/CommunicationEventServices.xml" invoke="removeCommunicationEventProduct" auth="true">
-        <description>Remove a Communication Event Product</description>
-        <auto-attributes entity-name="CommunicationEventProduct" include="pk" mode="IN" optional="false"/>
-    </service>
     
     <!-- Permission Services -->    
+    <service name="productGenericPermission" engine="simple"
+        location="org/ofbiz/product/product/ProductServices.xml" invoke="productGenericPermission">
+        <implements service="permissionInterface"/>
+    </service>
     <service name="checkCategoryRelatedPermissionService" engine="simple"
              location="org/ofbiz/product/category/CategoryServices.xml" invoke="checkCategoryRelatedPermissionService">
         <implements service="permissionInterface"/>
-         <attribute type="String" mode="IN" name="productCategoryId" optional="true"/>
-         <attribute type="List" mode="IN" name="categories" optional="true"/>
+        <attribute type="String" mode="IN" name="productCategoryId" optional="true"/>
+        <attribute type="List" mode="IN" name="categories" optional="true"/>
     </service>
 </services>

Modified: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml?view=diff&rev=507431&r1=507430&r2=507431
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml Wed Feb 14 00:05:53 2007
@@ -720,6 +720,30 @@
         <response name="error" type="view" value="EditCategoryAttributes"/>
     </request-map>
 
+    <!-- ================ Product Category Link Requests ================= -->
+    <request-map uri="EditProductCategoryLinks">
+        <security https="true" auth="true"/>
+        <response name="success" type="view" value="EditProductCategoryLinks"/>
+    </request-map>
+    <request-map uri="createProductCategoryLink">
+        <security https="true" auth="true"/>
+        <event type="service" path="" invoke="createProductCategoryLink"/>
+        <response name="success" type="view" value="EditProductCategoryLinks"/>
+        <response name="error" type="view" value="EditProductCategoryLinks"/>
+    </request-map>
+    <request-map uri="updateProductCategoryLink">
+        <security https="true" auth="true"/>
+        <event type="service" path="" invoke="updateProductCategoryLink"/>
+        <response name="success" type="view" value="EditProductCategoryLinks"/>
+        <response name="error" type="view" value="EditProductCategoryLinks"/>
+    </request-map>
+    <request-map uri="deleteProductCategoryLink">
+        <security https="true" auth="true"/>
+        <event type="service" path="" invoke="deleteProductCategoryLink"/>
+        <response name="success" type="view" value="EditProductCategoryLinks"/>
+        <response name="error" type="view" value="EditProductCategoryLinks"/>
+    </request-map>
+    
     <!-- ================ Product Keyword Requests ================= -->
     <request-map uri="EditProductKeyword">
         <security https="true" auth="true"/>
@@ -2283,6 +2307,7 @@
     <view-map name="EditCategoryProdCatalogs" type="screen" page="component://product/widget/catalog/CategoryScreens.xml#EditCategoryProdCatalogs"/>
     <view-map name="EditCategoryFeatureCats" type="screen" page="component://product/widget/catalog/CategoryScreens.xml#EditCategoryFeatureCats"/>
     <view-map name="EditCategoryParties" type="screen" page="component://product/widget/catalog/CategoryScreens.xml#EditCategoryParties"/>
+    <view-map name="EditProductCategoryLinks" type="screen" page="component://product/widget/catalog/CategoryScreens.xml#EditProductCategoryLinks"/>
 
     <view-map name="createProductInCategoryStart" type="screen" page="component://product/widget/catalog/CategoryScreens.xml#createProductInCategoryStart"/>
     <view-map name="createProductInCategoryCheckExisting" type="screen" page="component://product/widget/catalog/CategoryScreens.xml#createProductInCategoryCheckExisting"/>

Modified: ofbiz/trunk/applications/product/webapp/catalog/category/CategoryForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/category/CategoryForms.xml?view=diff&rev=507431&r1=507430&r2=507431
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/category/CategoryForms.xml (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/category/CategoryForms.xml Wed Feb 14 00:05:53 2007
@@ -119,4 +119,63 @@
         <field use-when="content == null" name="submitButton" title="${uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button-type="button"/></field>
         <field use-when="content != null" name="submitButton" title="${uiLabelMap.CommonUpdate}" widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
+    
+    <!-- ProductCategoryLink Forms-->
+    <form name="ListProductCategoryLinks" type="list"  list-name="productCategoryLinks"  target="updateProductCategoryLink"
+            default-title-style="tableheadtext" default-widget-style="inputBox" default-tooltip-style="tabletext" separate-columns="true">
+        <actions>
+            <entity-condition entity-name="ProductCategoryLink">
+                <condition-expr field-name="productCategoryId" env-name="productCategoryId"/>
+                <order-by field-name="sequenceNum"/>
+            </entity-condition>
+        </actions>
+        <auto-fields-service service-name="updateProductCategoryLink"/>
+        
+        <field name="productCategoryId"><hidden/></field>
+        <field name="linkSeqId" widget-style="tabletext"><display/></field>
+        <field name="fromDate" title="${uiLabelMap.CommonFromDate}" widget-style="tabletext"><display/></field>
+        <field name="thruDate" title="${uiLabelMap.CommonThruDate}"><date-time/></field>
+        <field name="titleText"><text size="20" maxlength="250"/></field>
+        <field name="comments"><text size="20" maxlength="250"/></field>
+        <field name="sequenceNum" title="${uiLabelMap.CommonSequence}"><text maxlength="5" size="5"/></field>
+        <field name="linkTypeEnumId"><ignored/></field>
+        <field name="detailText"><ignored/></field>
+        <field name="linkInfo"><ignored/></field>
+        <field name="detailSubScreen"><ignored/></field>
+        <field name="imageUrl"><ignored/></field>        
+        <field name="deleteLink" title="" widget-style="buttontext">
+            <hyperlink target="deleteProductCategoryLink?productCategoryId=${productCategoryId}&amp;linkSeqId=${linkSeqId}&amp;fromDate=${fromDate}"
+                description="${uiLabelMap.CommonDelete}" also-hidden="false"/>
+        </field>
+        <field name="submitButton" title="${uiLabelMap.CommonUpdate}" widget-style="smallSubmit"><submit button-type="button"/></field>
+    </form>
+    <form name="AddProductCategoryLink" type="single" target="createProductCategoryLink" title="" default-map-name="productCategoryLink"
+            default-title-style="tableheadtext" default-widget-style="inputBox" default-tooltip-style="tabletext">
+        <alt-target use-when="productCategoryLink != null" target="updateProductCategoryLink"/>
+        <auto-fields-service service-name="createProductCategoryLink"/>
+        <field name="productCategoryId"><hidden/></field>
+        <field name="linkSeqId" use-when="productCategoryLink==null"><ignored/></field>
+        <field name="linkSeqId" use-when="productCategoryLink!=null" widget-style="tabletext"><display/></field>
+        <field use-when="productCategoryLink != null" name="fromDate" tooltip="${uiLabelMap.CommonNotModifRecreat}" widget-style="tabletext"><display/></field>
+        <field use-when="productCategoryLink == null" name="fromDate" title="${uiLabelMap.CommonFromDate}"><date-time/></field>
+        <field name="thruDate" title="${uiLabelMap.CommonThruDate}"><date-time/></field>
+        <field name="sequenceNum" title="${uiLabelMap.CommonSequence}"><text maxlength="5" size="5"/></field>
+        <field name="imageUrl" tooltip="example: /images/categories/linkOne/100.jpg"><text size="60" maxlength="255"/></field>        
+        <field name="linkTypeEnumId" title="${uiLabelMap.ProductLinkTypeEnumId}">
+            <drop-down allow-empty = "false">
+                <entity-options description="${description}" entity-name="Enumeration" key-field-name="enumId">
+                    <entity-constraint name="enumId" operator="equals" value="PCLT_SEARCH_PARAM"/>
+                    <entity-order-by field-name="description"/>
+                </entity-options>
+                <entity-options description="${description}" entity-name="Enumeration" key-field-name="enumId">
+                    <entity-constraint name="enumId" operator="equals" value="PCLT_ABS_URL"/>
+                    <entity-order-by field-name="description"/>
+                </entity-options>
+            </drop-down>
+        </field>
+        <field name="detailSubScreen" tooltip="example: component://ecommerce/widget/CatalogScreens.xml#categorydetail"><text size="60" maxlength="255"/></field>
+        <field name="submitButton" use-when="productCategoryLink==null" title="${uiLabelMap.CommonAdd}" widget-style="smallSubmit"><submit button-type="button"/></field>
+        <field name="submitButton" use-when="productCategoryLink!=null" title="${uiLabelMap.CommonUpdate}" widget-style="smallSubmit"><submit button-type="button"/></field>
+        <field name="clearFormButton" title="" use-when="productCategoryLink!=null" widget-style="buttontext"><hyperlink target="EditProductCategoryLinks?productCategoryId=${productCategoryId}" target-type="intra-app" description="Clear Form"/></field>
+    </form>
 </forms>

Modified: ofbiz/trunk/applications/product/webapp/catalog/category/CategoryTabBar.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/category/CategoryTabBar.ftl?view=diff&rev=507431&r1=507430&r2=507431
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/category/CategoryTabBar.ftl (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/category/CategoryTabBar.ftl Wed Feb 14 00:05:53 2007
@@ -30,4 +30,6 @@
         <a href="<@o...@ofbizUrl>" class="${selectedClassMap.EditCategoryFeatureCats?default(unselectedClassName)}">${uiLabelMap.ProductFeatureCats}</a>
         <a href="<@o...@ofbizUrl>" class="${selectedClassMap.EditCategoryParties?default(unselectedClassName)}">${uiLabelMap.PartyParties}</a>
         <a href="<@o...@ofbizUrl>" class="${selectedClassMap.EditCategoryAttributes?default(unselectedClassName)}">${uiLabelMap.ProductAttributes}</a>
+        <a href="<@o...@ofbizUrl>" class="${selectedClassMap.EditProductCategoryLinks?default(unselectedClassName)}">${uiLabelMap.ProductCategoryLinks}</a>
     </div>
+    

Modified: ofbiz/trunk/applications/product/widget/catalog/CategoryScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/widget/catalog/CategoryScreens.xml?view=diff&rev=507431&r1=507430&r2=507431
==============================================================================
--- ofbiz/trunk/applications/product/widget/catalog/CategoryScreens.xml (original)
+++ ofbiz/trunk/applications/product/widget/catalog/CategoryScreens.xml Wed Feb 14 00:05:53 2007
@@ -387,4 +387,30 @@
             </widgets>
         </section>
     </screen>
+    
+    <!-- ProductCategoryLinks Screen -->
+    <screen name="EditProductCategoryLinks">
+        <section>
+            <actions>
+                <set field="titleProperty" value="PageTitleEditProductCategoryLink"/>
+                <set field="headerItem" value="category"/>
+                <set field="tabButtonItem" value="EditProductCategoryLinks"/>
+                <set field="labelTitleProperty" value="ProductCategoryLinks"/>
+
+                <set field="productCategoryId" from-field="parameters.productCategoryId"/>
+                <set field="linkSeqId" from-field="parameters.linkSeqId"/>
+                <set field="fromDate" from-field="parameters.fromDate" type="Timestamp"/>
+                <entity-one entity-name="ProductCategoryLink" value-name="productCategoryLink"/>
+            </actions>
+            <widgets>
+                <decorator-screen name="CommonCategoryDecorator">
+                    <decorator-section name="body">
+                        <include-form name="ListProductCategoryLinks" location="component://product/webapp/catalog/category/CategoryForms.xml"/>
+                        <include-form name="AddProductCategoryLink" location="component://product/webapp/catalog/category/CategoryForms.xml"/>
+                    </decorator-section>
+                </decorator-screen>
+            </widgets>
+        </section>
+    </screen>
+    
 </screens>