blob: 1eadf7861c3214a62764f344626b023b6a26f58a [file] [log] [blame]
<?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-v2.xsd">
<!-- ================================================================ -->
<!-- ProductCategory Services -->
<!-- ================================================================ -->
<simple-method method-name="createProductCategory" short-description="Create an ProductCategory">
<check-permission permission="CATALOG" action="_CREATE">
<alt-permission permission="CATALOG_ROLE" action="_CREATE"/>
<fail-property resource="ProductUiLabels" property="ProductCatalogCreatePermissionError"/>
</check-permission>
<check-errors/>
<now-timestamp field="nowTimestamp"/>
<make-value value-field="newEntity" entity-name="ProductCategory"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="parameters.productCategoryId">
<sequenced-id sequence-name="ProductCategory" field="newEntity.productCategoryId"/>
<else>
<set field="newEntity.productCategoryId" from-field="parameters.productCategoryId"/>
<check-id field="newEntity.productCategoryId"/>
<check-errors/>
</else>
</if-empty>
<field-to-result field="newEntity.productCategoryId" result-name="productCategoryId"/>
<create-value value-field="newEntity"/>
<!-- if setting the primaryParentCategoryId, create a rollup entity too -->
<!-- NOTE: this is commented out to disable because it is dangerous to add category rollups on a live site without being able to specify a fromDate
<if-not-empty field="newEntity.primaryParentCategoryId">
<make-value entity-name="ProductCategoryRollup" value-field="newRollup"/>
<field-to-field field-name="productCategoryId" map-name="newEntity" to-field-name="productCategoryId" to-map-name="newRollup"/>
<field-to-field field-name="primaryParentCategoryId" map-name="newEntity" to-field-name="parentProductCategoryId" to-map-name="newRollup"/>
<env-to-field env-name="nowTimestamp" field-name="fromDate" map-name="newRollup"/>
<create-value value-field="newRollup"/>
</if-not-empty>
-->
<!-- if the user has the role limited position, add this category to the limit category/ies -->
<if-has-permission permission="CATALOG_ROLE" action="_CREATE">
<entity-and entity-name="ProductCategoryRole" list="productCategoryRoles" filter-by-date="true">
<field-map field-name="partyId" from-field="userLogin.partyId"/>
<field-map field-name="roleTypeId" value="LTD_ADMIN"/>
</entity-and>
<iterate entry="productCategoryRole" list="productCategoryRoles">
<!-- add this new product to the category -->
<make-value value-field="newLimitRollup" entity-name="ProductCategoryRollup"/>
<set field="newLimitRollup.productCategoryId" from-field="newEntity.productCategoryId"/>
<set field="newLimitRollup.parentProductCategoryId" from-field="productCategoryRole.productCategoryId"/>
<set field="newLimitRollup.fromDate" from-field="nowTimestamp"/>
<create-value value-field="newLimitRollup"/>
</iterate>
</if-has-permission>
</simple-method>
<simple-method method-name="updateProductCategory" short-description="Update an ProductCategory">
<set field="callingMethodName" value="updateProductCategory"/>
<set field="checkAction" value="UPDATE"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<entity-one entity-name="ProductCategory" value-field="lookedUpValue"/>
<!-- save this value before overwriting it so we can compare it later -->
<!-- <field-to-field field-name="primaryParentCategoryId" map-name="lookedUpValue" to-map-name="saveIdMap"/> -->
<set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
<store-value value-field="lookedUpValue"/>
<!-- if setting the primaryParentCategoryId, create a rollup entity too -->
<!-- NOTE: this is commented out to disable because it is dangerous to add category rollups on a live site without being able to specify a fromDate
<if-not-empty field="lookedUpValue.primaryParentCategoryId">
<if-compare-field to-field="saveIdMap.primaryParentCategoryId" field="lookedUpValue.primaryParentCategoryId" operator="not-equals">
<make-value entity-name="ProductCategoryRollup" value-field="newRollup"/>
<field-to-field field-name="productCategoryId" map-name="lookedUpValue" to-field-name="productCategoryId" to-map-name="newRollup"/>
<field-to-field field-name="primaryParentCategoryId" map-name="lookedUpValue" to-field-name="parentProductCategoryId" to-map-name="newRollup"/>
<now-timestamp field="nowTimestamp"/>
<env-to-field env-name="nowTimestamp" field-name="fromDate" map-name="newRollup"/>
<create-value value-field="newRollup"/>
</if-compare-field>
</if-not-empty>
-->
</simple-method>
<!-- ================================================================ -->
<!-- ProductCategoryMember Services -->
<!-- ================================================================ -->
<simple-method method-name="addProductToCategory" short-description="Add Product to Category">
<!-- note that the security semantics require the user to have the general admin permission,
or the role limited permission and association with the category, not the product -->
<!--
<set value="addProductToCategory" field="callingMethodName"/>
<set value="CREATE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
-->
<make-value value-field="newEntity" entity-name="ProductCategoryMember"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="newEntity.fromDate"/>
</if-empty>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="addProductToCategories" short-description="Add Product to Multiple Categories">
<if-instance-of field="parameters.categories" class="java.util.List">
<iterate entry="category" list="parameters.categories">
<!-- note that the security semantics require the user to have the general admin permission,
or the role limited permission and association with the category, not the product -->
<!--
<set field="productCategoryIdToCheck" from-field="category"/>
<set field="callingMethodName" value="addProductToCategories"/>
<set field="checkAction" value="CREATE"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
-->
<make-value value-field="newEntity" entity-name="ProductCategoryMember"/>
<set field="newEntity.productCategoryId" from-field="category"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="newEntity.fromDate"/>
</if-empty>
<create-value value-field="newEntity"/>
</iterate>
<else>
<!-- note that the security semantics require the user to have the general admin permission,
or the role limited permission and association with the category, not the product -->
<set from-field="parameters.categories" field="productCategoryIdToCheck"/>
<set field="callingMethodName" value="addProductToCategories"/>
<set field="checkAction" value="CREATE"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="newEntity" entity-name="ProductCategoryMember"/>
<set field="newEntity.productCategoryId" from-field="parameters.categories"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="newEntity.fromDate"/>
</if-empty>
<create-value value-field="newEntity"/>
</else>
</if-instance-of>
</simple-method>
<simple-method method-name="updateProductToCategory" short-description="Update Product to Category Application">
<!-- note that the security semantics require the user to have the general admin permission,
or the role limited permission and association with the category, not the product -->
<!--
<set value="updateProductToCategory" field="callingMethodName"/>
<set value="UPDATE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
-->
<make-value value-field="lookupPKMap" entity-name="ProductCategoryMember"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ProductCategoryMember" map="lookupPKMap" value-field="lookedUpValue"/>
<set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
<store-value value-field="lookedUpValue"/>
</simple-method>
<simple-method method-name="removeProductFromCategory" short-description="Remove Product From Category">
<!-- note that the security semantics require the user to have the general admin permission,
or the role limited permission and association with the category, not the product -->
<!--
<set value="removeProductFromCategory" field="callingMethodName"/>
<set value="DELETE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
-->
<!-- If the associated category was the primary category for the product, clear that field -->
<entity-one entity-name="Product" value-field="product" auto-field-map="true"/>
<if-compare-field field="product.primaryProductCategoryId" to-field="parameters.productCategoryId" operator="equals">
<clear-field field="product.primaryProductCategoryId"/>
<store-value value-field="product"/>
</if-compare-field>
<make-value value-field="lookupPKMap" entity-name="ProductCategoryMember"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ProductCategoryMember" map="lookupPKMap" value-field="lookedUpValue"/>
<remove-value value-field="lookedUpValue"/>
</simple-method>
<!-- ================================================================ -->
<!-- ProductCategoryRole Services -->
<!-- ================================================================ -->
<simple-method method-name="addPartyToCategory" short-description="Add Party to Category">
<set value="addPartyToCategory" field="callingMethodName"/>
<set value="CREATE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="newEntity" entity-name="ProductCategoryRole"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="newEntity.fromDate"/>
</if-empty>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="updatePartyToCategory" short-description="Update Party to Category Application">
<set value="updatePartyToCategory" field="callingMethodName"/>
<set value="UPDATE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="lookupPKMap" entity-name="ProductCategoryRole"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ProductCategoryRole" map="lookupPKMap" value-field="lookedUpValue"/>
<set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
<store-value value-field="lookedUpValue"/>
</simple-method>
<simple-method method-name="removePartyFromCategory" short-description="Remove Party From Category">
<set value="removePartyFromCategory" field="callingMethodName"/>
<set value="DELETE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="lookupPKMap" entity-name="ProductCategoryRole"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ProductCategoryRole" map="lookupPKMap" value-field="lookedUpValue"/>
<remove-value value-field="lookedUpValue"/>
</simple-method>
<!-- ================================================================ -->
<!-- ProductCategoryRollup Services -->
<!-- ================================================================ -->
<simple-method method-name="addProductCategoryToCategory" short-description="Add ProductCategory to Category">
<set value="addProductCategoryToCategory" field="callingMethodName"/>
<set value="CREATE" field="checkAction"/>
<!-- note the the user must be associated with the parent category with the role limited permission -->
<set value="parentProductCategoryId" field="productCategoryIdName"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="newEntity" entity-name="ProductCategoryRollup"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="newEntity.fromDate"/>
</if-empty>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="addProductCategoryToCategories" short-description="Add ProductCategory to Categories">
<if-instance-of field="parameters.categories" class="java.util.List">
<iterate entry="category" list="parameters.categories">
<set field="callingMethodName" value="addProductCategoryToCategories"/>
<set field="checkAction" value="CREATE"/>
<!-- note the the user must be associated with the parent category with the role limited permission -->
<set field="productCategoryIdToCheck" from-field="category"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="newEntity" entity-name="ProductCategoryRollup"/>
<set field="newEntity.parentProductCategoryId" from-field="category"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="newEntity.fromDate"/>
</if-empty>
<create-value value-field="newEntity"/>
</iterate>
<else>
<set value="addProductCategoryToCategories" field="callingMethodName"/>
<set value="CREATE" field="checkAction"/>
<!-- note the the user must be associated with the parent category with the role limited permission -->
<set field="productCategoryIdToCheck" from-field="parameters.categories"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="newEntity" entity-name="ProductCategoryRollup"/>
<set field="newEntity.parentProductCategoryId" from-field="parameters.categories"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="newEntity.fromDate"/>
</if-empty>
<create-value value-field="newEntity"/>
</else>
</if-instance-of>
</simple-method>
<simple-method method-name="updateProductCategoryToCategory" short-description="Update ProductCategory to Category Application">
<set value="updateProductCategoryToCategory" field="callingMethodName"/>
<set value="UPDATE" field="checkAction"/>
<!-- note the the user must be associated with the parent category with the role limited permission -->
<set value="parentProductCategoryId" field="productCategoryIdName"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="lookupPKMap" entity-name="ProductCategoryRollup"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ProductCategoryRollup" map="lookupPKMap" value-field="lookedUpValue"/>
<set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
<store-value value-field="lookedUpValue"/>
<field-to-result field="parameters.productCategoryId" result-name="productCategoryId"/>
</simple-method>
<simple-method method-name="removeProductCategoryFromCategory" short-description="Remove ProductCategory From Category">
<set value="removeProductCategoryFromCategory" field="callingMethodName"/>
<set value="DELETE" field="checkAction"/>
<!-- note the the user must be associated with the parent category with the role limited permission -->
<set value="parentProductCategoryId" field="productCategoryIdName"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<make-value value-field="lookupPKMap" entity-name="ProductCategoryRollup"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ProductCategoryRollup" map="lookupPKMap" value-field="lookedUpValue"/>
<remove-value value-field="lookedUpValue"/>
</simple-method>
<!-- ================================================================ -->
<!-- Special Category Function Services -->
<!-- ================================================================ -->
<simple-method method-name="copyCategoryProductMembers" short-description="copy CategoryProduct Members to a CategoryProductTo">
<set value="copyCategoryProductMembers" field="callingMethodName"/>
<set value="CREATE" field="checkAction"/>
<!-- note the the user must be associated with the target category with the role limited permission -->
<set value="productCategoryIdTo" field="productCategoryIdName"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<entity-and entity-name="ProductCategoryMember" list="productCategoryMembers">
<field-map field-name="productCategoryId" from-field="parameters.productCategoryId"/>
</entity-and>
<set field="validDate" from-field="parameters.validDate"/>
<if-not-empty field="validDate">
<filter-list-by-date list="productCategoryMembers" valid-date="validDate"/>
</if-not-empty>
<!-- add each to a list to store and then store all and let the entity engine do inserts or updates as needed; much more reliable/useful -->
<iterate entry="productCategoryMember" list="productCategoryMembers">
<clone-value value-field="productCategoryMember" new-value-field="newProductCategoryMember"/>
<set field="newProductCategoryMember.productCategoryId" from-field="parameters.productCategoryIdTo"/>
<field-to-list field="newProductCategoryMember" list="pcmsToStore"/>
</iterate>
<store-list list="pcmsToStore"/>
<if-compare field="parameters.recurse" operator="equals" value="Y">
<!-- call this service for each sub-category in the rollup with the same productCategoryIdTo -->
<set field="lookupChildrenMap.parentProductCategoryId" from-field="parameters.productCategoryId"/>
<find-by-and entity-name="ProductCategoryRollup" map="lookupChildrenMap" list="productCategoryRollups"/>
<if-not-empty field="validDate">
<filter-list-by-date list="productCategoryRollups" valid-date="validDate"/>
</if-not-empty>
<iterate entry="productCategoryRollup" list="productCategoryRollups">
<set field="callServiceMap.productCategoryId" from-field="productCategoryRollup.productCategoryId"/>
<set field="callServiceMap.productCategoryIdTo" from-field="parameters.productCategoryIdTo"/>
<set field="callServiceMap.validDate" from-field="parameters.validDate"/>
<set field="callServiceMap.recurse" from-field="parameters.recurse"/>
<call-service service-name="copyCategoryProductMembers" in-map-name="callServiceMap"/>
</iterate>
</if-compare>
</simple-method>
<simple-method method-name="duplicateCategoryEntities" short-description="a service wrapper for copyCategoryEntities">
<set value="duplicateCategoryEntities" field="callingMethodName"/>
<check-permission permission="CATALOG" action="_CREATE">
<alt-permission permission="CATALOG_ROLE" action="_CREATE"/>
<fail-property resource="ProductUiLabels" property="ProductCatalogCreatePermissionError"/>
</check-permission>
<check-errors/>
<set field="entityName" from-field="parameters.entityName"/>
<set field="productCategoryId" from-field="parameters.productCategoryId"/>
<set field="productCategoryIdTo" from-field="parameters.productCategoryIdTo"/>
<set field="validDate" from-field="parameters.validDate"/>
<call-simple-method method-name="copyCategoryEntities"/>
</simple-method>
<simple-method method-name="copyCategoryEntities" short-description="copies all entities of entityName with a productCategoryId to a new entity with a productCategoryIdTo,
filtering them by a timestamp passed in to validDate if necessary">
<entity-and entity-name="${entityName}" list="categoryEntities">
<field-map field-name="productCategoryId" from-field="productCategoryId"/>
</entity-and>
<if-not-empty field="validDate">
<filter-list-by-date list="categoryEntities" valid-date="validDate"/>
</if-not-empty>
<!-- add each to a list to store and then store all and let the entity engine do inserts or updates as needed; much more reliable/useful -->
<iterate entry="categoryEntity" list="categoryEntities">
<clone-value value-field="categoryEntity" new-value-field="newCategoryEntity"/>
<set field="newCategoryEntity.productCategoryId" from-field="productCategoryIdTo"/>
<field-to-list field="newCategoryEntity" list="entitiesToStore"/>
</iterate>
<store-list list="entitiesToStore"/>
</simple-method>
<simple-method method-name="expireAllCategoryProductMembers" short-description="Remove ProductCategory From Category">
<set value="expireAllCategoryProductMembers" field="callingMethodName"/>
<set value="UPDATE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<if-not-empty field="parameters.thruDate">
<set field="expireTimestamp" from-field="parameters.thruDate"/>
<else>
<now-timestamp field="expireTimestamp"/>
</else>
</if-not-empty>
<entity-and entity-name="ProductCategoryMember" list="productCategoryMembers">
<field-map field-name="productCategoryId" from-field="parameters.productCategoryId"/>
</entity-and>
<iterate entry="productCategoryMember" list="productCategoryMembers">
<set field="productCategoryMember.thruDate" from-field="expireTimestamp"/>
<store-value value-field="productCategoryMember"/>
</iterate>
</simple-method>
<simple-method method-name="removeExpiredCategoryProductMembers" short-description="Remove ProductCategory From Category">
<set value="removeExpiredCategoryProductMembers" field="callingMethodName"/>
<set value="DELETE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<if-not-empty field="parameters.validDate">
<set field="expireTimestamp" from-field="parameters.validDate"/>
<else>
<now-timestamp field="expireTimestamp"/>
</else>
</if-not-empty>
<entity-and entity-name="ProductCategoryMember" list="productCategoryMembers">
<field-map field-name="productCategoryId" from-field="parameters.productCategoryId"/>
</entity-and>
<iterate entry="productCategoryMember" list="productCategoryMembers">
<if-compare-field field="productCategoryMember.thruDate" to-field="expireTimestamp" operator="less" type="Timestamp">
<remove-value value-field="productCategoryMember"/>
</if-compare-field>
</iterate>
</simple-method>
<!-- ================================================================ -->
<!-- Special Category Related Create Services -->
<!-- ================================================================ -->
<simple-method method-name="createProductInCategory" short-description="Create a Product in a Category along with special information such as features">
<set value="createProductInCategory" field="callingMethodName"/>
<set value="CREATE" field="checkAction"/>
<call-simple-method method-name="checkCategoryRelatedPermission"/>
<check-errors/>
<if-empty field="parameters.currencyUomId">
<!-- default to USD for lack of a better alternative, for now anyway... -->
<set field="parameters.currencyUomId" value="USD"/>
</if-empty>
<!-- create Product -->
<set-service-fields service-name="createProduct" map="parameters" to-map="callCreateProductMap"/>
<if-empty field="callCreateProductMap.productTypeId">
<set field="callCreateProductMap.productTypeId" value="FINISHED_GOOD"/>
</if-empty>
<call-service service-name="createProduct" in-map-name="callCreateProductMap">
<result-to-field result-name="productId"/>
</call-service>
<field-to-result field="productId"/>
<!-- create ProductCategoryMember -->
<set field="callCreateProductCategoryMemberMap.productId" from-field="productId"/>
<set field="callCreateProductCategoryMemberMap.productCategoryId" from-field="parameters.productCategoryId"/>
<call-service service-name="addProductToCategory" in-map-name="callCreateProductCategoryMemberMap"/>
<!-- create defaultPrice and averageCost ProductPrice -->
<if-not-empty field="parameters.defaultPrice">
<set field="createDefaultPriceMap.productId" from-field="productId"/>
<set field="createDefaultPriceMap.currencyUomId" from-field="parameters.currencyUomId"/>
<set field="createDefaultPriceMap.price" from-field="parameters.defaultPrice"/>
<set field="createDefaultPriceMap.productStoreGroupId" value="_NA_"/>
<set field="createDefaultPriceMap.productPriceTypeId" value="DEFAULT_PRICE"/>
<set field="createDefaultPriceMap.productPricePurposeId" value="PURCHASE"/>
<call-service service-name="createProductPrice" in-map-name="createDefaultPriceMap"/>
</if-not-empty>
<if-not-empty field="parameters.averageCost">
<set field="createAverageCostMap.productId" from-field="productId"/>
<set field="createAverageCostMap.currencyUomId" from-field="parameters.currencyUomId"/>
<set field="createAverageCostMap.price" from-field="parameters.averageCost"/>
<set field="createAverageCostMap.productStoreGroupId" value="_NA_"/>
<set field="createAverageCostMap.productPriceTypeId" value="AVERAGE_COST"/>
<set field="createAverageCostMap.productPricePurposeId" value="PURCHASE"/>
<call-service service-name="createProductPrice" in-map-name="createAverageCostMap"/>
</if-not-empty>
<!-- create ProductFeatureAppl(s) -->
<set field="hasSelectableFeatures" value="N"/>
<iterate-map map="parameters.productFeatureIdByType" key="productFeatureTypeId" value="productFeatureId">
<log level="info" message="Applying feature [${productFeatureId}] of type [${productFeatureTypeId}] to product [${productId}]"/>
<set field="createPfaMap.productId" from-field="productId"/>
<set field="createPfaMap.productFeatureId" from-field="productFeatureId"/>
<if-compare field="parameters.productFeatureSelectableByType[productFeatureTypeId]" operator="equals" value="Y">
<set field="createPfaMap.productFeatureApplTypeId" value="SELECTABLE_FEATURE"/>
<set field="hasSelectableFeatures" value="Y"/>
<else>
<set field="createPfaMap.productFeatureApplTypeId" value="STANDARD_FEATURE"/>
</else>
</if-compare>
<call-service service-name="applyFeatureToProduct" in-map-name="createPfaMap"/>
<clear-field field="createPfaMap"/>
</iterate-map>
<!-- set isVirtual based on hasSelectableFeatures -->
<if-compare field="hasSelectableFeatures" operator="equals" value="Y">
<entity-one entity-name="Product" value-field="newProduct"/>
<set field="newProduct.isVirtual" value="Y"/>
<store-value value-field="newProduct"/>
</if-compare>
</simple-method>
<simple-method method-name="duplicateProductCategory" short-description="Duplicate a ProductCategory">
<set value="duplicateProductCategory" field="callingMethodName"/>
<check-permission permission="CATALOG" action="_CREATE">
<alt-permission permission="CATALOG_ROLE" action="_CREATE"/>
<fail-property resource="ProductUiLabels" property="ProductCatalogCreatePermissionError"/>
</check-permission>
<check-errors/>
<!-- look up the old product category and clone it -->
<entity-one entity-name="ProductCategory" value-field="oldCategory">
<field-map field-name="productCategoryId" from-field="parameters.oldProductCategoryId"/>
</entity-one>
<clone-value value-field="oldCategory" new-value-field="newCategory"/>
<!-- set the new product category id, and write it to the datasource -->
<set field="newCategory.productCategoryId" from-field="parameters.productCategoryId"/>
<create-value value-field="newCategory"/>
<set field="productCategoryId" from-field="parameters.oldProductCategoryId"/>
<set field="productCategoryIdTo" from-field="parameters.productCategoryId"/>
<!-- if requested, duplicate related data as well -->
<if-not-empty field="parameters.duplicateMembers">
<set field="entityName" value="ProductCategoryMember"/>
<call-simple-method method-name="copyCategoryEntities"/>
</if-not-empty>
<if-not-empty field="parameters.duplicateContent">
<set field="entityName" value="ProductCategoryContent"/>
<call-simple-method method-name="copyCategoryEntities"/>
</if-not-empty>
<if-not-empty field="parameters.duplicateRoles">
<set field="entityName" value="ProductCategoryRole"/>
<call-simple-method method-name="copyCategoryEntities"/>
</if-not-empty>
<if-not-empty field="parameters.duplicateAttributes">
<set field="entityName" value="ProductCategoryAttribute"/>
<call-simple-method method-name="copyCategoryEntities"/>
</if-not-empty>
<if-not-empty field="parameters.duplicateFeatures">
<set field="entityName" value="ProductFeatureCategoryAppl"/>
<call-simple-method method-name="copyCategoryEntities"/>
</if-not-empty>
<if-not-empty field="parameters.duplicateCatalogs">
<set field="entityName" value="ProdCatalogCategory"/>
<call-simple-method method-name="copyCategoryEntities"/>
</if-not-empty>
<!-- parent rollups are where oldProductCategoryId = ProductCategoryRollup.productCategoryId, but the
child roll up is where oldProductCategoryId = ProductCategoryRollup.parentProductCategoryId and hence
requires a new find-by map -->
<if-not-empty field="parameters.duplicateParentRollup">
<entity-and entity-name="ProductCategoryRollup" list="foundValues">
<field-map field-name="productCategoryId" from-field="parameters.oldProductCategoryId"/>
</entity-and>
<iterate entry="foundValue" list="foundValues">
<clone-value value-field="foundValue" new-value-field="newTempValue"/>
<set field="newTempValue.productCategoryId" from-field="parameters.productCategoryId"/>
<create-value value-field="newTempValue"/>
</iterate>
</if-not-empty>
<if-not-empty field="parameters.duplicateChildRollup">
<entity-and entity-name="ProductCategoryRollup" list="foundValues">
<field-map field-name="parentProductCategoryId" from-field="parameters.oldProductCategoryId"/>
</entity-and>
<iterate entry="foundValue" list="foundValues">
<clone-value value-field="foundValue" new-value-field="newTempValue"/>
<set field="newTempValue.parentProductCategoryId" from-field="parameters.productCategoryId"/>
<create-value value-field="newTempValue"/>
</iterate>
</if-not-empty>
</simple-method>
<!-- ================================================================ -->
<!-- Product Category Attribute Services -->
<!-- ================================================================ -->
<simple-method method-name="createProductCategoryAttribute"
short-description="Create an attribute for a product category">
<check-permission permission="CATALOG" action="_CREATE">
<fail-property resource="ProductUiLabels" property="ProductCatalogCreatePermissionError"/>
</check-permission>
<check-errors/>
<make-value value-field="newEntity" entity-name="ProductCategoryAttribute"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="updateProductCategoryAttribute"
short-description="Update an association between two product categories">
<check-permission permission="CATALOG" action="_UPDATE">
<fail-property resource="ProductUiLabels" property="ProductCatalogUpdatePermissionError"/>
</check-permission>
<check-errors/>
<make-value value-field="lookupPKMap" entity-name="ProductCategoryAttribute"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ProductCategoryAttribute" map="lookupPKMap" value-field="ProductCategoryAttributeInstance"/>
<set-nonpk-fields map="parameters" value-field="ProductCategoryAttributeInstance"/>
<store-value value-field="ProductCategoryAttributeInstance"/>
</simple-method>
<simple-method method-name="deleteProductCategoryAttribute"
short-description="Delete an association between two product categories">
<check-permission permission="CATALOG" action="_DELETE">
<fail-property resource="ProductUiLabels" property="ProductCatalogDeletePermissionError"/>
</check-permission>
<check-errors/>
<make-value value-field="lookupPKMap" entity-name="ProductCategoryAttribute"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ProductCategoryAttribute" map="lookupPKMap" value-field="ProductCategoryAttributeInstance"/>
<remove-value value-field="ProductCategoryAttributeInstance"/>
</simple-method>
<!-- ProductCategoryLink Create/Update/Delete"-->
<simple-method method-name="createProductCategoryLink" short-description="create a ProductCategoryLink">
<make-value entity-name="ProductCategoryLink" value-field="newEntity"/>
<set field="newEntity.productCategoryId" from-field="parameters.productCategoryId"/>
<!-- don't set the fromDate yet; let's get the seq ID first -->
<if-empty field="parameters.linkSeqId">
<make-next-seq-id value-field="newEntity" seq-field-name="linkSeqId"/> <!-- this finds the next sub-sequence ID -->
<set from-field="linkSeqId" field="newEntity.linkSeqId"/>
</if-empty>
<!-- now set the rest of the PK fields (should just be fromDate now; unless linkSeqId is not empty -->
<set-pk-fields value-field="newEntity" map="parameters"/>
<if-empty field="newEntity.fromDate">
<now-timestamp field="newEntity.fromDate"/>
</if-empty>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="updateProductCategoryLink" short-description="update a ProductCategoryLink">
<entity-one entity-name="ProductCategoryLink" value-field="lookedUpValue"/>
<set-nonpk-fields value-field="lookedUpValue" map="parameters"/>
<store-value value-field="lookedUpValue"/>
</simple-method>
<simple-method method-name="deleteProductCategoryLink" short-description="delete a ProductCategoryLink">
<entity-one entity-name="ProductCategoryLink" value-field="lookedUpValue"/>
<remove-value value-field="lookedUpValue"/>
</simple-method>
<!-- ============================= -->
<!-- Permission Methods -->
<!-- ============================= -->
<!-- a methods 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="checkCategoryRelatedPermission" short-description="Check Product Category Related Permission">
<if-empty field="callingMethodName">
<set field="callingMethodName" value="this operation"/>
</if-empty>
<if-empty field="checkAction">
<set field="checkAction" value="UPDATE"/>
</if-empty>
<if-empty field="productCategoryIdName">
<set field="productCategoryIdName" value="productCategoryId"/>
</if-empty>
<if-empty field="productCategoryIdToCheck">
<set field="productCategoryIdToCheck" from-field="parameters.${productCategoryIdName}"/>
</if-empty>
<!-- find all role-categories that this category is a member of -->
<if>
<condition>
<not><if-has-permission permission="CATALOG" action="_${checkAction}"/></not>
</condition>
<then>
<entity-and entity-name="ProductCategoryRollupAndRole" list="roleCategories" filter-by-date="true">
<field-map field-name="productCategoryId" from-field="productCategoryIdToCheck"/>
<field-map field-name="partyId" from-field="userLogin.partyId"/>
<field-map field-name="roleTypeId" value="LTD_ADMIN"/>
</entity-and>
<filter-list-by-date list="roleCategories" from-field-name="roleFromDate" thru-field-name="roleThruDate"/>
</then>
</if>
<log level="info" message="Checking category permission, roleCategories=${roleCategories}"/>
<if>
<condition>
<not>
<or>
<if-has-permission permission="CATALOG" action="_${checkAction}"/>
<and>
<if-has-permission permission="CATALOG_ROLE" action="_${checkAction}"/>
<not><if-empty field="roleCategories"/></not>
</and>
</or>
</not>
</condition>
<then>
<log level="verbose" message="Permission check failed, user does not have permission"/>
<add-error>
<fail-property resource="ProductUiLabels" property="ProductCatalogCreatePermissionError"/>
</add-error>
<set field="hasPermission" type="Boolean" value="false"/>
</then>
</if>
</simple-method>
<simple-method method-name="productCategoryGenericPermission" short-description="Main permission logic">
<set field="mainAction" from-field="parameters.mainAction"/>
<if-empty field="mainAction">
<add-error>
<fail-property resource="ProductUiLabels" property="ProductMissingMainActionInPermissionService"/>
</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="checkCategoryRelatedPermission"/>
<if-empty field="error_list">
<set field="hasPermission" type="Boolean" value="true"/>
<field-to-result field="hasPermission"/>
<else>
<property-to-field resource="ProductUiLabels" property="ProductPermissionError" field="failMessage"/>
<set field="hasPermission" type="Boolean" value="false"/>
<field-to-result field="hasPermission"/>
<field-to-result field="failMessage"/>
</else>
</if-empty>
</simple-method>
<!-- a service verion of checkCategoryRelatedPermission, only with purchase/viewAllowPermReqd taken into account -->
<simple-method method-name="checkCategoryPermissionWithViewPurchaseAllow" short-description="Check Product Category Permission With View and Purchase Allow">
<set-service-fields service-name="productCategoryGenericPermission" map="parameters" to-map="productCategoryGenericPermissionMap"/>
<call-service service-name="productCategoryGenericPermission" in-map-name="productCategoryGenericPermissionMap">
<results-to-map map-name="genericResult"/>
</call-service>
<if-compare field="genericResult.hasPermission" operator="equals" value="false" type="Boolean">
<field-to-result field="genericResult.hasPermission" result-name="hasPermission"/>
<field-to-result field="failMessage.genericResult.failMessage" result-name="genericResult.failMessage"/>
<return/>
</if-compare>
<!-- if the generic permission test passed, carry on -->
<set field="hasPermission" type="Boolean" value="true"/>
<!-- Set up for a call to checkCategoryRelatedPermission below, but callingMethodName is needed sooner -->
<set field="callingMethodName" from-field="parameters.resourceDescription" default-value="this operation"/>
<set field="checkAction" from-field="parameters.mainAction" default-value="UPDATE"/>
<entity-condition list="prodCatalogCategoryList" entity-name="ProdCatalogCategory" filter-by-date="true">
<condition-list combine="and">
<condition-expr field-name="productCategoryId" from-field="parameters.productCategoryId"/>
<condition-list combine="or">
<condition-expr field-name="prodCatalogCategoryTypeId" value="PCCT_VIEW_ALLW"/>
<condition-expr field-name="prodCatalogCategoryTypeId" value="PCCT_PURCH_ALLW"/>
</condition-list>
</condition-list>
</entity-condition>
<iterate entry="prodCatalogCategory" list="prodCatalogCategoryList">
<!-- Do not do a permission check unless the ProdCatalog requires it -->
<entity-one entity-name="ProdCatalog" value-field="prodCatalog" auto-field-map="false">
<field-map field-name="prodCatalogId" from-field="prodCatalogCategory.prodCatalogId"/>
</entity-one>
<if>
<condition>
<and>
<if-compare field="prodCatalog.viewAllowPermReqd" operator="equals" value="Y"/>
<not><if-has-permission permission="CATALOG_VIEW_ALLOW"/></not>
</and>
</condition>
<then>
<log level="verbose" message="Permission check failed, user does not have permission"/>
<set field="failMessage" value="Security Error: to run ${callingMethodName} you must have the CATALOG_VIEW_ALLOW permission."/>
<set field="hasPermission" type="Boolean" value="false"/>
</then>
</if>
<if>
<condition>
<and>
<if-compare field="prodCatalog.purchaseAllowPermReqd" operator="equals" value="Y"/>
<not><if-has-permission permission="CATALOG_PURCHASE_ALLOW"/></not>
</and>
</condition>
<then>
<log level="verbose" message="Permission check failed, user does not have permission"/>
<set field="failMessage" value="Security Error: to run ${callingMethodName} you must have the CATALOG_PURCHASE_ALLOW permission."/>
<set field="hasPermission" type="Boolean" value="false"/>
</then>
</if>
</iterate>
<field-to-result field="hasPermission"/>
<field-to-result field="failMessage"/>
</simple-method>
<!-- To help dynamically populate a products dropdown given a product category id from a change in another dropdown, possibly sorted on sequenceNum -->
<simple-method method-name="getAssociatedProductsList" short-description="Set the product options for selected product category, mostly used by getDependentDropdownValues" login-required="false">
<set field="parameters.categoryId" from-field="parameters.productCategoryId"/>
<set-service-fields service-name="getProductCategoryMembers" map="parameters" to-map="getProductCategoryMembersMap"/>
<call-service service-name="getProductCategoryMembers" in-map-name="getProductCategoryMembersMap">
<result-to-field result-name="categoryMembers" field="productsList"/>
</call-service>
<order-map-list list="productsList">
<order-by field-name="sequenceNum"/>
</order-map-list>
<iterate list="productsList" entry="productMember">
<entity-one entity-name="Product" value-field="product">
<field-map field-name="productId" from-field="productMember.productId"/>
</entity-one>
<set field="productName" value="${product.internalName}: ${product.productId}"/>
<field-to-list list="products" field="productName"/>
</iterate>
<if-empty field="products">
<property-to-field resource="ProductUiLabels" property="ProductNoProducts" field="noOption"/>
<field-to-list list="products" field="noOption"/>
</if-empty>
<field-to-result field="products"/>
</simple-method>
<!-- Load data of best selling category -->
<simple-method method-name="loadBestSellingCategory" short-description="Load data of best selling category by week.">
<now-date-to-env field="nowDate"/>
<set field="week" value="${groovy: import java.util.Calendar;
Calendar cal = Calendar.getInstance();
cal.setTime(nowDate);
return cal.get(Calendar.WEEK_OF_YEAR);}" type="Long"/>
<set field="year" value="${groovy: import java.util.Calendar;
Calendar cal = Calendar.getInstance();
cal.setTime(nowDate);
int aa = cal.get(Calendar.YEAR);
return aa;}" type="Long"/>
<if-compare field="week" operator="equals" value="1">
<set field="week" value="52"/>
<else>
<calculate field="week">
<calcop field="week" operator="subtract">
<number value="1"/>
</calcop>
</calculate>
<if-compare field="week" operator="equals" value="1">
<calculate field="year">
<calcop field="year" operator="subtract">
<number value="1"/>
</calcop>
</calculate>
</if-compare>
</else>
</if-compare>
<entity-and entity-name="ProductStoreCatalog" list="productStoreCatalogs" filter-by-date="true">
<field-map field-name="productStoreId" from-field="parameters.productStoreId"/>
</entity-and>
<if-not-empty field="productStoreCatalogs">
<first-from-list list="productStoreCatalogs" entry="productStoreCatalog"/>
<set field="callRemoveProductMap.prodCatalogId" from-field="productStoreCatalog.prodCatalogId"/>
<call-service service-name="RemoveProductFromBestSellCategory" in-map-name="callRemoveProductMap"/>
<set field="callAddProductMap.productStoreId" from-field="parameters.productStoreId"/>
<set field="callAddProductMap.prodCatalogId" from-field="productStoreCatalog.prodCatalogId"/>
<set field="callAddProductMap.week" from-field="week" type="Long"/>
<set field="callAddProductMap.year" from-field="year" type="Long"/>
<call-service service-name="AddProductToBestSellCategory" in-map-name="callAddProductMap"/>
</if-not-empty>
</simple-method>
<simple-method method-name="RemoveProductFromBestSellCategory" short-description="Remove products from best selling category.">
<entity-and entity-name="ProdCatalogCategory" list="prodCatalogCategorys">
<field-map field-name="prodCatalogId" from-field="parameters.prodCatalogId"/>
<field-map field-name="prodCatalogCategoryTypeId" value="PCCT_BEST_SELL"/>
</entity-and>
<iterate list="prodCatalogCategorys" entry="prodCatalogCategory">
<entity-and entity-name="ProductCategoryRollup" list="productCategoryRollups">
<field-map field-name="parentProductCategoryId" from-field="prodCatalogCategory.productCategoryId"/>
</entity-and>
<iterate list="productCategoryRollups" entry="productCategoryRollup">
<entity-and entity-name="ProductCategoryMember" list="productCategoryMembers">
<field-map field-name="productCategoryId" from-field="productCategoryRollup.productCategoryId"/>
</entity-and>
<iterate list="productCategoryMembers" entry="productCategoryMember">
<remove-value value-field="productCategoryMember"/>
</iterate>
</iterate>
</iterate>
</simple-method>
<simple-method method-name="AddProductToBestSellCategory" short-description="Add products to best selling category.">
<entity-and entity-name="ProdCatalogCategory" list="prodCatalogCategorys">
<field-map field-name="prodCatalogId" from-field="parameters.prodCatalogId"/>
<field-map field-name="prodCatalogCategoryTypeId" value="PCCT_BEST_SELL"/>
</entity-and>
<first-from-list list="prodCatalogCategorys" entry="prodCatalogCategory"/>
<entity-and entity-name="ProductCategoryRollup" list="productCategoryRollupList">
<field-map field-name="parentProductCategoryId" from-field="prodCatalogCategory.productCategoryId"/>
</entity-and>
<iterate list="productCategoryRollupList" entry="productCategoryRollup">
<set-service-fields service-name="FindCategoryChild" map="parameters" to-map="CategoryChildMap"/>
<set field="CategoryChildMap.productCategoryId" from-field="productCategoryRollup.productCategoryId"/>
<set field="CategoryChildMap.primaryProductCategoryId" from-field="productCategoryRollup.productCategoryId"/>
<call-service service-name="FindCategoryChild" in-map-name="CategoryChildMap"/>
</iterate>
</simple-method>
<simple-method method-name="FindCategoryChild" short-description="Find category child.">
<entity-and entity-name="ProductCategoryRollup" list="productCategoryRollupList">
<field-map field-name="parentProductCategoryId" from-field="parameters.productCategoryId"/>
</entity-and>
<if-empty field="productCategoryRollupList">
<set-service-fields service-name="FindBestSellingProduct" map="parameters" to-map="AddProductMap"/>
<set field="AddProductMap.productCategoryId" from-field="parameters.productCategoryId"/>
<call-service service-name="FindBestSellingProduct" in-map-name="AddProductMap"/>
<else>
<iterate list="productCategoryRollupList" entry="productCategoryRollup">
<set-service-fields service-name="FindCategoryChild" map="parameters" to-map="CategoryChildMap"/>
<set field="CategoryChildMap.productCategoryId" from-field="productCategoryRollup.productCategoryId"/>
<call-service service-name="FindCategoryChild" in-map-name="CategoryChildMap"/>
</iterate>
</else>
</if-empty>
</simple-method>
<simple-method method-name="FindBestSellingProduct" short-description="Find best selling product.">
<now-timestamp field="nowTimestamp"/>
<entity-and entity-name="ProductCategoryMember" list="productCategoryMembers" filter-by-date="true">
<field-map field-name="productCategoryId" from-field="parameters.productCategoryId"/>
</entity-and>
<iterate list="productCategoryMembers" entry="productCategoryMember">
<entity-condition entity-name="SalesOrderItemStarSchema" list="salesOrderItemStarSchemas" distinct="true">
<condition-list combine="and">
<condition-expr field-name="productProductId" operator="equals" from-field="productCategoryMember.productId"/>
<condition-expr field-name="productStoreId" operator="equals" from-field="parameters.productStoreId"/>
<condition-expr field-name="orderDateWeekOfYear" operator="equals" from-field="parameters.week"/>
<condition-expr field-name="orderDateYearName" operator="equals" from-field="parameters.year"/>
</condition-list>
</entity-condition>
<if-not-empty field="salesOrderItemStarSchemas">
<first-from-list list="salesOrderItemStarSchemas" entry="salesOrderItemStarSchema"/>
<make-value entity-name="ProductCategoryMember" value-field="newEntity"/>
<set field="newEntity.productCategoryId" from-field="parameters.primaryProductCategoryId"/>
<set field="newEntity.productId" from-field="salesOrderItemStarSchema.productProductId"/>
<set field="newEntity.fromDate" from-field="nowTimestamp"/>
<set field="newEntity.quantity" from-field="salesOrderItemStarSchema.quantity"/>
<create-value value-field="newEntity"/>
</if-not-empty>
</iterate>
</simple-method>
</simple-methods>