ilscipio/scipio-erp

View on GitHub
applications/commonext/script/org/ofbiz/setup/SetupEvents.xml

Summary

Maintainability
Test Coverage
<?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">

    <simple-method method-name="createOrganization" short-description="Create Organization" login-required="false">
        <!-- SCIPIO: 2017-10-04: don't know why this was forced here (it is specified by forms)
        <set field="require_email" value="true"/>-->
        <set field="require_email" from-field="parameters.require_email" default-value="true"/>
        <set field="require_phone" value="false"/>
        <set field="require_login" value="false"/>
        <!-- this parameter must be set to true or the createUser method below will use a default password instead of the one entered by user -->
        <set field="create_allow_password" value="true"/>

        <set field="parameters.roleTypeId" value="INTERNAL_ORGANIZATIO"/>
        <now-timestamp field="nowStamp"/>

        <!-- Create the PartyGroup -->
        <call-map-processor in-map-name="parameters" out-map-name="partyGroupContext">
            <simple-map-processor name="newPartyGroup">
                <process field="partyId"><copy/></process>
                <process field="groupName"><copy to-field="groupName"/><not-empty><fail-property resource="" property="SetupOrganizationNameIsMissing"/></not-empty></process>
            </simple-map-processor>
        </call-map-processor>

        <!-- Create the PartyRole -->
        <set field="partyRoleContext.roleTypeId" from-field="parameters.roleTypeId"/>

        <!-- SCIPIO: 2017-09-29: factored out verification code -->
        <call-simple-method method-name="verifyOrganizationFields"/>

        <!-- get the visit from the session to get the visitId -->
        <session-to-field field="visit"/>

        <!-- now that everything is validated & setup, check to see if there are errors, then call the services -->
        <check-errors/>

        <call-service service-name="createPartyGroup" in-map-name="partyGroupContext">
            <result-to-field result-name="partyId" field="tempMap.partyId"/>
        </call-service>

        <!-- now that we have the partyId, put it where it needs to go... -->
        <set field="userLoginContext.partyId" from-field="tempMap.partyId"/>
        <set field="partyGroupContext.partyId" from-field="tempMap.partyId"/>
        <set field="partyRoleContext.partyId" from-field="tempMap.partyId"/>
        <set field="addressContext.partyId" from-field="tempMap.partyId"/>
        <set field="workPhoneContext.partyId" from-field="tempMap.partyId"/>
        <set field="faxPhoneContext.partyId" from-field="tempMap.partyId"/>
        <set field="mobilePhoneContext.partyId" from-field="tempMap.partyId"/>
        <set field="emailContext.partyId" from-field="tempMap.partyId"/>

        <call-service service-name="createPartyRole" in-map-name="partyRoleContext"/>
        <!-- add Carrier roletype  -->
        <set field="partyRoleContext.roleTypeId" value="CARRIER"/>
        <call-service service-name="createPartyRole" in-map-name="partyRoleContext"/>

        <!-- billing address -->
        <if-compare field="parameters.USE_ADDRESS" operator="equals" value="false">
            <!-- address not used, do nothing -->
            <else>
                <call-service service-name="createPartyPostalAddress" in-map-name="addressContext">
                    <result-to-field result-name="contactMechId" field="addressPurposeContext.contactMechId"/>
                </call-service>
                <set field="addressPurposeContext.partyId" from-field="tempMap.partyId"/>
                <!-- create the payment location -->
                <set field="addressPurposeContext.contactMechPurposeTypeId" value="PAYMENT_LOCATION"/>
                <call-service service-name="createPartyContactMechPurpose" in-map-name="addressPurposeContext"/>
                <!-- also consider this address the general correspondence address -->
                <set field="addressPurposeContext.contactMechPurposeTypeId" value="GENERAL_LOCATION"/>
                <call-service service-name="createPartyContactMechPurpose" in-map-name="addressPurposeContext"/>
                <!-- create the billing location -->
                <set field="addressPurposeContext.contactMechPurposeTypeId" value="BILLING_LOCATION"/>
                <call-service service-name="createPartyContactMechPurpose" in-map-name="addressPurposeContext"/>
            </else>
        </if-compare>
        <!-- home phone -->
        <if-not-empty field="parameters.USER_HOME_CONTACT">
            <call-service service-name="createPartyTelecomNumber" in-map-name="homePhoneContext">
                <result-to-field result-name="contactMechId" field="homePhonePurposeContext.contactMechId"/>
            </call-service>
            <set field="homePhonePurposeContext.partyId" from-field="tempMap.partyId"/>
            <set field="homePhonePurposeContext.contactMechPurposeTypeId" value="PHONE_HOME"/>
            <call-service service-name="createPartyContactMechPurpose" in-map-name="homePhonePurposeContext"/>
        </if-not-empty>
        <!-- work phone -->
        <if-not-empty field="parameters.USER_WORK_CONTACT">
            <call-service service-name="createPartyTelecomNumber" in-map-name="workPhoneContext">
                <result-to-field result-name="contactMechId" field="workPhonePurposeContext.contactMechId"/>
            </call-service>
            <set field="workPhonePurposeContext.partyId" from-field="tempMap.partyId"/>
            <set field="workPhonePurposeContext.contactMechPurposeTypeId" value="PHONE_WORK"/>
            <call-service service-name="createPartyContactMechPurpose" in-map-name="workPhonePurposeContext"/>
        </if-not-empty>
        <!-- fax phone -->
        <if-not-empty field="parameters.USER_FAX_CONTACT">
            <call-service service-name="createPartyTelecomNumber" in-map-name="faxPhoneContext">
                <result-to-field result-name="contactMechId" field="faxPhonePurposeContext.contactMechId"/>
            </call-service>
            <set field="faxPhonePurposeContext.partyId" from-field="tempMap.partyId"/>
            <set field="faxPhonePurposeContext.contactMechPurposeTypeId" value="FAX_NUMBER"/>
            <call-service service-name="createPartyContactMechPurpose" in-map-name="faxPhonePurposeContext"/>
        </if-not-empty>
        <!-- mobile phone -->
        <if-not-empty field="parameters.USER_MOBILE_CONTACT">
            <call-service service-name="createPartyTelecomNumber" in-map-name="mobilePhoneContext">
                <result-to-field result-name="contactMechId" field="mobilePhonePurposeContext.contactMechId"/>
            </call-service>
            <set field="mobilePhonePurposeContext.partyId" from-field="tempMap.partyId"/>
            <set field="mobilePhonePurposeContext.contactMechPurposeTypeId" value="PHONE_MOBILE"/>
            <call-service service-name="createPartyContactMechPurpose" in-map-name="mobilePhonePurposeContext"/>
        </if-not-empty>
        <!-- email address -->
        <if-not-empty field="parameters.USER_EMAIL">
            <call-service service-name="createPartyEmailAddress" in-map-name="emailContext">
                <result-to-field result-name="contactMechId" field="emailPurposeContext.contactMechId"/>
            </call-service>
            <set field="emailPurposeContext.partyId" from-field="tempMap.partyId"/>
            <set field="emailPurposeContext.contactMechPurposeTypeId" value="PRIMARY_EMAIL"/>
            <call-service service-name="createPartyContactMechPurpose" in-map-name="emailPurposeContext"/>
        </if-not-empty>

        <!-- General Ledger Setup for the new organization -->
        <!--<call-simple-method method-name="setupDefaultGeneralLedger"/>-->

        <!-- create CustomTimePeriod within one years -->
        <now-timestamp field="nowTimestamp"/>
        <set field="endMonth" value="12"/>
        <set field="endDate" value="31"/>
        <call-class-method class-name="org.ofbiz.base.util.UtilDateTime" method-name="getYearStart" ret-field="fromDateStamp">
            <field field="nowTimestamp" type="java.sql.Timestamp"/>
        </call-class-method>
        <set field="curYearString" value="${str:toString(date:year(fromDateStamp, util:defaultTimeZone(), util:defaultLocale()))}"/>

        <set field="customTimePeriodCtx.fromDate" from-field="fromDateStamp" type="java.sql.Timestamp"/>
        <set field="customTimePeriodCtx.thruDate" value="${groovy:org.ofbiz.base.util.UtilDateTime.toSqlDate(endMonth ,endDate , curYearString)}" type="java.sql.Timestamp"/>
        <set field="customTimePeriodCtx.isClosed" value="N"/>
        <set field="customTimePeriodCtx.organizationPartyId" from-field="tempMap.partyId"/>
        <set field="customTimePeriodCtx.periodName" from-field="curYearString"/>
        <set field="customTimePeriodCtx.periodNum" value="1" type="Long"/>
        <set field="customTimePeriodCtx.periodTypeId" value="FISCAL_YEAR"/>
        <call-service service-name="createCustomTimePeriod" in-map-name="customTimePeriodCtx"/>

        <!-- Create partyId for UserLogin -->
        <!-- SCIPIO: 2017-09-29: not sure this is always wanted, so allow to skip this behavior -->
        <if-compare field="parameters.update_current_userlogin_party" operator="not-equals" value="false">
            <session-to-field field="userLoginCtx" session-name="userLogin"/>
            <if-empty field="userLoginCtx.partyId">
                <make-value entity-name="Party" value-field="newEntity"/>
                <set field="newEntity.partyId" from-field="userLoginCtx.userLoginId"/>
                <set field="newEntity.partyTypeId" value="PERSON"/>
                <create-value value-field="newEntity"/>
                <clear-field field="newEntity"/>
                <make-value entity-name="Person" value-field="newPerson"/>
                <set field="newPerson.partyId" from-field="userLoginCtx.userLoginId"/>
                <create-value value-field="newPerson"/>
                <clear-field field="newPerson"/>

                <set field="userLoginCtx.partyId" from-field="userLoginCtx.userLoginId"/>
                <store-value value-field="userLoginCtx"/>
            </if-empty>
        </if-compare>

        <!-- set the partyId in the request -->
        <field-to-request field="tempMap.partyId" request-name="partyId"/>
    </simple-method>

    <!-- SCIPIO: 2017-09-29: factored out from createOrganization -->
    <simple-method method-name="verifyOrganizationFields" short-description="SCIPIO: Verify organization parameters" login-required="false">
        <!-- Create the Postal Address -->
        <if-compare field="parameters.USE_ADDRESS" operator="equals" value="false">
            <!-- address not used, do nothing -->
            <else>
                <call-map-processor in-map-name="parameters" out-map-name="addressContext">
                    <simple-map-processor name="newPerson">
                        <process field="roleTypeId"><copy/></process>
                        <process field="groupName"><copy to-field="toName"/></process>
                        <process field="USER_ADDRESS1"><copy to-field="address1"/><not-empty><fail-property resource="PartyUiLabels" property="PartyAddressLine1Missing"/></not-empty></process>
                        <process field="USER_ADDRESS2"><copy to-field="address2"/></process>
                        <process field="USER_CITY"><copy to-field="city"/><not-empty><fail-property resource="PartyUiLabels" property="PartyCityMissing"/></not-empty></process>
                        <process field="USER_STATE"><copy to-field="stateProvinceGeoId"/></process>
                        <process field="USER_POSTAL_CODE"><copy to-field="postalCode"/><not-empty><fail-property resource="PartyUiLabels" property="PartyPostalCodeMissing"/></not-empty></process>
                        <process field="USER_COUNTRY"><copy to-field="countryGeoId"/><not-empty><fail-property resource="CommonUiLabels" property="CommonCountryMissing"/></not-empty></process>
                        <process field="USER_ADDRESS_ALLOW_SOL"><copy to-field="allowSolicitation"/></process>
                    </simple-map-processor>
                </call-map-processor>
                <if-compare value="USA" operator="equals" field="parameters.USER_COUNTRY">
                    <if-empty field="parameters.USER_STATE">
                        <property-to-field field="tempErrorMessage" resource="PartyUiLabels" property="PartyStateInUsMissing"/>
                        <field-to-list field="tempErrorMessage" list="error_list"/>
                    </if-empty>
                </if-compare>
                <if-compare value="CAN" operator="equals" field="parameters.USER_COUNTRY">
                    <if-empty field="parameters.USER_STATE">
                        <property-to-field field="tempErrorMessage" resource="PartyUiLabels" property="PartyStateInCanadaMissing"/>
                        <field-to-list field="tempErrorMessage" list="error_list"/>
                    </if-empty>
                </if-compare>
            </else>
        </if-compare>
        <!-- Create the Work Phone -->
        <if-not-empty field="parameters.USER_WORK_CONTACT">
            <call-map-processor in-map-name="parameters" out-map-name="workPhoneContext">
                <simple-map-processor name="newTelecomNumber">
                    <process field="roleTypeId"><copy/></process>
                    <process field="USER_WORK_COUNTRY"><copy to-field="countryCode"/></process>
                    <process field="USER_WORK_AREA"><copy to-field="areaCode"/></process>
                    <process field="USER_WORK_CONTACT"><copy to-field="contactNumber"/></process>
                    <process field="USER_WORK_EXT"><copy to-field="extension"/></process>
                    <process field="USER_WORK_ALLOW_SOL"><copy to-field="allowSolicitation"/></process>
                </simple-map-processor>
            </call-map-processor>
        </if-not-empty>
        <!-- Create the Fax Phone -->
        <if-not-empty field="parameters.USER_FAX_CONTACT">
            <call-map-processor in-map-name="parameters" out-map-name="faxPhoneContext">
                <simple-map-processor name="newTelecomNumber">
                    <process field="roleTypeId"><copy/></process>
                    <process field="USER_FAX_COUNTRY"><copy to-field="countryCode"/></process>
                    <process field="USER_FAX_AREA"><copy to-field="areaCode"/></process>
                    <process field="USER_FAX_CONTACT"><copy to-field="contactNumber"/></process>
                    <process field="USER_FAX_EXT"><copy to-field="extension"/></process>
                    <process field="USER_FAX_ALLOW_SOL"><copy to-field="allowSolicitation"/></process>
                </simple-map-processor>
            </call-map-processor>
        </if-not-empty>
        <!-- Check for required Phone -->
        <if-compare field="require_phone" operator="equals" value="true">
            <if-empty field="parameters.USER_HOME_CONTACT">
                <if-empty field="parameters.USER_WORK_CONTACT">
                    <if-empty field="parameters.USER_MOBILE_CONTACT">
                        <call-map-processor in-map-name="parameters" out-map-name="dummymap">
                            <simple-map-processor name="checkRequiredPhone">
                                <process field="REQUIRED_PHONE">
                                    <not-empty><fail-property resource="PartyUiLabels" property="PartyContactTelephoneMissing"/></not-empty>
                                </process>
                            </simple-map-processor>
                        </call-map-processor>
                    </if-empty>
                </if-empty>
            </if-empty>
        </if-compare>
        <!-- Create the email address -->
        <call-map-processor in-map-name="parameters" out-map-name="emailContext">
            <simple-map-processor name="newEmail">
                <process field="roleTypeId"><copy/></process>
                <process field="USER_EMAIL"><copy to-field="emailAddress"/></process>
                <process field="USER_EMAIL_ALLOW_SOL"><copy to-field="allowSolicitation"/></process>
            </simple-map-processor>
        </call-map-processor>
        <!-- Check for required E-Mail -->
        <if-compare field="require_email" operator="equals" value="true">
            <if-empty field="emailContext.emailAddress">
                <call-map-processor in-map-name="emailContext" out-map-name="dummymap">
                    <simple-map-processor name="checkRequiredEmail">
                        <process field="emailAddress">
                            <not-empty><fail-property resource="PartyUiLabels" property="PartyEmailAddressMissing"/></not-empty>
                        </process>
                    </simple-map-processor>
                </call-map-processor>
            </if-empty>
        </if-compare>
        <!-- SCIPIO: 2017-09-29: MOVED this check outside of the require_email condition; must always check
            email validity when non-empty -->
        <if-not-empty field="emailContext.emailAddress">
            <call-map-processor in-map-name="emailContext" out-map-name="dummymap">
                <simple-map-processor name="checkRequiredEmailFormat">
                    <process field="emailAddress">
                        <validate-method method="isEmail">
                            <fail-property resource="PartyUiLabels" property="PartyEmailAddressNotFormattedCorrectly"/>
                        </validate-method>
                    </process>
                </simple-map-processor>
            </call-map-processor>
        </if-not-empty>
    </simple-method>

    <simple-method method-name="setupDefaultGeneralLedger" short-description="General Ledger Setup for the new organization">
        <set field="partyId" from-field="parameters.partyId"/>
        <!-- create GL journal for suspended transactions (failed post) -->
        <set field="createGlJournalCtx.organizationPartyId" from-field="partyId"/>
        <set field="createGlJournalCtx.glJournalName" value="Suspense transactions"/>
        <call-service service-name="createGlJournal" in-map-name="createGlJournalCtx">
            <result-to-field result-name="glJournalId" field="acctgPreferenceCtx.errorGlJournalId"/>
        </call-service>

        <entity-one entity-name="PartyGroup" value-field="partyGroup"/>
        <script lang="groovy"><![CDATA[
           groupName = partyGroup.get("groupName");
           if(groupName != null){
              parameters.put("invoiceIdPrefix", groupName.toUpperCase().substring(0, 2)+"CI");
           }else{
              parameters.put("invoiceIdPrefix", "CI");
           }
        ]]></script>

        <set field="acctgPreferenceCtx.partyId" from-field="partyId"/>
        <set field="acctgPreferenceCtx.taxFormId" value="US_IRS_1120"/>
        <set field="acctgPreferenceCtx.cogsMethodId" value="COGS_AVG_COST"/>
        <set field="acctgPreferenceCtx.baseCurrencyUomId" value="USD"/>
        <set field="acctgPreferenceCtx.oldInvoiceSequenceEnumId" value="INVSQ_ENF_SEQ"/>
        <set field="acctgPreferenceCtx.invoiceIdPrefix" from-field="parameters.invoiceIdPrefix"/>
        <set field="acctgPreferenceCtx.oldQuoteSequenceEnumId" value="INVSQ_ENF_SEQ"/>
        <set field="acctgPreferenceCtx.quoteIdPrefix" value="QU"/>
        <set field="acctgPreferenceCtx.oldOrderSequenceEnumId" value="INVSQ_ENF_SEQ"/>
        <set field="acctgPreferenceCtx.orderIdPrefix" value="OD"/>
        <call-service service-name="createPartyAcctgPreference" in-map-name="acctgPreferenceCtx"/>

        <!-- run demo General Chart Of Accounts  -->
        <entity-condition entity-name="GlAccount" list="glAccountList"/>
        <if-empty field="glAccountList">
            <set field="importChartOfAccountCtx.filename" value="${sys:getProperty('ofbiz.home')}/applications/accounting/data/DemoGeneralChartOfAccounts.xml"/>
            <session-to-field field="importChartOfAccountCtx.userLogin" session-name="userLogin"/>
            <call-service service-name="entityImport" in-map-name="importChartOfAccountCtx"/>
            <check-errors/>
        </if-empty>

        <!-- create General Ledger Setup -->
        <now-timestamp field="nowTimestamp"/>
        <set field="placeholderValues.orgPartyId" from="partyId"/>
        <set field="placeholderValues.fromDate" value="${groovy:nowTimestamp.toString()}"/>
        <set field="importFileCtx.filename" value="${sys:getProperty('ofbiz.home')}/applications/commonext/data/GlAccountData.xml"/>
        <set field="importFileCtx.placeholderValues" from="placeholderValues"/>
        <call-service service-name="entityImport" in-map-name="importFileCtx"/>
        <check-errors/>
    </simple-method>

    <simple-method method-name="createCustomer" short-description="Create Customer" login-required="false">
        <set field="require_email" value="true"/>
        <set field="require_phone" value="false"/>
        <set field="require_login" value="false"/>
        <!-- this parameter must be set to true or the createUser method below will use a default password instead of the one entered by user -->
        <set field="create_allow_password" value="true"/>
        <set field="parameters.roleTypeId" value="CUSTOMER"/>
        <set field="organizationPartyId" from-field="parameters.partyId"/>
        <set field="personContext.partyId" from-field="parameters.customerPartyId"/>
        <call-simple-method method-name="createUser" xml-resource="component://party/script/org/ofbiz/party/user/UserEvents.xml"/>
    </simple-method>

    <simple-method method-name="createFacilityAndContactMech" short-description="create Facility and ContactMech">
        <!-- SCIPIO: delegated for reuse -->
        <call-simple-method method-name="verifyFacilityFields"/>
        <check-errors/>

        <make-value entity-name="Facility" value-field="newEntity"/>
        <set field="defaultDaysToShip" from-field="parameters.defaultDaysToShip" type="Long"/>
        <clear-field field="parameters.defaultDaysToShip"/>

        <set-nonpk-fields map="parameters" value-field="newEntity"/>
        <set field="newEntity.defaultDaysToShip" from-field="defaultDaysToShip" type="Long"/>

        <if-empty field="parameters.facilityId">
            <sequenced-id sequence-name="Facility" field="facilityId"/>
            <to-string field="facilityId"/>
            <set field="newEntity.facilityId" from-field="facilityId"/>
            <else>
                <set field="newEntity.facilityId" from-field="parameters.facilityId"/>
            </else>
        </if-empty>
        <set field="facilityId" from-field="newEntity.facilityId"/>
        <field-to-request field="facilityId" request-name="facilityId"/>
        <create-value value-field="newEntity"/>

        <!-- create  Facility ContactMech-->
        <!-- SCIPIO: 2017-09-27: support a specific contact mech ID AND also support manual input -->
        <if-compare field="parameters.useFacilityAddr" operator="not-equals" value="false">
            <if-compare field="parameters.useInputFacilityAddr" operator="equals" value="true">
                <set-service-fields service-name="createPostalAddress" map="shipAddressContext" to-map="addressContext"/>
                <else>
                    <if>
                        <condition><not><if-empty field="parameters.postalAddressContactMechId"/></not></condition>
                        <then>
                            <entity-and entity-name="PartyAndPostalAddress" list="listPartyPostalAddress" filter-by-date="true">
                                <field-map field-name="partyId" from-field="parameters.partyId"/>
                                <field-map field-name="contactMechId" from-field="parameters.postalAddressContactMechId"/>
                            </entity-and>
                            <first-from-list list="listPartyPostalAddress" entry="partyPostalAddress"/>
                        </then>
                        <else>
                            <!-- stock ofbiz -->
                            <entity-and entity-name="PartyAndPostalAddress" list="listPartyPostalAddress" filter-by-date="true">
                                <field-map field-name="partyId" from-field="parameters.partyId"/>
                            </entity-and>
                            <first-from-list list="listPartyPostalAddress" entry="partyPostalAddress"/>
                        </else>
                    </if>
                    <set-service-fields service-name="createPostalAddress" map="partyPostalAddress" to-map="addressContext"/>
                </else>
            </if-compare>
        </if-compare>

        <sequenced-id sequence-name="ContactMech" field="addressContext.contactMechId"/>
        <call-service service-name="createPostalAddress" in-map-name="addressContext">
            <result-to-field result-name="contactMechId" field="contactMechId"/>
        </call-service>

        <set field="facilityContactMechCtx.contactMechId" from-field="contactMechId"/>
        <set field="facilityContactMechCtx.facilityId" from-field="facilityId"/>
        <call-service service-name="createFacilityContactMech" in-map-name="facilityContactMechCtx"/>

        <!-- create the payment location -->
        <set field="addressPurposeContext.facilityId" from-field="facilityId"/>
        <set field="addressPurposeContext.contactMechId" from-field="contactMechId"/>
        <set field="addressPurposeContext.contactMechPurposeTypeId" value="SHIPPING_LOCATION"/>
        <call-service service-name="createFacilityContactMechPurpose" in-map-name="addressPurposeContext"/>
        <!-- also consider this address the shipping origin address -->
        <set field="addressPurposeContext.contactMechPurposeTypeId" value="SHIP_ORIG_LOCATION"/>
        <call-service service-name="createFacilityContactMechPurpose" in-map-name="addressPurposeContext"/>
    </simple-method>

    <!-- SCIPIO: new -->
    <simple-method method-name="verifyFacilityFields" short-description="SCIPIO: verify facility fields">
        <if-empty field="parameters.facilityName">
            <add-error>
                <fail-property resource="SetupUiLabels" property="SetupFacilityNameIsMissing"/>
            </add-error>
        </if-empty>

        <if-compare field="parameters.useFacilityAddr" operator="not-equals" value="false">
            <if-compare field="parameters.useInputFacilityAddr" operator="equals" value="true">
                <!-- NOTE: logic copied and modified from createOrganization -->
                <call-map-processor in-map-name="parameters" out-map-name="shipAddressContext">
                    <simple-map-processor name="newPostalAddress">
                        <!--<process field="roleTypeId"><copy/></process>-->
                        <process field="shipAddress_toName"><copy to-field="toName"/></process>
                        <process field="shipAddress_attnName"><copy to-field="attnName"/></process>
                        <process field="shipAddress_address1"><copy to-field="address1"/><not-empty><fail-property resource="PartyUiLabels" property="PartyAddressLine1Missing"/></not-empty></process>
                        <process field="shipAddress_address2"><copy to-field="address2"/></process>
                        <process field="shipAddress_city"><copy to-field="city"/><not-empty><fail-property resource="PartyUiLabels" property="PartyCityMissing"/></not-empty></process>
                        <process field="shipAddress_stateProvinceGeoId"><copy to-field="stateProvinceGeoId"/></process>
                        <process field="shipAddress_postalCode"><copy to-field="postalCode"/><not-empty><fail-property resource="PartyUiLabels" property="PartyPostalCodeMissing"/></not-empty></process>
                        <process field="shipAddress_countryGeoId"><copy to-field="countryGeoId"/><not-empty><fail-property resource="CommonUiLabels" property="CommonCountryMissing"/></not-empty></process>
                    </simple-map-processor>
                </call-map-processor>
                <if-compare value="USA" operator="equals" field="parameters.shipAddress_countryGeoId">
                    <if-empty field="parameters.shipAddress_stateProvinceGeoId">
                        <property-to-field field="tempErrorMessage" resource="PartyUiLabels" property="PartyStateInUsMissing"/>
                        <field-to-list field="tempErrorMessage" list="error_list"/>
                    </if-empty>
                </if-compare>
                <if-compare value="CAN" operator="equals" field="parameters.shipAddress_countryGeoId">
                    <if-empty field="parameters.shipAddress_stateProvinceGeoId">
                        <property-to-field field="tempErrorMessage" resource="PartyUiLabels" property="PartyStateInCanadaMissing"/>
                        <field-to-list field="tempErrorMessage" list="error_list"/>
                    </if-empty>
                </if-compare>
            </if-compare>
        </if-compare>
    </simple-method>

    <simple-method method-name="createProductStoreWithDefaultSetting" short-description="create ProductStore and setting default value for payment and shipping">
        <if-empty field="parameters.storeName">
            <add-error>
                <fail-property resource="SetupUiLabels" property="SetupProductStoreNameIsMissing"/>
            </add-error>
        </if-empty>
        <if-compare field="parameters.showPricesWithVatTax" operator="equals" value="Y">
            <if-empty field="parameters.vatTaxAuthGeoId">
                <add-error><fail-property resource="ProductUiLabels" property="ProductVatTaxAuthGeoNotSet"/></add-error>
            </if-empty>
            <if-empty field="parameters.vatTaxAuthPartyId">
                <add-error><fail-property resource="ProductUiLabels" property="ProductVatTaxAuthPartyNotSet"/></add-error>
            </if-empty>
        </if-compare>
        <check-errors/>

        <!-- SCIPIO: 2017-09-29: check if store already exists for given ID -->
        <if-not-empty field="parameters.productStoreId">
            <entity-one entity-name="ProductStore" value-field="existingProductStore">
                <field-map field-name="productStoreId" from-field="parameters.productStoreId"/>
            </entity-one>
            <if-not-empty field="existingProductStore">
                <set field="productStoreId" from-field="parameters.productStoreId"/>
                <add-error><fail-property resource="ProductErrorUiLabels" property="productevents.productstore_already_exists_for_id"/></add-error>
                <check-errors/>
            </if-not-empty>
        </if-not-empty>

        <!-- Create ProductStore -->
        <make-value entity-name="ProductStore" value-field="newEntity"/>
        <set-nonpk-fields map="parameters" value-field="newEntity"/>
        <set field="newEntity.storeCreditValidDays" value="90" type="Long"/>
        <set field="newEntity.daysToCancelNonPay"  value="30" type="Long"/>

        <if-empty field="parameters.productStoreId">
            <sequenced-id sequence-name="ProductStore" field="productStoreId"/>
            <to-string field="productStoreId"/>
            <set field="newEntity.productStoreId" from-field="productStoreId"/>
            <else>
                <set field="newEntity.productStoreId" from-field="parameters.productStoreId"/>
            </else>
        </if-empty>
        <set field="productStoreId" from-field="newEntity.productStoreId"/>
        <field-to-request field="productStoreId" request-name="productStoreId"/>
        <create-value value-field="newEntity"/>

        <!-- create the ProductStoreFacility record -->
        <now-timestamp field="nowTimestamp"/>
        <if-not-empty field="newEntity.inventoryFacilityId">
            <make-value entity-name="ProductStoreFacility" value-field="storeFacility"/>
            <set from-field="newEntity.inventoryFacilityId" field="storeFacility.facilityId"/>
            <set from-field="newEntity.productStoreId" field="storeFacility.productStoreId"/>
            <set from-field="nowTimestamp" field="storeFacility.fromDate"/>
            <create-value value-field="storeFacility"/>
        </if-not-empty>

        <field-to-request field="parameters.partyId" request-name="partyId"/>
        <set field="organizationPartyId" from-field="parameters.partyId"/>

        <!-- Create default data of ProductStoreShipmentMeth, ShipmentMethodType , CarrierShipmentMethod, and ShipmentCostEstimate. -->
        <entity-condition entity-name="ShipmentMethodType" list="shipmentMethodTypeList"/>
        <if-empty field="shipmentMethodTypeList">
            <!-- run demo Shipping  -->
            <set field="importShippingCtx.filename" value="${sys:getProperty('ofbiz.home')}/applications/commonext/data/ShippingData.xml"/>
            <session-to-field field="importShippingCtx.userLogin" session-name="userLogin"/>
            <call-service service-name="entityImport" in-map-name="importShippingCtx"/>
            <check-errors/>
        </if-empty>

        <!-- SCIPIO: 2019-03-26: Ensuring organizationPartyId has the role CARRIER assigned -->
        <set field="ensurePartyRoleCtx.partyId" from-field="organizationPartyId"/>
        <set field="ensurePartyRoleCtx.roleTypeId" value="CARRIER"/>
        <call-service service-name="ensurePartyRole" in-map-name="ensurePartyRoleCtx"/>
        <!-- SCIPIO: 2017-10-05: new reservation handling -->
        <call-simple-method method-name="createProductStoreShipMethIdRange"/>
        <check-errors/>
        <if-empty field="productStoreShipMethIdList">
            <!-- this should never happen, just a sanity check to prevent ever corrupting anything -->
            <add-error>
                <fail-message message="Internal error: no productStoreShipMethIdList range reservation was created - please contact support"/>
            </add-error>
            <check-errors/>
        </if-empty>
        <set field="placeholderValues.productStoreShipMethIdList" from-field="productStoreShipMethIdList"/>

        <!-- Import Default ProductStore & Shipment data -->
        <set field="placeholderValues.orgPartyId" from="organizationPartyId"/>
        <set field="placeholderValues.productStoreId" from="productStoreId"/>
        <set field="importFileCtx.filename" value="${sys:getProperty('ofbiz.home')}/applications/commonext/data/ProductStoreData.xml"/>
        <set field="importFileCtx.placeholderValues" from="placeholderValues"/>
        <call-service service-name="entityImport" in-map-name="importFileCtx"/>
        <check-errors/>
    </simple-method>

    <!-- SCIPIO: 2017-10-05: new productStoreShipMethIdList reservation handling for ProductStoreData.xml -->
    <simple-method method-name="createProductStoreShipMethIdRange" short-description="creates a ProductStoreShipmentMeth ID range list in productStoreShipMethIdList">
        <!-- SCIPIO: 2017-10-05: NEW WORKAROUND for productStoreShipMethId uniqueness issue;
            productStoreId is not part of the ProductStoreShipmentMeth primary key so we must determine
            a unique base that is not in use.
            We now use EntitySeqIdList classes which generate and cache new IDs when accessed through the get(int) method
            by ProductStoreData.xml.
            If an explicit productStoreShipMethIdBase is passed, we use that instead, but it
            is risky, see warning below.
            If there are no ProductStoreShipmentMeth in the system yet, then we use 9000 instead
            of generating, for simplicity for simple setups. -->

        <property-to-field resource="scipiosetup" property="store.productStoreData.productStoreShipMethId.bankSize" field="pssmBankSize" default="100"/>
        <set field="pssmBankSize" type="Integer" from-field="pssmBankSize"/>
        

        <set field="productStoreShipMethIdBase" type="Long" value="" set-if-null="true"/><!-- SCIPIO: 2018-11-02: set-if-null="true" required to set null -->
        <if-not-empty field="parameters.productStoreShipMethIdBase">
            <set field="productStoreShipMethIdBase" type="Long" from-field="parameters.productStoreShipMethIdBase"/>
            <log level="warning" message="ProductStoreData.xml: caller passed an explicit productStoreShipMethIdBase to use as base for ProductStoreShipmentMeth ID (${groovy:productStoreShipMethIdBase+''}) - if this value is wrongly selected, it could crush existing store records!"/>
            <else>
                <!-- If there are no ProductStoreShipmentMeth records in the system, we'll use the stock default 9000;
                    otherwise use new sequence -->
                <entity-condition entity-name="ProductStoreShipmentMeth" list="productStoreShipmentMethList">
                </entity-condition>
                <if-empty field="productStoreShipmentMethList">
                    <log level="info" message="ProductStoreData.xml: There are no ProductStoreShipmentMeth records in the system yet (first store), so we will use ID base 9000"/>
                    <set field="productStoreShipMethIdBase" type="Long" value="9000"/>
                </if-empty>
            </else>
        </if-not-empty>
        <check-errors/>
        <if-not-empty field="productStoreShipMethIdBase">
            <log level="info" message="ProductStoreData.xml: Using fixed productStoreShipMethId range starting from: ${groovy:productStoreShipMethIdBase+''}"/>
            <create-object class-name="org.ofbiz.entity.util.EntitySeqIdList$FixedEntitySeqIdStringList"
                field="productStoreShipMethIdList">
                <field field="productStoreShipMethIdBase" type="Object"/>
                <field field="pssmBankSize" type="int"/>
            </create-object>
            <else>
                <log level="info" message="ProductStoreData.xml: Using dynamically reserved productStoreShipMethId range"/>
                <create-object class-name="org.ofbiz.entity.util.EntitySeqIdList$DynamicEntitySeqIdStringList"
                    field="productStoreShipMethIdList">
                    <field field="delegator" type="org.ofbiz.entity.Delegator"/>
                    <string value="ProductStoreShipmentMeth"/>
                    <field field="pssmBankSize" type="int"/>
                </create-object>
                <!--<sequenced-id sequence-name="ProductStoreShipmentMeth" field="productStoreShipMethIdBase" get-long-only="true"/>-->
            </else>
        </if-not-empty>
        <check-errors/>
    </simple-method>

    <simple-method method-name="createProdCatalogAndProductStoreCatalog" short-description="create ProdCatalog And ProductStoreCatalog">
        <set-service-fields service-name="createProdCatalog" map="parameters" to-map="createProdCatalogCtx"/>

        <call-service service-name="createProdCatalog" in-map-name="createProdCatalogCtx">
            <result-to-field result-name="prodCatalogId" field="newProductStoreCatalog.prodCatalogId"/>
            <result-to-request result-name="prodCatalogId" request-name="prodCatalogId"/>
        </call-service>

        <set field="newProductStoreCatalog.productStoreId" from-field="parameters.productStoreId"/>
        <set field="newProductStoreCatalog.sequenceNum" from-field="parameters.sequenceNum"/><!-- SCIPIO: 2017-09-28: support create with sequence num -->
        <call-service service-name="createProductStoreCatalog" in-map-name="newProductStoreCatalog"/>
    </simple-method>

    <simple-method method-name="createProductCategoryAndAddToProdCatalog" short-description="addProductCategoryToProdCatalog">
        <!-- Create Parent ProductCategory -->
        <set field="createPrimaryProductCategoryCtx.productCategoryId" value="${parameters.prodCatalogId}_ROOT"/>
        <set field="createPrimaryProductCategoryCtx.categoryName" value="${parameters.prodCatalogId} Browse Root Category"/>
        <set field="createPrimaryProductCategoryCtx.productCategoryTypeId" value="CATALOG_CATEGORY"/>
        <call-service service-name="createProductCategory" in-map-name="createPrimaryProductCategoryCtx">
            <result-to-field result-name="productCategoryId" field="parameters.primaryParentCategoryId"/>
        </call-service>

        <set field="addToProdCatalogCtx.productCategoryId" from-field="parameters.primaryParentCategoryId"/>
        <set field="addToProdCatalogCtx.prodCatalogId" from-field="parameters.prodCatalogId"/>
        <set field="addToProdCatalogCtx.prodCatalogCategoryTypeId" value="PCCT_BROWSE_ROOT"/>
        <set field="addToProdCatalogCtx.sequenceNum" value="1" type="Long"/>
        <call-service service-name="addProductCategoryToProdCatalog" in-map-name="addToProdCatalogCtx"/>

        <!-- Create Promotion ProductCategory -->
        <call-object-method obj-field="parameters.prodCatalogId" method-name="toUpperCase" ret-field="catalogUpperCase"/>
        <set field="createPromotionCategoryCtx.productCategoryId" value="${catalogUpperCase}_PROMOTIONS"/>
        <set field="createPromotionCategoryCtx.categoryName" value="${catalogUpperCase} Promotions"/>
        <set field="createPromotionCategoryCtx.productCategoryTypeId" value="CATALOG_CATEGORY"/>
        <!-- SCIPIO: Now point to shop -->
        <set field="createPromotionCategoryCtx.detailScreen" value="component://shop/widget/CatalogScreens.xml#categorydetailmatrix"/>

        <call-service service-name="createProductCategory" in-map-name="createPromotionCategoryCtx">
            <result-to-field result-name="productCategoryId" field="promotionCategoryId"/>
        </call-service>
        <set field="addPromoCatToProdCatalogCtx.productCategoryId" from-field="promotionCategoryId"/>
        <set field="addPromoCatToProdCatalogCtx.prodCatalogId" from-field="parameters.prodCatalogId"/>
        <set field="addPromoCatToProdCatalogCtx.prodCatalogCategoryTypeId" value="PCCT_PROMOTIONS"/>
        <set field="addPromoCatToProdCatalogCtx.sequenceNum" value="2" type="Long"/>
        <call-service service-name="addProductCategoryToProdCatalog" in-map-name="addPromoCatToProdCatalogCtx"/>

        <!-- Create ProductCategory & ProductCategoryRollup -->
        <set-service-fields service-name="createProductCategory" map="parameters" to-map="createProductCategoryCtx"/>
        <call-service service-name="createProductCategory" in-map-name="createProductCategoryCtx">
            <result-to-field result-name="productCategoryId" field="productCategoryId"/>
            <result-to-request result-name="productCategoryId" request-name="productCategoryId"/>
        </call-service>

        <make-value entity-name="ProductCategoryRollup" value-field="newEntity"/>
        <set field="newEntity.parentProductCategoryId" from-field="parameters.primaryParentCategoryId"/>
        <set field="newEntity.productCategoryId" from-field="productCategoryId"/>
        <set field="newEntity.sequenceNum" value="1" type="Long"/>
        <if-empty field="newEntity.fromDate">
            <now-timestamp field="nowTimestamp"/>
            <set from-field="nowTimestamp" field="newEntity.fromDate"/>
        </if-empty>
        <create-value value-field="newEntity"/>
    </simple-method>

    <simple-method method-name="createUpdateProductInCategory" short-description="Create/Update a Product in a Category along with special information such as features">
        <set value="createUpdateProductInCategory" field="callingMethodName"/>
        <if-compare field="parameters.productId" operator="equals" value="${parameters.productCategoryId}">
            <set field="parameters.productId" value="${parameters.productId}-001"/>
        </if-compare>
        <entity-one entity-name="Product" value-field="product"/>
        <if-empty field="product">
            <set field="checkAction" value="CREATE"/>
            <else><set field="checkAction" value="UPDATE"/></else>
        </if-empty>
        <call-simple-method method-name="checkCategoryRelatedPermission" xml-resource="component://product/script/org/ofbiz/product/category/CategoryServices.xml"/>
        <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>

        <if-empty field="product">
            <!-- 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>

            <!-- 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"/>

            <set field="callCreateProductCategoryMemberMap.productId" from-field="productId"/>
            <set field="callCreateProductCategoryMemberMap.productCategoryId" from-field="parameters.promoCat"/>
            <call-service service-name="addProductToCategory" in-map-name="callCreateProductCategoryMemberMap"/>

            <!-- 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>
            <else>
                <!-- update Product -->
                <set-service-fields service-name="updateProduct" map="parameters" to-map="callUpdateProductMap"/>
                <call-service service-name="updateProduct" in-map-name="callUpdateProductMap"/>
                <set field="productId" from-field="parameters.productId"/>
            </else>
        </if-empty>
        <field-to-result field="productId"/>

        <!-- create/update defaultPrice and averageCost ProductPrice -->
        <if-not-empty field="parameters.defaultPrice">
            <entity-condition entity-name="ProductPrice" list="defaultPriceValues" filter-by-date="true">
                <condition-list>
                    <condition-expr field-name="productId" from-field="productId"/>
                    <condition-expr field-name="productPriceTypeId" value="DEFAULT_PRICE"/>
                    <condition-expr field-name="productPricePurposeId" value="PURCHASE"/>
                </condition-list>
            </entity-condition>
            <if-empty field="defaultPriceValues">
                <set field="createDefaultPriceMap.productId" from-field="productId"/>
                <set field="createDefaultPriceMap.currencyUomId" from-field="parameters.currencyUomId"/>
                <set field="createDefaultPriceMap.price" from-field="parameters.defaultPrice" type="BigDecimal"/>
                <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"/>

                <else>
                    <first-from-list list="defaultPriceValues" entry="defaultPrice"/>
                    <set field="updateDefaultPriceMap.productId" from-field="productId"/>
                    <set field="updateDefaultPriceMap.price" from-field="parameters.defaultPrice" type="BigDecimal"/>
                    <set field="updateDefaultPriceMap.productPricePurposeId" from-field="defaultPrice.productPricePurposeId"/>
                    <set field="updateDefaultPriceMap.productPriceTypeId" from-field="defaultPrice.productPriceTypeId"/>
                    <set field="updateDefaultPriceMap.productStoreGroupId" from-field="defaultPrice.productStoreGroupId"/>
                    <set field="updateDefaultPriceMap.currencyUomId" from-field="defaultPrice.currencyUomId"/>
                    <set field="updateDefaultPriceMap.fromDate" from-field="defaultPrice.fromDate"/>
                    <call-service service-name="updateProductPrice" in-map-name="updateDefaultPriceMap"/>
                </else>
            </if-empty>

        </if-not-empty>

        <if-not-empty field="parameters.averageCost">
            <entity-condition entity-name="ProductPrice" list="averageCostValues" filter-by-date="true">
                <condition-list>
                    <condition-expr field-name="productId" from-field="productId"/>
                    <condition-expr field-name="productPriceTypeId" value="AVERAGE_COST"/>
                    <condition-expr field-name="productPricePurposeId" value="PURCHASE"/>
                </condition-list>
            </entity-condition>
            <if-empty field="averageCostValues">
                <set field="createAverageCostMap.productId" from-field="productId"/>
                <set field="createAverageCostMap.currencyUomId" from-field="parameters.currencyUomId"/>
                <set field="createAverageCostMap.price" from-field="parameters.averageCost" type="BigDecimal"/>
                <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"/>

                <else>
                    <first-from-list list="averageCostValues" entry="averageCost"/>
                    <set field="updateAverageCostMap.productId" from-field="productId"/>
                    <set field="updateAverageCostMap.productPricePurposeId" from-field="averageCost.productPricePurposeId"/>
                    <set field="updateAverageCostMap.productPriceTypeId" from-field="averageCost.productPriceTypeId"/>
                    <set field="updateAverageCostMap.productStoreGroupId" from-field="averageCost.productStoreGroupId"/>
                    <set field="updateAverageCostMap.currencyUomId" from-field="averageCost.currencyUomId"/>
                    <set field="updateAverageCostMap.fromDate" from-field="averageCost.fromDate"/>
                    <set field="updateAverageCostMap.price" from-field="parameters.averageCost" type="BigDecimal"/>
                    <call-service service-name="updateProductPrice" in-map-name="updateAverageCostMap"/>
                </else>
            </if-empty>
        </if-not-empty>
    </simple-method>

    <simple-method method-name="createDefaultWebSite" short-description="Create a WebSite, default webSiteId is ScipioWebStore.">
        <!-- SCIPIO: don't override the webSiteId if one is passed
        <set field="parameters.webSiteId" value="ScipioWebStore"/>-->
        <set field="parameters.webSiteId" from-field="parameters.webSiteId" default-value="ScipioWebStore"/><!-- SCIPIO: new default value -->
        <set-service-fields service-name="createWebSite" to-map="createWebSiteCtx" map="parameters"/>
        <call-service service-name="createWebSite" in-map-name="createWebSiteCtx"/>
    </simple-method>

</simple-methods>